diff --git a/matlab/+bgp/write.m b/matlab/+bgp/write.m index e0161d3638a771ad094de4fdefa7b7774835251c..a46ea55a42b0ae0e13aab4238546f1168bbeab4b 100644 --- a/matlab/+bgp/write.m +++ b/matlab/+bgp/write.m @@ -15,7 +15,7 @@ function write(M_) % REMARKS % - The trends are assumed to be multiplicative. -% Copyright © 2019-2023 Dynare Team +% Copyright © 2019-2024 Dynare Team % % This file is part of Dynare. % @@ -84,37 +84,40 @@ fprintf(fid, 'y = z(1:%u);\n\n', M_.endo_nbr); fprintf(fid, 'g = z(%u:%u);\n', M_.endo_nbr+1, 2*M_.endo_nbr); % Define the point where the dynamic model is to be evaluated. -fprintf(fid, 'Y = zeros(%u, 1);\n', 2*(n0+n1+n2)); +% In period t, then in period t+1 +fprintf(fid, 'Y0 = NaN(%u, 1);\n', 3*M_.endo_nbr); +fprintf(fid, 'Y1 = NaN(%u, 1);\n', 3*M_.endo_nbr); for i=1:length(I0) % period t equations, lagged variables. if I0(i) - fprintf(fid, 'Y(%u) = y(%u);\n', I0(i), i); + fprintf(fid, 'Y0(%u) = y(%u);\n', i+(purely_forward_model*M_.endo_nbr), 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); + fprintf(fid, 'Y0(%u) = y(%u)*g(%u);\n', i+M_.endo_nbr+(purely_forward_model*M_.endo_nbr), 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); + fprintf(fid, 'Y0(%u) = y(%u)*g(%u)*g(%u);\n', i+2*M_.endo_nbr, 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); + fprintf(fid, 'Y1(%u) = y(%u)*g(%u);\n', i+(purely_forward_model*M_.endo_nbr), 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); + fprintf(fid, 'Y1(%u) = y(%u)*g(%u)*g(%u);\n', i+M_.endo_nbr+(purely_forward_model*M_.endo_nbr), 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); + fprintf(fid, 'Y1(%u) = y(%u)*g(%u)*g(%u)*g(%u);\n', i+2*M_.endo_nbr, i, i, i, i); end end + fprintf(fid, '\n'); % Define the vector of parameters. @@ -131,19 +134,36 @@ fprintf(fid, 'F = NaN(%u, 1);\n', 2*M_.endo_nbr); fprintf(fid, 'x = zeros(1, %u);\n\n', M_.exo_nbr); % Evaluate the residuals and jacobian of the dynamic model in periods t and t+1. +fprintf(fid, '[F(1:%u), T0_order, T0] = %s.sparse.dynamic_resid(Y0, x, p, y);\n', M_.endo_nbr, M_.fname); +fprintf(fid, '[F(%u:%u), T1_order, T1] = %s.sparse.dynamic_resid(Y1, x, p, y);\n', M_.endo_nbr+1, 2*M_.endo_nbr, M_.fname); fprintf(fid, 'if nargout>1\n'); +fprintf(fid, ' sparse_rowval = ['); +fprintf(fid, '%u ', M_.dynamic_g1_sparse_rowval); +fprintf(fid, '];\n'); +fprintf(fid, ' sparse_colval = ['); +fprintf(fid, '%u ', M_.dynamic_g1_sparse_colval); +fprintf(fid, '];\n'); +fprintf(fid, ' sparse_colptr = ['); +fprintf(fid, '%u ', M_.dynamic_g1_sparse_colptr); +fprintf(fid, '];\n'); +fprintf(fid, ' J0 = %s.sparse.dynamic_g1(Y0, x, p, y, sparse_rowval, sparse_colval, sparse_colptr, T0_order, T0);\n', M_.fname); +fprintf(fid, ' J1 = %s.sparse.dynamic_g1(Y1, x, p, y, sparse_rowval, sparse_colval, sparse_colptr, T1_order, T1);\n', M_.fname); + +% Transform back the Jacobians J0 and J1 in the legacy format (non-sparse) +% NB: it is probably possible to simplify the rest of this file, but maintaining +% decent performance does not seem straightforward. +lli = find(M_.lead_lag_incidence'); +if purely_forward_model + lli = lli + M_.endo_nbr; +end +fprintf(fid, ' lli = ['); +fprintf(fid, '%u ', lli); +fprintf(fid, '];\n'); + fprintf(fid, ' J = zeros(%u, %u);\n', 2*M_.endo_nbr, n0+n1+n2+M_.endo_nbr); -fprintf(fid, ' [F(1:%u), tmp] = %s.dynamic(Y(1:%u), x, p, y, 1);\n', M_.endo_nbr, M_.fname, n0+n1+n2); -fprintf(fid, ' J(1:%u,1:%u) = tmp(:,1:%u);\n', M_.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', M_.endo_nbr+1, 2*M_.endo_nbr, M_.fname, n0+n1+n2, 2*(n0+n1+n2)); -fprintf(fid, ' J(%u:%u,1:%u) = tmp(:,1:%u);\n', M_.endo_nbr+1, 2*M_.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', M_.endo_nbr, M_.fname, n0+n1+n2); -fprintf(fid, ' F(%u:%u) = %s.dynamic(Y(1+%u:%u), x, p, y, 1);\n', M_.endo_nbr+1, 2*M_.endo_nbr, M_.fname, n0+n1+n2, 2*(n0+n1+n2)); -fprintf(fid, 'end\n\n'); +fprintf(fid, ' J(1:%u,1:%u) = full(J0(:,lli));\n', M_.endo_nbr, n0+n1+n2); +fprintf(fid, ' J(%u:%u,1:%u) = full(J1(:,lli));\n', M_.endo_nbr+1, 2*M_.endo_nbr, n0+n1+n2); -% Compute the jacobian if required. -fprintf(fid, 'if nargout>1\n'); fprintf(fid, ' JAC = zeros(%u,%u);\n', 2*M_.endo_nbr, 2*M_.endo_nbr); % Compute the derivatives of the first block of equations (period t) @@ -279,7 +299,7 @@ else end % Compute the derivatives of the second block of equations (period t+1) -% with respect to the endogenous variables. +% with respect to the growth factors. if purely_backward_model || purely_forward_model for i=M_.eq_nbr+1:2*M_.eq_nbr for j=1:M_.endo_nbr @@ -328,4 +348,4 @@ end fprintf(fid, ' JAC(:,%u:%u) = J(:,%u:%u);\n', M_.endo_nbr+1, 2*M_.endo_nbr, n0+n1+n2+1, n0+n1+n2+M_.endo_nbr); fprintf(fid,'end\n'); -fclose(fid); \ No newline at end of file +fclose(fid);