1function [dr, info, M, options, oo] = resol(check_flag, M, options, oo)
2
3% Computes the perturbation based decision rules of the DSGE model (orders 1 to 3)
4%
5% INPUTS
6% - check_flag    [integer]       scalar, equal to 0 if all the approximation is required, equal to 1 if only the eigenvalues are to be computed.
7% - M             [structure]     Matlab's structure describing the model (M_).
8% - options       [structure]     Matlab's structure describing the current options (options_).
9% - oo            [structure]     Matlab's structure containing the results (oo_).
10%
11% OUTPUTS
12% - dr            [structure]     Reduced form model.
13% - info          [integer]       scalar or vector, error code.
14% - M             [structure]     Matlab's structure describing the model (M_).
15% - options       [structure]     Matlab's structure describing the current options (options_).
16% - oo            [structure]     Matlab's structure containing the results (oo_).
17%
18% REMARKS
19% Possible values for the error codes are:
20%
21%   info(1)=0     ->    No error.
22%   info(1)=1     ->    The model doesn't determine the current variables uniquely.
23%   info(1)=2     ->    MJDGGES returned an error code.
24%   info(1)=3     ->    Blanchard & Kahn conditions are not satisfied: no stable equilibrium.
25%   info(1)=4     ->    Blanchard & Kahn conditions are not satisfied: indeterminacy.
26%   info(1)=5     ->    Blanchard & Kahn conditions are not satisfied: indeterminacy due to rank failure.
27%   info(1)=6     ->    The jacobian evaluated at the deterministic steady state is complex.
28%   info(1)=19    ->    The steadystate routine has thrown an exception (inconsistent deep parameters).
29%   info(1)=20    ->    Cannot find the steady state, info(2) contains the sum of square residuals (of the static equations).
30%   info(1)=21    ->    The steady state is complex, info(2) contains the sum of square of imaginary parts of the steady state.
31%   info(1)=22    ->    The steady has NaNs.
32%   info(1)=23    ->    M_.params has been updated in the steadystate routine and has complex valued scalars.
33%   info(1)=24    ->    M_.params has been updated in the steadystate routine and has some NaNs.
34%   info(1)=30    ->    Ergodic variance can't be computed.
35
36% Copyright (C) 2001-2018 Dynare Team
37%
38% This file is part of Dynare.
39%
40% Dynare is free software: you can redistribute it and/or modify
41% it under the terms of the GNU General Public License as published by
42% the Free Software Foundation, either version 3 of the License, or
43% (at your option) any later version.
44%
45% Dynare is distributed in the hope that it will be useful,
46% but WITHOUT ANY WARRANTY; without even the implied warranty of
47% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48% GNU General Public License for more details.
49%
50% You should have received a copy of the GNU General Public License
51% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
52
53if isfield(oo,'dr')
54    if isfield(oo.dr,'kstate')
55        dr.kstate = oo.dr.kstate;
56    end
57    if isfield(oo.dr,'inv_order_var')
58        dr.inv_order_var = oo.dr.inv_order_var;
59    end
60    if isfield(oo.dr,'order_var')
61        dr.order_var = oo.dr.order_var;
62    end
63    if isfield(oo.dr,'restrict_var_list')
64        dr.restrict_var_list = oo.dr.restrict_var_list;
65    end
66    if isfield(oo.dr,'restrict_columns')
67        dr.restrict_columns = oo.dr.restrict_columns;
68    end
69    if isfield(oo.dr,'obs_var')
70        dr.obs_var = oo.dr.obs_var;
71    end
72end
73
74if M.exo_nbr == 0
75    oo.exo_steady_state = [] ;
76end
77
78[dr.ys,M.params,info] = evaluate_steady_state(oo.steady_state,M,options,oo,~options.steadystate.nocheck);
79
80if info(1)
81    oo.dr = dr;
82    return
83end
84
85if options.loglinear
86    threshold = 1e-16;
87    % Find variables with non positive steady state. Skip auxiliary
88    % variables for lagges/leaded exogenous variables
89    idx = find(dr.ys(get_all_variables_but_lagged_leaded_exogenous(M))<threshold);
90    if length(idx)
91        if options.debug
92            variables_with_non_positive_steady_state = M.endo_names{idx};
93            skipline()
94            fprintf('You are attempting to simulate/estimate a loglinear approximation of a model, but\n')
95            fprintf('the steady state level of the following variables is not strictly positive:\n')
96            for var_iter=1:length(idx)
97                fprintf(' - %s (%s)\n',deblank(variables_with_non_positive_steady_state(var_iter,:)), num2str(dr.ys(idx(var_iter))))
98            end
99            if isinestimationobjective()
100                fprintf('You should check that the priors and/or bounds over the deep parameters are such\n')
101                fprintf('that the steady state levels of all the variables are strictly positive, or consider\n')
102                fprintf('a linearization of the model instead of a log linearization.\n')
103            else
104                fprintf('You should check that the calibration of the deep parameters is such that the\n')
105                fprintf('steady state levels of all the variables are strictly positive, or consider\n')
106                fprintf('a linearization of the model instead of a log linearization.\n')
107            end
108        end
109        info(1)=26;
110        info(2)=sum(dr.ys(dr.ys<threshold).^2);
111        return
112    end
113end
114
115if options.block
116    [dr,info,M,options,oo] = dr_block(dr,check_flag,M,options,oo);
117    dr.edim = nnz(abs(dr.eigval) > options.qz_criterium);
118    dr.sdim = dr.nd-dr.edim;
119else
120    [dr,info] = stochastic_solvers(dr,check_flag,M,options,oo);
121end
122oo.dr = dr;
123