diff --git a/matlab/build_two_dim_hessian.m b/matlab/build_two_dim_hessian.m new file mode 100644 index 000000000..802c7c1fc --- /dev/null +++ b/matlab/build_two_dim_hessian.m @@ -0,0 +1,58 @@ +function H = build_two_dim_hessian(sparse_indices, g2_v, neq, nvar) +% Creates a 2D Hessian (equations in rows, pairs of variables in columns), +% given the output from the sparse {static,dynamic}_g2.m +% +% – sparse_indices is typically equal to M_.{static,dynamic}_g2_sparse_indices +% – g2_v is the vector of non zero values returned by {static,dynamic}_g2.m +% – neq is the number of equations (equal to number of rows of the output matrix) +% – nvar is the number of variables (the output matrix will have nvar² columns) + +% Copyright © 2024 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 . + +nnz = size(sparse_indices, 1); + +%% The g2_* arrays may be expanded if there are symmetric elements added +g2_i = int32(zeros(nnz, 1)); +g2_j = int32(zeros(nnz, 1)); + +next_sym_idx = nnz + 1; % Index of next symmetric element to be added + +for k = 1:length(g2_v) + eq = sparse_indices(k, 1); + var1 = sparse_indices(k, 2)-1; + var2 = sparse_indices(k, 3)-1; + + g2_i(k) = eq; + g2_j(k) = var1 * nvar + var2 + 1; + + %% Add symmetric elements, which are not included by sparse {static,dynamic}_g2.m + if var1 ~= var2 + g2_i(next_sym_idx) = eq; + g2_j(next_sym_idx) = var2 * nvar + var1 + 1; + g2_v(next_sym_idx) = g2_v(k); + next_sym_idx = next_sym_idx + 1; + end +end + +%% On MATLAB < R2020a, sparse() does not accept int32 indices +if ~isoctave && matlab_ver_less_than('9.8') + g2_i = double(g2_i); + g2_j = double(g2_j); +end + +H = sparse(g2_i, g2_j, g2_v, neq, nvar*nvar); diff --git a/matlab/discretionary_policy/discretionary_policy_1.m b/matlab/discretionary_policy/discretionary_policy_1.m index 30f7ca048..440b74f6a 100644 --- a/matlab/discretionary_policy/discretionary_policy_1.m +++ b/matlab/discretionary_policy/discretionary_policy_1.m @@ -13,7 +13,7 @@ function [dr, info, params]=discretionary_policy_1(M_, options_, dr, endo_steady % - info [integer] scalar or vector, error code. % - params [double] vector of potentially updated parameters -% Copyright © 2007-2020 Dynare Team +% Copyright © 2007-2024 Dynare Team % % This file is part of Dynare. % @@ -49,7 +49,9 @@ else end params=M_.params; -[~,Uy,W] = feval([M_.fname,'.objective.static'],zeros(M_.endo_nbr,1),[], M_.params); +y = zeros(M_.endo_nbr,1); +[Uy, T_order, T] = feval([M_.fname,'.objective.sparse.static_g1'], y, [], params, M_.objective_g1_sparse_rowval, M_.objective_g1_sparse_colval, M_.objective_g1_sparse_colptr); + if any(any(isnan(Uy))) info = 64 ; %the derivatives of the objective function contain NaN return; @@ -70,6 +72,8 @@ if any(any(Uy~=0)) return; end +g2_v = feval([M_.fname,'.objective.sparse.static_g2'], y, [], params, T_order, T); +W = build_two_dim_hessian(M_.objective_g2_sparse_indices, g2_v, 1, M_.endo_nbr); W=reshape(W,M_.endo_nbr,M_.endo_nbr); klen = M_.maximum_lag + M_.maximum_lead + 1; @@ -122,4 +126,4 @@ dr.ghu=G(dr.order_var,:); if M_.maximum_endo_lag Selection=M_.lead_lag_incidence(1,dr.order_var)>0;%select state variables end -dr.ghx=T(:,Selection); \ No newline at end of file +dr.ghx=T(:,Selection); diff --git a/preprocessor b/preprocessor index b134dba32..db1bad652 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit b134dba32c9bfc8e0ee25c4977e37558721d7737 +Subproject commit db1bad652209c2d6de9d42143bb2b51a0f507b5e