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 . i0 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the lagged variables. i1 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the current variables. n0 = length(find(i0)); % Number of lagged variables. n1 = length(find(i1)); % Number of current variables. % 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)); 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(i0) % period t+1 equaions lagged variables. if i0(i) fprintf(fid, 'Y(%u) = y(%u)*g(%u);\n', n0+n1+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+i1(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+DynareModel.endo_nbr); fprintf(fid, ' [F(1:%u), tmp] = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n1+n0); fprintf(fid, ' J(1:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr, n0+n1, n0+n1); 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, n1+n0, 2*(n1+n0)); fprintf(fid, ' J(%u:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1, n0+n1); fprintf(fid, 'else\n'); fprintf(fid, ' F(1:%u) = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n1+n0); 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, n1+n0, 2*(n1+n0)); 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. 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 % Compute the derivatives of the second block of equations (period t+1) % with respect to the endogenous variables. 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 % Compute the derivatives of the first block of equations (period t) % with respect to the growth factors. 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+j, i, i1(j), j); end end end % Compute the derivatives of the second block of equations (period t+1) % with respect to the endogenous variables. 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+j, i, n0+n1+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+j, i, n0+n1+j, i, i1(j), j, j); end end end fprintf(fid, ' JAC(:,%u:%u) = J(:,%u:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1+1, n0+n1+DynareModel.endo_nbr); fprintf(fid,'end\n'); % Close file. fclose(fid);