diff --git a/matlab/dr_block.m b/matlab/dr_block.m index 7f7df97cc83b1bd3bf2f92050d6cf3fab2c7c920..e7d7d0398f8817467b7c0818e5dbc634a3dfa57d 100644 --- a/matlab/dr_block.m +++ b/matlab/dr_block.m @@ -567,7 +567,9 @@ for i = 1:Size; if block_type == 5 vghx_other = - inv(kron(eye(size(D_,2)), A_) + kron(C_', B_)) * vec(D_); ghx_other = reshape(vghx_other, size(D_,1), size(D_,2)); - else + elseif options_.sylvester_fp == 1 + ghx_other = gensylv_fp(A_, B_, C_, D_, i); + else [err, ghx_other] = gensylv(1, A_, B_, C_, -D_); end; if options_.aim_solver ~= 1 && options_.use_qzdiv diff --git a/matlab/dsge_likelihood.m b/matlab/dsge_likelihood.m index fbb2d1eab32148bd45b1813bcbe388a62591ca74..282a8abddf715eedda08f6f28e378379efd08c2e 100644 --- a/matlab/dsge_likelihood.m +++ b/matlab/dsge_likelihood.m @@ -366,7 +366,11 @@ switch DynareOptions.lik_init % Use standard kalman filter except if the univariate filter is explicitely choosen. kalman_algo = 1; end - Pstar = lyapunov_symm(T,R*Q*R',DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold); + if DynareOptions.lyapunov_fp == 1 + Pstar = lyapunov_symm(T,Q,DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold, 4, R); + else + Pstar = lyapunov_symm(T,R*Q*R',DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold); + end; Pinf = []; a = zeros(mm,1); Zflag = 0; diff --git a/matlab/gensylv_fp.m b/matlab/gensylv_fp.m new file mode 100644 index 0000000000000000000000000000000000000000..f56a65a9183b7939b5ef45d0ef67a529e3dc71bb --- /dev/null +++ b/matlab/gensylv_fp.m @@ -0,0 +1,73 @@ +function X = gensylv_fp(A, B, C, D, block) +% function X = gensylv_fp(A, B, C, D) +% Solve the Sylvester equation: +% A * X + B * X * C + D = 0 +% INPUTS +% A +% B +% C +% D +% block : block number (for storage purpose) +% OUTPUTS +% X solution +% +% ALGORITHM +% fixed point method +% MARLLINY MONSALVE (2008): "Block linear method for large scale +% Sylvester equations", Computational & Applied Mathematics, Vol 27, n�1, +% p47-59 +% ||A^-1||.||B||.||C|| < 1 is a suffisant condition: +% - to get a unique solution for the Sylvester equation +% - to get a convergent fixed-point algorithm +% +% SPECIAL REQUIREMENTS +% none. +% Copyright (C) 1996-2010 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/>. + +%tol = 1e-07; +%tol = 1e-13; +tol = 1e-12; +evol = 100; +A1 = inv(A); +eval(['persistent hxo_' int2str(block) ';']); +hxo = eval(['hxo_' int2str(block) ';']); +if isempty(hxo) + X = zeros(size(B, 2), size(C, 1)); +else + X = hxo; +end; +it_fp = 0; +maxit_fp = 1000; +Z = - (B * X * C + D); +while it_fp < maxit_fp && evol > tol; + %X_old = X; + %X = - A1 * ( B * X * C + D); + %evol = max(max(abs(X - X_old))); + X = A1 * Z; + Z_old = Z; + Z = - (B * X * C + D); + evol = max(sum(abs(Z - Z_old))); %norm_1 + %evol = max(sum(abs(Z - Z_old)')); %norm_inf + it_fp = it_fp + 1; +end; +%fprintf('sylvester it_fp=%d evol=%g | ',it_fp,evol); +if evol < tol + eval(['hxo_' int2str(block) ' = X;']); +else + error(['convergence not achieved in fixed point solution of Sylvester equation after ' int2str(it_fp) ' iterations']); +end; \ No newline at end of file diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m index 2ee53d90f3d7a75d351085da5a8509ce5c1d7be0..0e5dd3eefc9c00d3585ca5ca60331254b2208de6 100644 --- a/matlab/global_initialization.m +++ b/matlab/global_initialization.m @@ -382,6 +382,14 @@ options_.use_dll = 0; % model evaluated using bytecode.dll options_.bytecode = 0; +% use a fixed point method to solve Sylvester equation (for large scale +% models) +options_.sylvester_fp = 0; + +% use a fixed point method to solve Lyapunov equation (for large scale +% models) +options_.lyapunov_fp = 0; + % dates for historical time series options_.initial_date.freq = 1; options_.initial_date.period = 1; diff --git a/matlab/lyapunov_symm.m b/matlab/lyapunov_symm.m index d32f644394bb8f537abe97ad2b64768e4669c169..afa763c82f43036ff0332c643a79609bf1d7438d 100644 --- a/matlab/lyapunov_symm.m +++ b/matlab/lyapunov_symm.m @@ -1,4 +1,4 @@ -function [x,u] = lyapunov_symm(a,b,qz_criterium,lyapunov_complex_threshold,method) +function [x,u] = lyapunov_symm(a,b,qz_criterium,lyapunov_complex_threshold,method, R) % Solves the Lyapunov equation x-a*x*a' = b, for b and x symmetric matrices. % If a has some unit roots, the function computes only the solution of the stable subsystem. % @@ -12,6 +12,7 @@ function [x,u] = lyapunov_symm(a,b,qz_criterium,lyapunov_complex_threshold,metho % variables and the schur decomposition is triggered. % method=2 then U, T, n and k are declared as persistent % variables and the schur decomposition is not performed. +% method=3 fixed point method % OUTPUTS % x: [double] m*m solution matrix of the lyapunov equation, where m is the dimension of the stable subsystem. % u: [double] Schur vectors associated with unit roots @@ -38,10 +39,55 @@ function [x,u] = lyapunov_symm(a,b,qz_criterium,lyapunov_complex_threshold,metho % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see <http://www.gnu.org/licenses/>. - if nargin<5 method = 0; end + +if method == 3 + persistent X method1; + if ~isempty(method1) + method = method1; + end; + fprintf(' [methode=%d] ',method); + if method == 3 + %tol = 1e-8; + tol = 1e-10; + it_fp = 0; + evol = 100; + if isempty(X) + X = b; + max_it_fp = 2000; + else + max_it_fp = 300; + end; + at = a'; + %fixed point iterations + while evol > tol && it_fp < max_it_fp; + X_old = X; + X = a * X * at + b; + evol = max(sum(abs(X - X_old))); %norm_1 + %evol = max(sum(abs(X - X_old)')); %norm_inf + it_fp = it_fp + 1; + end; + fprintf('lyapunov it_fp=%d evol=%g\n',it_fp,evol); + if it_fp >= max_it_fp + disp(['convergence not achieved in solution of Lyapunov equation after ' int2str(it_fp) ' iterations, switching method from 3 to 0']); + method1 = 0; + method = 0; + else + method1 = 3; + x = X; + return; + end; + end; +elseif method == 4 + % works only with Matlab System Control toolbox + chol_b = R*chol(b,'lower'); + Rx = dlyapchol(a,chol_b); + x = Rx' * Rx; + return; +end; + if method persistent U T k n else @@ -113,4 +159,4 @@ if i == 1 x(1,1) = (B(1,1)+c)/(1-T(1,1)*T(1,1)); end x = U(:,k+1:end)*x*U(:,k+1:end)'; -u = U(:,1:k); \ No newline at end of file +u = U(:,1:k); diff --git a/mex/sources/bytecode/ErrorHandling.hh b/mex/sources/bytecode/ErrorHandling.hh index 9856b4338c719f3039411c8462397873d4ed4202..a27e5fe44b6af308fb2496d5bb829788a3a57dd0 100644 --- a/mex/sources/bytecode/ErrorHandling.hh +++ b/mex/sources/bytecode/ErrorHandling.hh @@ -113,7 +113,10 @@ public: value2(value2_arg) { ostringstream tmp; - tmp << " with X=" << value1 << "\n"; + if (abs(value1) > 1e-10 ) + tmp << " with X=" << value1 << "\n"; + else + tmp << " with X=" << value1 << " and a=" << value2 << "\n"; completeErrorMsg(tmp.str()); }; }; diff --git a/mex/sources/bytecode/Interpreter.cc b/mex/sources/bytecode/Interpreter.cc index d8dc69987276d48f8be780e71d25a4a75d02dc03..a75943b5acd05eb3c5ee6d036d3d8ca9f6c78275 100644 --- a/mex/sources/bytecode/Interpreter.cc +++ b/mex/sources/bytecode/Interpreter.cc @@ -71,7 +71,7 @@ double Interpreter::pow1(double a, double b) { double r = pow_(a, b); - if (isnan(r)) + if (isnan(r) || isinf(r)) { res1 = NAN; r = 0.0000000000000000000000001; @@ -85,7 +85,7 @@ double Interpreter::divide(double a, double b) { double r = a / b; - if (isinf(r)) + if (isnan(r) || isinf(r)) { res1 = NAN; r = 1e70; @@ -99,7 +99,7 @@ double Interpreter::log1(double a) { double r = log(a); - if (isnan(r)) + if (isnan(r) || isinf(r)) { res1 = NAN; r = -1e70; @@ -113,7 +113,7 @@ double Interpreter::log10_1(double a) { double r = log(a); - if (isnan(r)) + if (isnan(r) || isinf(r)) { res1 = NAN; r = -1e70; @@ -1718,6 +1718,16 @@ Interpreter::evaluate_a_block(const int size, const int type, string bin_basenam } } + +void +Interpreter::SingularDisplay(int Per_u_, bool evaluate, int Block_Count, int size, bool steady_state, it_code_type begining) +{ + it_code = begining; + compute_block_time(Per_u_, evaluate, Block_Count, size, steady_state); + Singular_display(Block_Count, size, steady_state, begining); +} + + int Interpreter::simulate_a_block(const int size, const int type, string file_name, string bin_basename, bool Gaussian_Elimination, bool steady_state, bool print_it, int block_num, const bool is_linear, const int symbol_table_endo_nbr, const int Block_List_Max_Lag, const int Block_List_Max_Lead, const int u_count_int) @@ -1726,6 +1736,7 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, int i; bool cvg; bool result = true; + bool singular_system; double *y_save; res1 = 0; #ifdef DEBUG @@ -1979,7 +1990,10 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, if (cvg) continue; int prev_iter = iter; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); + iter++; if (iter > prev_iter) { @@ -2024,7 +2038,9 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, } else cvg = false; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); if (!result) { mexPrintf(" in Solve Forward complete, convergence not achieved in block %d\n", Block_Count+1); @@ -2076,7 +2092,9 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, if (cvg) continue; int prev_iter = iter; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); iter++; if (iter > prev_iter) { @@ -2123,7 +2141,9 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, } else cvg = false; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); } } } @@ -2181,7 +2201,9 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, if (cvg) continue; int prev_iter = iter; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); iter++; if (iter > prev_iter) { @@ -2225,7 +2247,9 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, } else cvg = false; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, 0, 0, 0, size, print_it, cvg, iter, true, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); if (!result) { mexPrintf(" in Solve Backward complete, convergence not achieved in block %d\n", Block_Count+1); @@ -2277,7 +2301,9 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, if (cvg) continue; int prev_iter = iter; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); iter++; if (iter > prev_iter) { @@ -2320,7 +2346,9 @@ Interpreter::simulate_a_block(const int size, const int type, string file_name, } else cvg = false; - Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + singular_system = Simulate_Newton_One_Boundary(Block_Count, symbol_table_endo_nbr, it_, y_kmin, y_kmax, size, print_it, cvg, iter, false, stack_solve_algo, solve_algo); + if (singular_system) + SingularDisplay(0, false, block_num, size, steady_state, begining); } } } diff --git a/mex/sources/bytecode/Interpreter.hh b/mex/sources/bytecode/Interpreter.hh index 8b971e22710697e16e2b9e5e76273bfee7c1538e..22778b14dbaf97193635c1db1e513e20e1111353 100644 --- a/mex/sources/bytecode/Interpreter.hh +++ b/mex/sources/bytecode/Interpreter.hh @@ -61,6 +61,7 @@ protected: void print_a_block(const int size, const int type, string bin_basename, bool steady_state, int block_num, const bool is_linear, const int symbol_table_endo_nbr, const int Block_List_Max_Lag, const int Block_List_Max_Lead, const int u_count_int, int block); + void SingularDisplay(int Per_u_, bool evaluate, int Block_Count, int size, bool steady_state, it_code_type begining); vector<Block_contain_type> Block_Contain; code_liste_type code_liste; it_code_type it_code; diff --git a/mex/sources/bytecode/SparseMatrix.cc b/mex/sources/bytecode/SparseMatrix.cc index a7cf3769882b27ab9ee1014ac0ef4dc6208a9b39..db577ac11b97f2c87d7e885f022bdc805d6b0c67 100644 --- a/mex/sources/bytecode/SparseMatrix.cc +++ b/mex/sources/bytecode/SparseMatrix.cc @@ -366,7 +366,7 @@ SparseMatrix::Read_SparseMatrix(string file_name, const int Size, int periods, i } void -SparseMatrix::Simple_Init(int it_, int y_kmin, int y_kmax, int Size, map<pair<pair<int, int>, int>, int> &IM, bool &zero_solution) +SparseMatrix::Simple_Init(int Size, map<pair<pair<int, int>, int>, int> &IM, bool &zero_solution) { int i, eq, var, lag; map<pair<pair<int, int>, int>, int>::iterator it4; @@ -2153,6 +2153,94 @@ SparseMatrix::Solve_Matlab_BiCGStab(mxArray *A_m, mxArray *b_m, int Size, double } void +SparseMatrix::Singular_display(int block, int Size, bool steady_state, it_code_type it_code) +{ + bool zero_solution; + Simple_Init(Size, IM_i, zero_solution); + NonZeroElem *first; + mxArray *rhs[1]; + rhs[0] = mxCreateDoubleMatrix(Size, Size, mxREAL); + double *pind; + pind = mxGetPr(rhs[0]); + for (int j = 0; j < Size * Size; j++) + pind[j] = 0.0; + for (int ii = 0; ii < Size; ii++) + { + int nb_eq = At_Col(ii, &first); + for (int j = 0; j < nb_eq; j++) + { + int k = first->u_index; + int jj = first->r_index; + pind[ii * Size + jj ] = u[k]; + first = first->NZE_C_N; + } + } + mxArray *lhs[3]; + mexCallMATLAB(3, lhs, 1, rhs, "svd"); + mxArray* SVD_u = lhs[0]; + mxArray* SVD_s = lhs[1]; + mxArray* SVD_v = lhs[2]; + double *SVD_ps = mxGetPr(SVD_s); + double *SVD_pu = mxGetPr(SVD_u); + for (int i = 0; i < Size; i++) + { + if (abs(SVD_ps[i * (1 + Size)]) < 1e-12) + { + mexPrintf(" The following equations form a linear combination:\n "); + double max_u = 0; + for (int j = 0; j < Size; j++) + if (abs(SVD_pu[j + i * Size]) > abs(max_u)) + max_u = SVD_pu[j + i * Size]; + vector<int> equ_list; + for (int j = 0; j < Size; j++) + { + double rr = SVD_pu[j + i * Size] / max_u; + if ( rr < -1e-10) + { + equ_list.push_back(j); + if (rr != -1) + mexPrintf(" - %3.2f*Dequ_%d_dy",abs(rr),j+1); + else + mexPrintf(" - Dequ_%d_dy",j+1); + } + else if (rr > 1e-10) + { + equ_list.push_back(j); + if (j > 0) + if (rr != 1) + mexPrintf(" + %3.2f*Dequ_%d_dy",rr,j+1); + else + mexPrintf(" + Dequ_%d_dy",j+1); + else + if (rr != 1) + mexPrintf(" %3.2f*Dequ_%d_dy",rr,j+1); + else + mexPrintf(" Dequ_%d_dy",j+1); + } + } + mexPrintf(" = 0\n"); + /*mexPrintf(" with:\n"); + it_code = get_begin_block(block); + for (int j=0; j < Size; j++) + { + if (find(equ_list.begin(), equ_list.end(), j) != equ_list.end()) + mexPrintf(" equ_%d: %s\n",j, print_expression(it_code_expr, false, Size, block, steady_state, 0, 0, it_code, true).c_str()); + }*/ + } + } + mxDestroyArray(lhs[0]); + mxDestroyArray(lhs[1]); + mxDestroyArray(lhs[2]); + ostringstream tmp; + if (block > 1) + tmp << " in Solve_ByteCode_Sparse_GaussianElimination, singular system in block " << block+1 << "\n"; + else + tmp << " in Solve_ByteCode_Sparse_GaussianElimination, singular system\n"; + throw FatalExceptionHandling(tmp.str()); +} + + +bool SparseMatrix::Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, bool steady_state, int it_) { bool one; @@ -2219,7 +2307,6 @@ SparseMatrix::Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, bool } if (piv_abs < eps) { - mexEvalString("drawnow;"); mxFree(piv_v); mxFree(pivj_v); mxFree(pivk_v); @@ -2231,7 +2318,7 @@ SparseMatrix::Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, bool mexPrintf("Error: singular system in Simulate_NG in block %d\n", blck+1); else mexPrintf("Error: singular system in Simulate_NG\n"); - return; + return true; } else { @@ -2411,6 +2498,7 @@ SparseMatrix::Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, bool mxFree(pivk_v); mxFree(NR); mxFree(bc); + return false; } void @@ -2898,13 +2986,14 @@ SparseMatrix::Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bool End_GE(Size); } -void +bool SparseMatrix::Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state, int stack_solve_algo, int solve_algo) { int i, j; mxArray *b_m = NULL, *A_m = NULL, *x0_m = NULL; Clear_u(); error_not_printed = true; + bool singular_system = false; u_count_alloc_save = u_count_alloc; if (isnan(res1) || isinf(res1) || (res2 > 12*g0 && iter > 0)) { @@ -2931,7 +3020,7 @@ SparseMatrix::Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_ else mexPrintf(" dynare cannot improve the simulation in block %d at time %d (variable %d)\n", blck+1, it_+1, index_vara[max_res_idx]+1); mexEvalString("drawnow;"); - return; + return singular_system; } else { @@ -2972,11 +3061,11 @@ SparseMatrix::Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_ for (i = 0; i < y_size; i++) y[i+it_*y_size] = ya[i+it_*y_size] + slowc_save*direction[i+it_*y_size]; iter--; - return; + return singular_system; } if (cvg) { - return; + return singular_system; } if (print_it) { @@ -3024,7 +3113,7 @@ SparseMatrix::Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_ } bool zero_solution; if ((solve_algo == 5 && steady_state) || (stack_solve_algo == 5 && !steady_state)) - Simple_Init(it_, y_kmin, y_kmax, Size, IM_i, zero_solution); + Simple_Init(Size, IM_i, zero_solution); else { b_m = mxCreateDoubleMatrix(Size, 1, mxREAL); @@ -3063,7 +3152,7 @@ SparseMatrix::Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_ else { if ((solve_algo == 5 && steady_state) || (stack_solve_algo == 5 && !steady_state)) - Solve_ByteCode_Sparse_GaussianElimination(Size, blck, steady_state, it_); + singular_system = Solve_ByteCode_Sparse_GaussianElimination(Size, blck, steady_state, it_); else if ((solve_algo == 7 && steady_state) || (stack_solve_algo == 2 && !steady_state)) Solve_Matlab_GMRES(A_m, b_m, Size, slowc, blck, false, it_, steady_state, x0_m); else if ((solve_algo == 8 && steady_state) || (stack_solve_algo == 3 && !steady_state)) @@ -3071,7 +3160,7 @@ SparseMatrix::Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_ else if ((solve_algo == 6 && steady_state) || ((stack_solve_algo == 0 || stack_solve_algo == 1) && !steady_state)) Solve_Matlab_LU_UMFPack(A_m, b_m, Size, slowc, false, it_); } - return; + return singular_system; } void diff --git a/mex/sources/bytecode/SparseMatrix.hh b/mex/sources/bytecode/SparseMatrix.hh index dc7bb3861d28396df2b020cc3f994707f4b1b3f7..e6df80e9492ae7c159b6b6f81009ba104d648d88 100644 --- a/mex/sources/bytecode/SparseMatrix.hh +++ b/mex/sources/bytecode/SparseMatrix.hh @@ -63,21 +63,22 @@ class SparseMatrix : public ErrorMsg public: SparseMatrix(); void Simulate_Newton_Two_Boundaries(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, bool cvg, int &iter, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, char *P_endo_names) /*throw(ErrorHandlingException)*/; - void Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state, int stack_solve_algo, int solve_algo); + bool Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state, int stack_solve_algo, int solve_algo); void Direct_Simulate(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, int iter); void fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1); void Read_SparseMatrix(string file_name, const int Size, int periods, int y_kmin, int y_kmax, bool steady_state, bool two_boundaries, int stack_solve_algo, int solve_algo); void Read_file(string file_name, int periods, int u_size1, int y_size, int y_kmin, int y_kmax, int &nb_endo, int &u_count, int &u_count_init, double *u); + void Singular_display(int block, int Size, bool steady_state, it_code_type it_code); double g0, gp0, glambda2, try_at_iteration; private: void Init_GE(int periods, int y_kmin, int y_kmax, int Size, map<pair<pair<int, int>, int>, int> &IM); void Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Size, map<pair<pair<int, int>, int>, int> &IM, mxArray *A_m, mxArray *b_m, mxArray *x0_m); void Init_Matlab_Sparse_Simple(int Size, map<pair<pair<int, int>, int>, int> &IM, mxArray *A_m, mxArray *b_m, bool &zero_solution, mxArray *x0_m); - void Simple_Init(int it_, int y_kmin, int y_kmax, int Size, std::map<std::pair<std::pair<int, int>, int>, int> &IM, bool &zero_solution); + void Simple_Init(int Size, std::map<std::pair<std::pair<int, int>, int>, int> &IM, bool &zero_solution); void End_GE(int Size); void Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bool symbolic, int Block_number); - void Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, bool steady_state, int it_); + bool Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, bool steady_state, int it_); void Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned int Size, double slowc_l, bool is_two_boundaries, int it_); void Solve_Matlab_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_); void Solve_Matlab_GMRES(mxArray *A_m, mxArray *b_m, int Size, double slowc, int block, bool is_two_boundaries, int it_, bool steady_state, mxArray *x0_m); diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 6a5a2055b873cebe307af96a71ee7a4932a564c0..40857352d314936f48c81608ed7f7e783bc19946 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -100,6 +100,7 @@ class ParsingDriver; %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT %token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME %token <string_val> FLOAT_NUMBER +%token DEFAULT FIXED_POINT %token FORECAST K_ORDER_SOLVER INSTRUMENTS PRIOR SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN %token GAMMA_PDF GRAPH CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD %token HISTVAL HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HP_FILTER HP_NGRID @@ -108,7 +109,7 @@ class ParsingDriver; %token <string_val> DATE_NUMBER %token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF IRF_SHOCKS %token KALMAN_ALGO KALMAN_TOL SUBSAMPLES OPTIONS -%token LABELS LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR +%token LABELS LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LYAPUNOV %token MARKOWITZ MARGINAL_DENSITY MAX MAXIT %token MFS MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN MINIMAL_SOLVING_PERIODS %token MODE_CHECK MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN @@ -123,7 +124,7 @@ class ParsingDriver; %token QZ_CRITERIUM FULL DSGE_VAR DSGE_VARLAG DSGE_PRIOR_WEIGHT %token RELATIVE_IRF REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE %token SHOCKS SHOCK_DECOMPOSITION SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED SMOOTHER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO -%token STDERR STEADY STOCH_SIMUL +%token STDERR STEADY STOCH_SIMUL SYLVESTER %token TEX RAMSEY_POLICY PLANNER_DISCOUNT DISCRETIONARY_POLICY %token <string_val> TEX_NAME %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE @@ -694,8 +695,8 @@ svar_identification_elem : EXCLUSION LAG INT_NUMBER ';' svar_equation_list { driver.add_constants_exclusion(); } | RESTRICTION EQUATION INT_NUMBER COMMA { driver.add_restriction_equation_nbr($3);} - restriction_expression EQUAL - {driver.add_restriction_equal();} + restriction_expression EQUAL + {driver.add_restriction_equal();} restriction_expression ';' | UPPER_CHOLESKY ';' { driver.add_upper_cholesky(); } @@ -925,6 +926,7 @@ stoch_simul_options : o_dr_algo | o_conditional_variance_decomposition | o_k_order_solver | o_pruning + | o_sylvester ; symbol_list : symbol_list symbol @@ -1339,6 +1341,8 @@ estimation_options : o_datafile | o_cova_compute | o_irf_shocks | o_sub_draws + | o_sylvester + | o_lyapunov ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -2072,6 +2076,10 @@ o_aim_solver: AIM_SOLVER {driver.option_num("aim_solver", "1"); }; o_partial_information : PARTIAL_INFORMATION {driver.option_num("partial_information", "1"); }; o_sub_draws: SUB_DRAWS EQUAL INT_NUMBER {driver.option_num("sub_draws",$3);}; o_planner_discount : PLANNER_DISCOUNT EQUAL expression { driver.declare_optimal_policy_discount_factor_parameter($3); }; +o_sylvester : SYLVESTER EQUAL FIXED_POINT {driver.option_num("sylvester_fp", "1"); } + | SYLVESTER EQUAL DEFAULT {driver.option_num("sylvester_fp", "0"); }; +o_lyapunov : LYAPUNOV EQUAL FIXED_POINT {driver.option_num("lyapunov_fp", "1"); } + | LYAPUNOV EQUAL DEFAULT {driver.option_num("lyapunov_fp", "0"); }; o_bvar_prior_tau : BVAR_PRIOR_TAU EQUAL signed_number { driver.option_num("bvar_prior_tau", $3); }; o_bvar_prior_decay : BVAR_PRIOR_DECAY EQUAL non_negative_number { driver.option_num("bvar_prior_decay", $3); }; diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index 2d91d096e1330661937395ceac979b689a4cf6e0..a5010b5bdc198b1b411b8b09f1c68e324504268a 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -290,6 +290,8 @@ string eofbuff; <DYNARE_STATEMENT>dummy_obs {return token::DUMMY_OBS;} <DYNARE_STATEMENT>nstates {return token::NSTATES;} <DYNARE_STATEMENT>indxscalesstates {return token::INDXSCALESSTATES;} +<DYNARE_STATEMENT>fixed_point {return token::FIXED_POINT;} +<DYNARE_STATEMENT>default {return token::DEFAULT;} <DYNARE_STATEMENT>alpha { yylval->string_val = new string(yytext); return token::ALPHA; @@ -481,6 +483,8 @@ string eofbuff; <DYNARE_STATEMENT>stack_solve_algo {return token::STACK_SOLVE_ALGO;} <DYNARE_STATEMENT>drop {return token::DROP;} <DYNARE_STATEMENT>order {return token::ORDER;} +<DYNARE_STATEMENT>sylvester {return token::SYLVESTER;} +<DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;} <DYNARE_STATEMENT>replic {return token::REPLIC;} <DYNARE_STATEMENT>ar {return token::AR;} <DYNARE_STATEMENT>nofunctions {return token::NOFUNCTIONS;} diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 80e01abd517a18ad095e0fc8e1e2ce377e557e27..db60330e4a0a308531d3c59158a5777e0700b8cc 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -2264,7 +2264,7 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in else { //First time encountering this external function i.e., not previously declared or encountered if (in_model_block) - error("To use an external function within the model block, you must first declare it via the external_function() statement."); + error("To use an external function (" + *function_name + ") within the model block, you must first declare it via the external_function() statement."); declare_symbol(function_name, eExternalFunction, NULL); current_external_function_options.nargs = stack_external_function_args.top().size();