diff --git a/matlab/dynare_solve_block_or_bytecode.m b/matlab/dynare_solve_block_or_bytecode.m index f1316b281..3fafaf0d1 100644 --- a/matlab/dynare_solve_block_or_bytecode.m +++ b/matlab/dynare_solve_block_or_bytecode.m @@ -37,10 +37,10 @@ if options.block && ~options.bytecode ss(M.block_structure_stat.block(b).variable) = y; else n = length(M.block_structure_stat.block(b).variable); - [ss, T, check] = solve_one_boundary([M.fname '.block.static_' int2str(b)], ss, exo, ... - params, [], T, M.block_structure_stat.block(b).variable, n, 1, false, b, 0, options.simul.maxit, ... - options.solve_tolf, ... - options.slowc, 0, options.solve_algo, true, false, false, M, options); + [ss, T, ~, check] = solve_one_boundary([M.fname '.block.static_' int2str(b)], ss, exo, ... + params, [], T, M.block_structure_stat.block(b).variable, n, 1, false, b, 0, options.simul.maxit, ... + options.solve_tolf, ... + options.slowc, 0, options.solve_algo, true, false, false, M, options, []); if check info = 1; return diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver_core.m b/matlab/perfect-foresight-models/perfect_foresight_solver_core.m index 267545d69..ff7616d32 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_solver_core.m +++ b/matlab/perfect-foresight-models/perfect_foresight_solver_core.m @@ -60,7 +60,7 @@ if options_.block oo_.deterministic_simulation.status = false; end else - oo_ = feval([M_.fname '.dynamic'], options_, M_, oo_); + oo_ = solve_block_decomposed_problem(options_, M_, oo_); end else if options_.bytecode diff --git a/matlab/perfect-foresight-models/solve_block_decomposed_problem.m b/matlab/perfect-foresight-models/solve_block_decomposed_problem.m new file mode 100644 index 000000000..10449129f --- /dev/null +++ b/matlab/perfect-foresight-models/solve_block_decomposed_problem.m @@ -0,0 +1,85 @@ +function oo_ = solve_block_decomposed_problem(options_, M_, oo_) +% Computes deterministic simulation with block option without bytecode + +% Copyright (C) 2020 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 . + +cutoff = 1e-15; + +if options_.stack_solve_algo==0 + mthd='Sparse LU'; +elseif options_.stack_solve_algo==1 + mthd='Relaxation'; +elseif options_.stack_solve_algo==2 + mthd='GMRES'; +elseif options_.stack_solve_algo==3 + mthd='BICGSTAB'; +elseif options_.stack_solve_algo==4 + mthd='OPTIMPATH'; +else + mthd='UNKNOWN'; +end +if options_.verbosity + printline(41) + disp(sprintf('MODEL SIMULATION (method=%s):',mthd)) + skipline() +end + +y=oo_.endo_simul'; +T=NaN(M_.block_structure.dyn_tmp_nbr, options_.periods+M_.maximum_lag+M_.maximum_lead); +oo_.deterministic_simulation.status = 0; + +for blk = 1:size(M_.block_structure.block, 1) + funcname = sprintf('%s.block.dynamic_%d', M_.fname, blk); + + recursive_size = M_.block_structure.block(blk).endo_nbr - M_.block_structure.block(blk).mfs; + y_index = M_.block_structure.block(blk).variable((recursive_size+1):end); + + if M_.block_structure.block(blk).Simulation_Type == 1 || ... % evaluateForward + M_.block_structure.block(blk).Simulation_Type == 2 % evaluateBackward + oo_.deterministic_simulation.status = true; + oo_.deterministic_simulation.error = 0; + oo_.deterministic_simulation.iterations = 0; + oo_.deterministic_simulation.block(blk).status = true; + oo_.deterministic_simulation.block(blk).error = 0; + oo_.deterministic_simulation.block(blk).iterations = 0; + [y, T] = feval(funcname, y, oo_.exo_simul, M_.params, oo_.steady_state, T, false, M_.maximum_lag, options_.periods); + elseif M_.block_structure.block(blk).Simulation_Type == 3 || ... % solveForwardSimple + M_.block_structure.block(blk).Simulation_Type == 4 || ... % solveBackwardSimple + M_.block_structure.block(blk).Simulation_Type == 6 || ... % solveForwardComplete + M_.block_structure.block(blk).Simulation_Type == 7 % solveBackwardComplete + [y, T, oo_] = solve_one_boundary(funcname, y, oo_.exo_simul, M_.params, oo_.steady_state, T, y_index, M_.block_structure.block(blk).NNZDerivatives, options_.periods, M_.block_structure.block(blk).is_linear, blk, M_.maximum_lag, options_.simul.maxit, options_.solve_tolf, options_.slowc, cutoff, options_.stack_solve_algo, true, true, false, M_, options_, oo_); + elseif M_.block_structure.block(blk).Simulation_Type == 5 || ... % solveTwoBoundariesSimple + M_.block_structure.block(blk).Simulation_Type == 8 % solveTwoBoundariesComplete + [y, T, oo_] = solve_two_boundaries(funcname, y, oo_.exo_simul, M_.params, oo_.steady_state, T, y_index, M_.block_structure.block(blk).NNZDerivatives, options_.periods, M_.block_structure.block(blk).maximum_lag, M_.block_structure.block(blk).maximum_lead, M_.block_structure.block(blk).is_linear, blk, M_.maximum_lag, options_.simul.maxit, options_.solve_tolf, options_.slowc, cutoff, options_.stack_solve_algo, options_, M_, oo_); + end + + tmp = y(:,M_.block_structure.block(blk).variable); + if any(isnan(tmp) | isinf(tmp)) + disp(['Inf or Nan value during the resolution of block ' num2str(blk)]); + oo_.deterministic_simulation.status = false; + oo_.deterministic_simulation.error = 100; + oo_.deterministic_simulation.block(blk).status = false; + oo_.deterministic_simulation.block(blk).error = 100; + end + if ~oo_.deterministic_simulation.status + return + end +end + +oo_.endo_simul = y'; + diff --git a/matlab/solve_one_boundary.m b/matlab/solve_one_boundary.m index b0cf6b5be..22358ee3c 100644 --- a/matlab/solve_one_boundary.m +++ b/matlab/solve_one_boundary.m @@ -1,5 +1,5 @@ -function [y, T, info] = solve_one_boundary(fname, y, x, params, steady_state, T, ... - y_index_eq, nze, periods, is_linear, Block_Num, y_kmin, maxit_, solve_tolf, lambda, cutoff, stack_solve_algo, is_forward, is_dynamic, verbose, M, options, oo) +function [y, T, oo_, info] = solve_one_boundary(fname, y, x, params, steady_state, T, ... + y_index_eq, nze, periods, is_linear, Block_Num, y_kmin, maxit_, solve_tolf, lambda, cutoff, stack_solve_algo, is_forward, is_dynamic, verbose, M, options, oo_) % Computes the deterministic simulation of a block of equation containing % lead or lag variables % @@ -168,10 +168,10 @@ for it_=start:incr:finish end end if is_dynamic - oo_.deterministic_simulation.status = 0; + oo_.deterministic_simulation.status = false; oo_.deterministic_simulation.error = max_res; oo_.deterministic_simulation.iterations = iter; - oo_.deterministic_simulation.block(Block_Num).status = 0;% Convergency failed. + oo_.deterministic_simulation.block(Block_Num).status = false;% Convergency failed. oo_.deterministic_simulation.block(Block_Num).error = max_res; oo_.deterministic_simulation.block(Block_Num).iterations = iter; end @@ -321,10 +321,10 @@ for it_=start:incr:finish end end if is_dynamic - oo_.deterministic_simulation.status = 0; + oo_.deterministic_simulation.status = false; oo_.deterministic_simulation.error = max_res; oo_.deterministic_simulation.iterations = iter; - oo_.deterministic_simulation.block(Block_Num).status = 0;% Convergency failed. + oo_.deterministic_simulation.block(Block_Num).status = false;% Convergency failed. oo_.deterministic_simulation.block(Block_Num).error = max_res; oo_.deterministic_simulation.block(Block_Num).iterations = iter; end @@ -335,10 +335,10 @@ end if is_dynamic info = 1; - oo_.deterministic_simulation.status = 1; + oo_.deterministic_simulation.status = true; oo_.deterministic_simulation.error = max_res; oo_.deterministic_simulation.iterations = iter; - oo_.deterministic_simulation.block(Block_Num).status = 1; + oo_.deterministic_simulation.block(Block_Num).status = true; oo_.deterministic_simulation.block(Block_Num).error = max_res; oo_.deterministic_simulation.block(Block_Num).iterations = iter; else diff --git a/matlab/solve_two_boundaries.m b/matlab/solve_two_boundaries.m index 9eda54694..04183d367 100644 --- a/matlab/solve_two_boundaries.m +++ b/matlab/solve_two_boundaries.m @@ -146,10 +146,10 @@ while ~(cvg==1 || iter>maxit_) fprintf('Error in simul: Convergence not achieved in block %d, after %d iterations.\n Increase "options_.simul.maxit" or set "cutoff=0" in model options.\n',Block_Num, iter); end end - oo.deterministic_simulation.status = 0; + oo.deterministic_simulation.status = false; oo.deterministic_simulation.error = max_res; oo.deterministic_simulation.iterations = iter; - oo.deterministic_simulation.block(Block_Num).status = 0;% Convergency failed. + oo.deterministic_simulation.block(Block_Num).status = false;% Convergency failed. oo.deterministic_simulation.block(Block_Num).error = max_res; oo.deterministic_simulation.block(Block_Num).iterations = iter; return @@ -324,18 +324,18 @@ if (iter>maxit_) printline(41) %disp(['No convergence after ' num2str(iter,'%4d') ' iterations in Block ' num2str(Block_Num,'%d')]) end - oo.deterministic_simulation.status = 0; + oo.deterministic_simulation.status = false; oo.deterministic_simulation.error = max_res; oo.deterministic_simulation.iterations = iter; - oo.deterministic_simulation.block(Block_Num).status = 0;% Convergency failed. + oo.deterministic_simulation.block(Block_Num).status = false;% Convergency failed. oo.deterministic_simulation.block(Block_Num).error = max_res; oo.deterministic_simulation.block(Block_Num).iterations = iter; return end -oo.deterministic_simulation.status = 1; +oo.deterministic_simulation.status = true; oo.deterministic_simulation.error = max_res; oo.deterministic_simulation.iterations = iter; -oo.deterministic_simulation.block(Block_Num).status = 1;% Convergency obtained. +oo.deterministic_simulation.block(Block_Num).status = true;% Convergency obtained. oo.deterministic_simulation.block(Block_Num).error = max_res; oo.deterministic_simulation.block(Block_Num).iterations = iter; diff --git a/preprocessor b/preprocessor index 3c5d73150..f0c8a1455 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit 3c5d731500b56384946205864924ea3165a27eb7 +Subproject commit f0c8a145518cb86953a44fca4ba2b0ff7c88cf0a