331 lines
13 KiB
Matlab
331 lines
13 KiB
Matlab
function write(DynareModel)
|
|
|
|
% Writes the nonlinear problem to be solved for computing the growth
|
|
% rates and levels along the Balanced Growth Path. Note that for
|
|
% the variables growing along the BGP, the identified levels are
|
|
% meaningless, only the relative levels of the growing variables
|
|
% sharing the same trend(s) are relevant.
|
|
%
|
|
% INPUTS
|
|
% - DynareModel [struct] Dynare generated stucture describing the model (M_).
|
|
%
|
|
% OUTPUTS
|
|
% None
|
|
%
|
|
% REMARKS
|
|
% - The trends are assumed to be multiplicative.
|
|
|
|
% Copyright (C) 2019 Dynare Team
|
|
%
|
|
% 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/>.
|
|
|
|
if DynareModel.maximum_lag && ~DynareModel.maximum_lead
|
|
i0 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the lagged variables.
|
|
i1 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the current variables.
|
|
i2 = []; % Indices of the leaded variables.
|
|
elseif DynareModel.maximum_lag && DynareModel.maximum_lead
|
|
i0 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the lagged variables.
|
|
i1 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the current variables.
|
|
i2 = transpose(DynareModel.lead_lag_incidence(3,:)); % Indices of the leaded variables.
|
|
elseif ~DynareModel.maximum_lag && DynareModel.maximum_lead
|
|
i0 = []; % Indices of the lagged variables.
|
|
i1 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the current variables.
|
|
i2 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the leaded variables.
|
|
else
|
|
error('The model is static. The BGP is trivial.')
|
|
end
|
|
|
|
n0 = length(find(i0)); % Number of lagged variables.
|
|
n1 = length(find(i1)); % Number of current variables.
|
|
n2 = length(find(i2)); % Number of leaded variables.
|
|
|
|
purely_backward_model = logical(n0 && n1 && ~n2);
|
|
purely_forward_model = logical(~n0 && n1 && n2);
|
|
|
|
if purely_backward_model
|
|
I0 = i0;
|
|
I1 = i1;
|
|
I2 = [];
|
|
elseif purely_forward_model
|
|
I0 = i1;
|
|
I1 = i2;
|
|
I2 = [];
|
|
else
|
|
% Model has both leads and lags.
|
|
I0 = i0;
|
|
I1 = i1;
|
|
I2 = i2;
|
|
end
|
|
|
|
% Create function in mod namespace.
|
|
fid = fopen(sprintf('+%s/bgpfun.m', DynareModel.fname), 'w');
|
|
|
|
% Write header.
|
|
fprintf(fid, 'function [F, JAC] = bgpfun(z)\n\n');
|
|
fprintf(fid, '%% This file has been generated by dynare (%s).\n\n', datestr(now));
|
|
|
|
% The function admits a unique vector as input argument. The first
|
|
% half of the elements are for the levels of the endogenous
|
|
% variables, the second half for the growth factors.
|
|
fprintf(fid, 'y = z(1:%u);\n\n', DynareModel.endo_nbr);
|
|
fprintf(fid, 'g = z(%u:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr);
|
|
|
|
% Define the point where the dynamic model is to be evaluated.
|
|
fprintf(fid, 'Y = zeros(%u, 1);\n', 2*(n0+n1+n2));
|
|
for i=1:length(I0) % period t equations, lagged variables.
|
|
if I0(i)
|
|
fprintf(fid, 'Y(%u) = y(%u);\n', I0(i), i);
|
|
end
|
|
end
|
|
for i=1:length(I1) % period t equations, current variables.
|
|
if I1(i)
|
|
fprintf(fid, 'Y(%u) = y(%u)*g(%u);\n', I1(i), i, i);
|
|
end
|
|
end
|
|
for i=1:length(I2) % period t equations, leaded variables.
|
|
if I2(i)
|
|
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u);\n', I2(i), i, i, i);
|
|
end
|
|
end
|
|
for i=1:length(I0) % period t+1 equations lagged variables.
|
|
if I0(i)
|
|
fprintf(fid, 'Y(%u) = y(%u)*g(%u);\n', n0+n1+n2+I0(i), i, i);
|
|
end
|
|
end
|
|
for i=1:length(I1) % period t+1 equations current variables.
|
|
if I1(i)
|
|
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u);\n', n0+n1+n2+I1(i), i, i, i);
|
|
end
|
|
end
|
|
for i=1:length(I2) % period t+1 equations leaded variables.
|
|
if I2(i)
|
|
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u)*g(%u);\n', n0+n1+n2+I2(i), i, i, i, i);
|
|
end
|
|
end
|
|
fprintf(fid, '\n');
|
|
|
|
% Define the vector of parameters.
|
|
fprintf(fid, 'p = zeros(%u, 1);\n', DynareModel.param_nbr);
|
|
for i = 1:DynareModel.param_nbr
|
|
fprintf(fid, 'p(%u) = %16.12f;\n', i, DynareModel.params(i));
|
|
end
|
|
fprintf(fid, '\n');
|
|
|
|
% Initialize the vector holding the residuals over the two periods.
|
|
fprintf(fid, 'F = NaN(%u, 1);\n', 2*DynareModel.endo_nbr);
|
|
|
|
% Set vector of exogenous variables to 0.
|
|
fprintf(fid, 'x = zeros(1, %u);\n\n', DynareModel.exo_nbr);
|
|
|
|
% Evaluate the residuals and jacobian of the dynamic model in periods t and t+1.
|
|
fprintf(fid, 'if nargout>1\n');
|
|
fprintf(fid, ' J = zeros(%u, %u);\n', 2*DynareModel.endo_nbr, n0+n1+n2+DynareModel.endo_nbr);
|
|
fprintf(fid, ' [F(1:%u), tmp] = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2);
|
|
fprintf(fid, ' J(1:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr, n0+n1+n2, n0+n1+n2);
|
|
fprintf(fid, ' [F(%u:%u), tmp] = %s.dynamic(Y(1+%u:%u), x, p, y, 1);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2, 2*(n0+n1+n2));
|
|
fprintf(fid, ' J(%u:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1+n2, n0+n1+n2);
|
|
fprintf(fid, 'else\n');
|
|
fprintf(fid, ' F(1:%u) = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2);
|
|
fprintf(fid, ' F(%u:%u) = %s.dynamic(Y(1+%u:%u), x, p, y, 1);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2, 2*(n0+n1+n2));
|
|
fprintf(fid, 'end\n\n');
|
|
|
|
% Compute the jacobian if required.
|
|
fprintf(fid, 'if nargout>1\n');
|
|
fprintf(fid, ' JAC = zeros(%u,%u);\n', 2*DynareModel.endo_nbr, 2*DynareModel.endo_nbr);
|
|
|
|
% Compute the derivatives of the first block of equations (period t)
|
|
% with respect to the endogenous variables.
|
|
if purely_backward_model || purely_forward_model
|
|
for i=1:DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u);\n', i, j, i, I1(j), j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u);\n', i, j, i, I0(j));
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
for i=1:DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I2(j)
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j, i, I2(j), j, j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, i, I2(j), j, j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), i, I2(j), j, j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I2(j), j, j);
|
|
end
|
|
end
|
|
else
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u);\n', i, j, i, I1(j), j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u);\n', i, j, i, I0(j));
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
% Compute the derivatives of the second block of equations (period t+1)
|
|
% with respect to the endogenous variables.
|
|
if purely_backward_model || purely_forward_model
|
|
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u, %u) = J(%u, %u)*g(%u);\n', i, j, i, I0(j), j);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I2(j)
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j, i, I2(j), j, j, j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, j, i, I2(j), j, j, j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I2(j), j, j, j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I2(j), j, j, j);
|
|
end
|
|
end
|
|
else
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j);
|
|
else
|
|
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' JAC(%u, %u) = J(%u, %u)*g(%u);\n', i, j, i, I0(j), j);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
% Compute the derivatives of the first block of equations (period t)
|
|
% with respect to the growth factors.
|
|
if purely_backward_model || purely_forward_model
|
|
for i=1:DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I1(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j);
|
|
end
|
|
end
|
|
end
|
|
else
|
|
for i=1:DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I2(j)
|
|
if I1(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+J(%u,%u)*2*g(%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j, i, I2(j), j, j);
|
|
else
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*2*g(%u)*y(%u);\n', i, n0+n1+n2+j, i, I2(j), j, j);
|
|
end
|
|
else
|
|
if I1(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
% Compute the derivatives of the second block of equations (period t+1)
|
|
% with respect to the endogenous variables.
|
|
if purely_backward_model || purely_forward_model
|
|
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I0(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)+J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, n0+n1+n2+j, i, I0(j), j);
|
|
end
|
|
if I1(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)+2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, n0+n1+n2+j, i, I1(j), j, j);
|
|
end
|
|
end
|
|
end
|
|
else
|
|
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
|
|
for j=1:DynareModel.endo_nbr
|
|
if I2(j)
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+2*J(%u,%u)*y(%u)*g(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I1(j), j, j, i, I2(j), j, j, j);
|
|
else
|
|
fprintf(fid, ' J(%u,%u) = 2*J(%u,%u)*y(%u)*g(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I1(j), j, j, i, I2(j), j, j, j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I2(j), j, j, j);
|
|
else
|
|
fprintf(fid, ' J(%u,%u) = 3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I2(j), j, j, j);
|
|
end
|
|
end
|
|
else
|
|
if I1(j)
|
|
if I0(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I1(j), j, j);
|
|
else
|
|
fprintf(fid, ' J(%u,%u) = 2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, I1(j), j, j);
|
|
end
|
|
else
|
|
if I0(j)
|
|
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I0(j), j);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
fprintf(fid, ' JAC(:,%u:%u) = J(:,%u:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1+n2+1, n0+n1+n2+DynareModel.endo_nbr);
|
|
|
|
fprintf(fid,'end\n');
|
|
fclose(fid); |