discretionary_policy_1.m 5.52 KB
Newer Older
1 2
function [dr,ys,info]=discretionary_policy_1(oo_,Instruments)

3
% Copyright (C) 2007-2018 Dynare Team
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
%
% This file is part of Dynare.
%
% Dynare 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.
%
% Dynare 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.
%
% You should have received a copy of the GNU General Public License
% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.

global M_ options_
persistent Hold

23 24 25 26
dr = [];
ys = [];
info = 0;

27 28 29
if isempty(options_.qz_criterium)
    options_.qz_criterium = 1+1e-6;
end
30 31 32 33 34 35 36 37 38 39 40 41

% safeguard against issues like running ramsey policy first and then running discretion
if isfield(M_,'orig_model')
    orig_model = M_.orig_model;
    M_.endo_nbr = orig_model.endo_nbr;
    M_.endo_names = orig_model.endo_names;
    M_.lead_lag_incidence = orig_model.lead_lag_incidence;
    M_.maximum_lead = orig_model.maximum_lead;
    M_.maximum_endo_lead = orig_model.maximum_endo_lead;
    M_.maximum_lag = orig_model.maximum_lag;
    M_.maximum_endo_lag = orig_model.maximum_endo_lag;
else
42
    M_.orig_model = M_;
43 44
end

45
beta = get_optimal_policy_discount_factor(M_.params, M_.param_names);
46 47 48 49 50 51 52 53 54 55

exo_nbr = M_.exo_nbr;
if isfield(M_,'orig_model')
    orig_model = M_.orig_model;
    endo_nbr = orig_model.endo_nbr;
    endo_names = orig_model.endo_names;
    lead_lag_incidence = orig_model.lead_lag_incidence;
    MaxLead = orig_model.maximum_lead;
    MaxLag = orig_model.maximum_lag;
else
56 57 58 59
    endo_names = M_.endo_names;
    endo_nbr = M_.endo_nbr;
    MaxLag=M_.maximum_lag;
    MaxLead=M_.maximum_lead;
60 61 62
    lead_lag_incidence = M_.lead_lag_incidence;
end

63 64 65 66
%call steady_state_file if present to update parameters
if options_.steadystate_flag
    % explicit steady state file
    [junk,M_.params,info] = evaluate_steady_state_file(oo_.steady_state,[oo_.exo_steady_state; oo_.exo_det_steady_state],M_, ...
67
                                                      options_,0);
68
end
69
[U,Uy,W] = feval([M_.fname,'.objective.static'],zeros(endo_nbr,1),[], M_.params);
70
if any(any(Uy~=0))
71 72
    non_zero_derivs=find(any(Uy~=0));
    for ii=1:length(non_zero_derivs)
73
        non_zero_deriv_names{ii,1} = M_.endo_names{non_zero_derivs(ii)};
74 75 76 77 78 79
    end
    disp_string=[non_zero_deriv_names{1,:}];
    for ii=2:size(non_zero_deriv_names,1)
        disp_string=[disp_string,', ',non_zero_deriv_names{ii,:}];
    end
    fprintf('\nThe derivative of the objective function w.r.t. to variable(s) %s is not 0\n',disp_string)
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
    error(['discretionary_policy: the objective function must have zero ' ...
           'first order derivatives'])
end

W=reshape(W,endo_nbr,endo_nbr);

klen = MaxLag + MaxLead + 1;
iyv=lead_lag_incidence';
% Find the jacobian
z = repmat(zeros(endo_nbr,1),1,klen);
z = z(nonzeros(iyv)) ;
it_ = MaxLag + 1 ;

if exo_nbr == 0
    oo_.exo_steady_state = [] ;
end
96

97
[junk,jacobia_] = feval([M_.fname '.dynamic'],z, [zeros(size(oo_.exo_simul)) ...
98 99 100 101 102 103 104 105 106
                    oo_.exo_det_simul], M_.params, zeros(endo_nbr,1), it_);
if any(junk~=0)
    error(['discretionary_policy: the model must be written in deviation ' ...
           'form and not have constant terms'])
end

eq_nbr= size(jacobia_,1);
instr_nbr=endo_nbr-eq_nbr;

107
if instr_nbr==0
108
    error('discretionary_policy:: There are no available instruments, because the model has as many equations as variables.')
109
end
110 111 112 113
if size(Instruments,1)< instr_nbr
    error('discretionary_policy:: There are fewer declared instruments than omitted equations.')
elseif size(Instruments,1)> instr_nbr
    error('discretionary_policy:: There are more declared instruments than omitted equations.')    
114
end
115

116 117
instr_id=nan(instr_nbr,1);
for j=1:instr_nbr
118
    vj=deblank(Instruments{j});
119
    vj_id=strmatch(vj, endo_names, 'exact');
120 121 122 123 124
    if ~isempty(vj_id)
        instr_id(j)=vj_id;
    else
        error([mfilename,':: instrument ',vj,' not found'])
    end
125 126 127 128 129 130
end

Indices={'lag','0','lead'};
iter=1;
for j=1:numel(Indices)
    eval(['A',Indices{j},'=zeros(eq_nbr,endo_nbr);'])
131 132 133 134 135
    if strcmp(Indices{j},'0')||(strcmp(Indices{j},'lag') && MaxLag)||(strcmp(Indices{j},'lead') && MaxLead)
        [junk,row,col]=find(lead_lag_incidence(iter,:));
        eval(['A',Indices{j},'(:,row)=jacobia_(:,col);'])
        iter=iter+1;
    end
136 137 138 139 140
end
B=jacobia_(:,nnz(iyv)+1:end);

%%% MAIN ENGINE %%%
qz_criterium = options_.qz_criterium;
141
solve_maxit = options_.dp.maxit;
142 143 144
discretion_tol = options_.discretionary_tol;

if ~isempty(Hold)
145
    [H,G,info]=discretionary_policy_engine(Alag,A0,Alead,B,W,instr_id,beta,solve_maxit,discretion_tol,qz_criterium,Hold);
146
else
147
    [H,G,info]=discretionary_policy_engine(Alag,A0,Alead,B,W,instr_id,beta,solve_maxit,discretion_tol,qz_criterium);
148 149 150 151 152 153
end

if info
    dr=[];
    return
else
154 155
    Hold=H; %save previous solution
            % Hold=[]; use this line if persistent command is not used.
156 157 158 159
end
% set the state
dr=oo_.dr;
dr.ys =zeros(endo_nbr,1);
160
dr=set_state_space(dr,M_,options_);
161 162 163 164
order_var=dr.order_var;

T=H(order_var,order_var);
dr.ghu=G(order_var,:);
165
Selection=lead_lag_incidence(1,order_var)>0;%select state variables
166 167 168 169 170 171 172
dr.ghx=T(:,Selection);

ys=NondistortionarySteadyState(M_);
dr.ys=ys; % <--- dr.ys =zeros(NewEndo_nbr,1);

function ys=NondistortionarySteadyState(M_)
if exist([M_.fname,'_steadystate.m'],'file')
173
    eval(['ys=',M_.fname,'_steadystate.m;'])
174
else
175
    ys=zeros(M_.endo_nbr,1);
176
end