diff --git a/matlab/dyn_first_order_solver.m b/matlab/dyn_first_order_solver.m index c36fc31fd7beff64b93ee235598a21690c953810..2bca4871d726d119ab95e9f58a55cf24fc266a90 100644 --- a/matlab/dyn_first_order_solver.m +++ b/matlab/dyn_first_order_solver.m @@ -175,15 +175,14 @@ B(:,cols_b) = aa(:,index_c); % Jacobian matrix for contemporaneous endogeneous C = aa(:,index_p); % Jacobain matrix for led endogeneous variables info = 0; -info1 = 1; if task ~= 1 && (DynareOptions.dr_cycle_reduction || DynareOptions.dr_logarithmic_reduction) if n_current < DynareModel.endo_nbr if DynareOptions.dr_cycle_reduction error(['The cycle reduction algorithme can''t be used when the ' ... - 'coefficient matrix for current variables is singular']) + 'coefficient matrix for current variables isn''t invertible']) elseif DynareOptions.dr_logarithmic_reduction error(['The logarithmic reduction algorithme can''t be used when the ' ... - 'coefficient matrix for current variables is singular']) + 'coefficient matrix for current variables isn''t invertible']) end end if DynareOptions.gpu @@ -195,16 +194,18 @@ if task ~= 1 && (DynareOptions.dr_cycle_reduction || DynareOptions.dr_logarithmi B1 = [aa(row_indx,index_0m) aa(row_indx,index_0p) ]; C1 = [zeros(ndynamic,npred) aa(row_indx,index_p)]; if DynareOptions.dr_cycle_reduction == 1 - [ghx, info1] = cycle_reduction(A1, B1, C1, DynareOptions.dr_cycle_reduction_tol); + [ghx, info] = cycle_reduction(A1, B1, C1, DynareOptions.dr_cycle_reduction_tol); else - [ghx, info1] = logarithmic_reduction(C1, B1, A1, DynareOptions.dr_logarithmic_reduction_tol, DynareOptions.dr_logarithmic_reduction_maxiter); + [ghx, info] = logarithmic_reduction(C1, B1, A1, DynareOptions.dr_logarithmic_reduction_tol, DynareOptions.dr_logarithmic_reduction_maxiter); + end + if info + % cycle_reduction or logarithmic redution failed and set info + return end ghx = ghx(:,index_m); hx = ghx(1:npred+nboth,:); gx = ghx(1+npred:end,:); -end - -if info1 == 1 +else D = zeros(ndynamic+nboth); E = zeros(ndynamic+nboth); D(row_indx_de_1,index_d1) = aa(row_indx,index_d); @@ -214,11 +215,11 @@ if info1 == 1 E = [-aa(row_indx,[index_m index_0p]) ; [zeros(nboth,nboth+npred) eye(nboth,nboth+nfwrd) ] ]; - [err, ss, tt, w, sdim, dr.eigval, info2] = mjdgges(E,D,DynareOptions.qz_criterium); + [err, ss, tt, w, sdim, dr.eigval, info1] = mjdgges(E,D,DynareOptions.qz_criterium); mexErrCheck('mjdgges', err); - if info2 - if info2 == -30 + if info1 + if info1 == -30 % one eigenvalue is close to 0/0 info(1) = 7; else @@ -260,20 +261,25 @@ if info1 == 1 % derivatives with respect to dynamic state variables % forward variables Z = w'; - Z11t = Z(indx_stable_root, indx_stable_root)'; + Z11 = Z(indx_stable_root, indx_stable_root); Z21 = Z(indx_explosive_root, indx_stable_root); Z22 = Z(indx_explosive_root, indx_explosive_root); - if ~isscalar(Z22) && (condest(Z22) > 1e9) + [minus_gx,rc] = linsolve(Z22,Z21); + if rc < 1e-9 + % Z22 is near singular info(1) = 5; - info(2) = condest(Z22); + info(2) = -log(rc); return; - else - gx = - Z22 \ Z21; end + gx = -minus_gx; % predetermined variables - hx = Z11t * inv(tt(indx_stable_root, indx_stable_root)) * ss(indx_stable_root, indx_stable_root) * inv(Z11t); + opts.UT = true; + opts.TRANSA = true; + hx1 = linsolve(tt(indx_stable_root, indx_stable_root),Z11,opts)'; + opts.UT = false; + hx2 = linsolve(Z11,ss(indx_stable_root, indx_stable_root)',opts)'; + hx = hx1*hx2; ghx = [hx(k1,:); gx(k2(nboth+1:end),:)]; - end dr.gx = gx;