2021-08-15 21:00:29 +02:00
function [oo_, options_mom_, M_] = run ( bayestopt_, options_, oo_, estim_params_, M_, options_mom_)
%function [oo_, options_mom_, M_] = run(bayestopt_, options_, oo_, estim_params_, M_, options_mom_)
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% This function performs a method of moments estimation with the following steps:
% Step 0: Check if required structures and options exist
% Step 1: - Prepare options_mom_ structure
2020-07-10 21:42:18 +02:00
% - Carry over options from the preprocessor
% - Initialize other options
2020-06-29 07:40:34 +02:00
% - Get variable orderings and state space representation
2020-07-10 21:42:18 +02:00
% Step 2: Checks and transformations for matched moments structure
2020-06-29 07:40:34 +02:00
% Step 3: Checks and transformations for estimated parameters, priors, and bounds
% Step 4: Checks and transformations for data
2020-07-10 21:42:18 +02:00
% Step 5: Checks for steady state at initial parameters
% Step 6: Checks for objective function at initial parameters
% Step 7: Iterated method of moments estimation
% Step 8: J-Test
% Step 9: Clean up
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% This function is inspired by replication codes accompanied to the following papers:
% o Andreasen, Fernández-Villaverde, Rubio-Ramírez (2018): "The Pruned State-Space System for Non-Linear DSGE Models: Theory and Empirical Applications", Review of Economic Studies, 85(1):1-49.
% o Born, Pfeifer (2014): "Risk Matters: Comment", American Economic Review, 104(12):4231-4239.
% o Mutschler (2018): "Higher-order statistics for DSGE models", Econometrics and Statistics, 6:44-56.
% =========================================================================
% INPUTS
% o bayestopt_: [structure] information about priors
% o options_: [structure] information about global options
% o oo_: [structure] storage for results
% o estim_params_: [structure] information about estimated parameters
2020-08-05 15:30:58 +02:00
% o M_: [structure] information about model with
% o matched_moments: [cell] information about selected moments to match in estimation
% vars: matched_moments{:,1});
% lead/lags: matched_moments{:,2};
% powers: matched_moments{:,3};
2020-06-29 07:40:34 +02:00
% o options_mom_: [structure] information about settings specified by the user
% -------------------------------------------------------------------------
% OUTPUTS
% o oo_: [structure] storage for results (oo_)
2020-07-10 21:42:18 +02:00
% o options_mom_: [structure] information about all (user-specified and updated) settings used in estimation (options_mom_)
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% This function is called by
% o driver.m
% -------------------------------------------------------------------------
% This function calls
% o check_for_calibrated_covariances.m
% o check_prior_bounds.m
% o do_parameter_initialization.m
% o dynare_minimize_objective.m
% o evaluate_steady_state
% o get_all_parameters.m
2020-07-10 21:42:18 +02:00
% o get_matrix_entries_for_psd_check.m
2020-06-29 07:40:34 +02:00
% o makedataset.m
2021-08-15 21:00:29 +02:00
% o mom.check_plot.m
% o mom.data_moments.m
% o mom.objective_function.m
% o mom.optimal_weighting_matrix
% o mom-standard_errors
2020-06-29 07:40:34 +02:00
% o plot_priors.m
% o print_info.m
% o prior_bounds.m
% o set_default_option.m
% o set_prior.m
% o set_state_space.m
% o set_all_parameters.m
% o test_for_deep_parameters_calibration.m
% =========================================================================
2022-04-15 14:32:54 +02:00
% Copyright © 2020-2022 Dynare Team
2020-06-29 07:40:34 +02:00
%
% 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
2021-06-09 17:33:48 +02:00
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% Author(s):
% o Willi Mutschler (willi@mutschler.eu)
% o Johannes Pfeifer (jpfeifer@uni-koeln.de)
% =========================================================================
%% TO DO LIST
% - [ ] add IRF matching
2020-12-16 11:18:53 +01:00
% - [ ] speed up pruned_state_space_system (by using doubling with old initial values, hardcoding zeros, other "tricks" used in e.g. nlma)
% - [ ] add option to use autocorrelations (we have useautocorr in identification toolbox already)
% - [ ] SMM with extended path
% - [ ] deal with measurement errors (once @wmutschl has implemented this in identification toolbox)
2021-01-07 10:33:09 +01:00
% - [ ] dirname option to save output to different directory not yet implemented
2021-08-11 17:31:24 +02:00
% - [ ] display scaled moments
2021-01-19 14:52:27 +01:00
% The TeX option crashes MATLAB R2014a run with "-nodisplay" option
% (as is done from the testsuite).
% Since we can’ t directly test whether "-nodisplay" has been passed,
% we test for the "TOP_TEST_DIR" environment variable, which is set
% by the testsuite.
% Note that it was not tested whether the crash happens with more
% recent MATLAB versions, so when OLD_MATLAB_VERSION is increased,
% one should make a test before removing this workaround.
if options_ . TeX && ~ isoctave && matlab_ver_less_than ( ' 8.4' ) && ~ isempty ( getenv ( ' TOP_TEST_DIR' ) )
warning ( ' Disabling TeX option due to a bug in MATLAB R2014a with -nodisplay' )
options_ . TeX = false ;
end
if isfield ( options_mom_ , ' TeX' ) && options_mom_ . TeX && ~ isoctave && matlab_ver_less_than ( ' 8.4' ) && ~ isempty ( getenv ( ' TOP_TEST_DIR' ) )
warning ( ' Disabling TeX option due to a bug in MATLAB R2014a with -nodisplay' )
options_mom_ . TeX = false ;
end
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% Step 0: Check if required structures and options exist
% -------------------------------------------------------------------------
if isempty ( estim_params_ ) % structure storing the info about estimated parameters in the estimated_params block
if ~ ( isfield ( estim_params_ , ' nvx' ) && ( size ( estim_params_ . var_exo , 1 ) + size ( estim_params_ . var_endo , 1 ) + size ( estim_params_ . corrx , 1 ) + size ( estim_params_ . corrn , 1 ) + size ( estim_params_ . param_vals , 1 ) ) == 0 )
error ( ' method_of_moments: You need to provide an ' ' estimated_params' ' block' )
else
error ( ' method_of_moments: The ' ' estimated_params' ' block must not be empty' )
end
end
2022-01-25 16:26:12 +01:00
if ~ isfield ( M_ , ' matched_moments' ) || isempty ( M_ . matched_moments ) % structure storing the moments used for the method of moments estimation
2020-06-29 07:40:34 +02:00
error ( ' method_of_moments: You need to provide a ' ' matched_moments' ' block' )
end
if ~ isempty ( bayestopt_ ) && any ( bayestopt_ . pshape == 0 ) && any ( bayestopt_ . pshape ~= 0 )
error ( ' method_of_moments: Estimation must be either fully classical or fully Bayesian. Maybe you forgot to specify a prior distribution.' )
end
if options_ . logged_steady_state || options_ . loglinear
error ( ' method_of_moments: The loglinear option is not supported. Please append the required logged variables as auxiliary equations.\n' )
2020-07-10 21:23:07 +02:00
else
options_mom_ . logged_steady_state = 0 ;
options_mom_ . loglinear = false ;
2020-06-29 07:40:34 +02:00
end
2020-12-18 14:37:45 +01:00
fprintf ( ' \n==== Method of Moments Estimation (%s) ====\n\n' , options_mom_ . mom . mom_method )
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% Step 1a: Prepare options_mom_ structure
% -------------------------------------------------------------------------
% options_mom_ is local and contains default and user-specified values for
% all settings needed for the method of moments estimation. Some options,
% though, are set by the preprocessor into options_ and we copy these over.
% The idea is to be independent of options_ and have full control of the
% estimation instead of possibly having to deal with options chosen somewhere
% else in the mod file.
% Method of Moments estimation options that can be set by the user in the mod file, otherwise default values are provided
if strcmp ( options_mom_ . mom . mom_method , ' GMM' ) || strcmp ( options_mom_ . mom . mom_method , ' SMM' )
2020-07-10 21:42:18 +02:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' bartlett_kernel_lag' , 20 ) ; % bandwith in optimal weighting matrix
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' penalized_estimator' , false ) ; % include deviation from prior mean as additional moment restriction and use prior precision as weight
2020-06-29 07:40:34 +02:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' verbose' , false ) ; % display and store intermediate estimation results
2021-08-11 17:31:24 +02:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' weighting_matrix' , { ' DIAGONAL' ; ' OPTIMAL' } ) ; % weighting matrix in moments distance objective function at each iteration of estimation;
2020-07-10 21:42:18 +02:00
% possible values are 'OPTIMAL', 'IDENTITY_MATRIX' ,'DIAGONAL' or a filename. Size of cell determines stages in iterated estimation.
2021-01-07 10:33:09 +01:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' weighting_matrix_scaling_factor' , 1 ) ; % scaling of weighting matrix in objective function
2020-07-10 21:42:18 +02:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' se_tolx' , 1e-5 ) ; % step size for numerical computation of standard errors
options_mom_ = set_default_option ( options_mom_ , ' order' , 1 ) ; % order of Taylor approximation in perturbation
2020-12-16 10:59:49 +01:00
options_mom_ = set_default_option ( options_mom_ , ' pruning' , false ) ; % use pruned state space system at higher-order
2020-06-29 07:40:34 +02:00
% Checks for perturbation order
if options_mom_ . order < 1
2020-12-16 10:59:49 +01:00
error ( ' method_of_moments: The order of the Taylor approximation cannot be 0!' )
2020-06-29 07:40:34 +02:00
end
end
if strcmp ( options_mom_ . mom . mom_method , ' SMM' )
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' burnin' , 500 ) ; % number of periods dropped at beginning of simulation
2020-07-10 21:42:18 +02:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' bounded_shock_support' , false ) ; % trim shocks in simulation to +- 2 stdev
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' seed' , 24051986 ) ; % seed used in simulations
2021-08-11 17:31:24 +02:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' simulation_multiple' , 7 ) ; % multiple of the data length used for simulation
2020-06-29 07:40:34 +02:00
if options_mom_ . mom . simulation_multiple < 1
2020-07-10 21:42:18 +02:00
fprintf ( ' The simulation horizon is shorter than the data. Dynare resets the simulation_multiple to 5.\n' )
2021-08-11 17:31:24 +02:00
options_mom_ . mom . simulation_multiple = 7 ;
2020-06-29 07:40:34 +02:00
end
end
if strcmp ( options_mom_ . mom . mom_method , ' GMM' )
% Check for pruning with GMM at higher order
if options_mom_ . order > 1 && ~ options_mom_ . pruning
fprintf ( ' GMM at higher order only works with pruning, so we set pruning option to 1.\n' ) ;
options_mom_ . pruning = true ;
end
2020-12-16 10:59:49 +01:00
if options_mom_ . order > 3
error ( ' method_of_moments: perturbation orders higher than 3 are not implemented for GMM estimation, try using SMM.\n' ) ;
end
2020-06-29 07:40:34 +02:00
end
2021-01-22 20:09:32 +01:00
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' analytic_standard_errors' , false ) ; % compute standard errors numerically (0) or analytically (1). Analytical derivatives are only available for GMM.
options_mom_ . mom = set_default_option ( options_mom_ . mom , ' analytic_jacobian' , false ) ; % use analytic Jacobian in optimization, only available for GMM and gradient-based optimizers
2021-01-14 10:03:39 +01:00
% initialize flag to compute derivs in objective function (needed for GMM with either analytic_standard_errors or analytic_jacobian )
options_mom_ . mom . compute_derivs = false ;
2020-06-29 07:40:34 +02:00
% General options that can be set by the user in the mod file, otherwise default values are provided
2021-01-07 10:33:09 +01:00
options_mom_ = set_default_option ( options_mom_ , ' dirname' , M_ . dname ) ; % specify directory in which to store estimation output [not yet working]
2020-06-29 07:40:34 +02:00
options_mom_ = set_default_option ( options_mom_ , ' graph_format' , ' eps' ) ; % specify the file format(s) for graphs saved to disk
options_mom_ = set_default_option ( options_mom_ , ' nodisplay' , false ) ; % do not display the graphs, but still save them to disk
options_mom_ = set_default_option ( options_mom_ , ' nograph' , false ) ; % do not create graphs (which implies that they are not saved to the disk nor displayed)
options_mom_ = set_default_option ( options_mom_ , ' noprint' , false ) ; % do not print output to console
options_mom_ = set_default_option ( options_mom_ , ' plot_priors' , true ) ; % control plotting of priors
options_mom_ = set_default_option ( options_mom_ , ' prior_trunc' , 1e-10 ) ; % probability of extreme values of the prior density that is ignored when computing bounds for the parameters
options_mom_ = set_default_option ( options_mom_ , ' TeX' , false ) ; % print TeX tables and graphics
2022-02-18 00:48:39 +01:00
options_mom_ = set_default_option ( options_mom_ , ' verbosity' , false ) ; % print TeX tables and graphics
2020-06-29 07:40:34 +02:00
% Data and model options that can be set by the user in the mod file, otherwise default values are provided
options_mom_ = set_default_option ( options_mom_ , ' first_obs' , 1 ) ; % number of first observation
2020-07-10 21:23:07 +02:00
options_mom_ = set_default_option ( options_mom_ , ' logdata' , false ) ; % if data is already in logs
2020-06-29 07:40:34 +02:00
options_mom_ = set_default_option ( options_mom_ , ' nobs' , NaN ) ; % number of observations
options_mom_ = set_default_option ( options_mom_ , ' prefilter' , false ) ; % demean each data series by its empirical mean and use centered moments
options_mom_ = set_default_option ( options_mom_ , ' xls_sheet' , 1 ) ; % name of sheet with data in Excel
options_mom_ = set_default_option ( options_mom_ , ' xls_range' , ' ' ) ; % range of data in Excel sheet
2022-03-30 08:51:52 +02:00
% temporary workaround for https://git.dynare.org/Dynare/dseries/-/issues/51
if options_mom_ . xls_sheet ~= 1
evalin ( ' base' , ' options_.xls_sheet=options_mom_.xls_sheet' ) ;
end
if ~ isempty ( options_mom_ . xls_range )
evalin ( ' base' , ' options_.xls_range=options_mom_.xls_range' ) ;
end
2020-06-29 07:40:34 +02:00
% Recursive estimation and forecast are not supported
if numel ( options_mom_ . nobs ) > 1
error ( ' method_of_moments: Recursive estimation and forecast for samples is not supported. Please set an integer as ' ' nobs' ' .' ) ;
end
if numel ( options_mom_ . first_obs ) > 1
error ( ' method_of_moments: Recursive estimation and forecast for samples is not supported. Please set an integer as ' ' first_obs' ' .' ) ;
end
% Optimization options that can be set by the user in the mod file, otherwise default values are provided
2020-07-10 21:23:07 +02:00
options_mom_ = set_default_option ( options_mom_ , ' huge_number' , 1e7 ) ; % value for replacing the infinite bounds on parameters by finite numbers. Used by some optimizers for numerical reasons
2021-08-12 06:19:27 +02:00
if ( isoctave && user_has_octave_forge_package ( ' optim' ) ) || ( ~ isoctave && user_has_matlab_license ( ' optimization_toolbox' ) )
options_mom_ = set_default_option ( options_mom_ , ' mode_compute' , 13 ) ; % specifies lsqnonlin as default optimizer for minimization of moments distance
else
options_mom_ = set_default_option ( options_mom_ , ' mode_compute' , 4 ) ; % specifies csminwel as fallback default option for minimization of moments distance
end
2020-07-10 21:23:07 +02:00
options_mom_ = set_default_option ( options_mom_ , ' additional_optimizer_steps' , [ ] ) ; % vector of additional mode-finders run after mode_compute
options_mom_ = set_default_option ( options_mom_ , ' optim_opt' , [ ] ) ; % a list of NAME and VALUE pairs to set options for the optimization routines. Available options depend on mode_compute
options_mom_ = set_default_option ( options_mom_ , ' silent_optimizer' , false ) ; % run minimization of moments distance silently without displaying results or saving files in between
2020-11-26 13:28:29 +01:00
% Check plot options that can be set by the user in the mod file, otherwise default values are provided
2020-07-10 21:23:07 +02:00
options_mom_ . mode_check . nolik = false ; % we don't do likelihood (also this initializes mode_check substructure)
2021-01-07 10:33:09 +01:00
options_mom_ . mode_check = set_default_option ( options_mom_ . mode_check , ' status' , false ) ; % plot the target function for values around the computed minimum for each estimated parameter in turn. This is helpful to diagnose problems with the optimizer.
2020-11-26 13:28:29 +01:00
options_mom_ . mode_check = set_default_option ( options_mom_ . mode_check , ' neighbourhood_size' , . 5 ) ; % width of the window around the computed minimum to be displayed on the diagnostic plots. This width is expressed in percentage deviation. The Inf value is allowed, and will trigger a plot over the entire domain
options_mom_ . mode_check = set_default_option ( options_mom_ . mode_check , ' symmetric_plots' , true ) ; % ensure that the check plots are symmetric around the minimum. A value of 0 allows to have asymmetric plots, which can be useful if the minimum is close to a domain boundary, or in conjunction with neighbourhood_size = Inf when the domain is not the entire real line
options_mom_ . mode_check = set_default_option ( options_mom_ . mode_check , ' number_of_points' , 20 ) ; % number of points around the minimum where the target function is evaluated (for each parameter)
2020-06-29 07:40:34 +02:00
% Numerical algorithms options that can be set by the user in the mod file, otherwise default values are provided
2020-07-10 21:42:18 +02:00
options_mom_ = set_default_option ( options_mom_ , ' aim_solver' , false ) ; % use AIM algorithm to compute perturbation approximation instead of mjdgges
2020-07-10 21:23:07 +02:00
options_mom_ = set_default_option ( options_mom_ , ' k_order_solver' , false ) ; % use k_order_perturbation instead of mjdgges
2020-06-29 07:40:34 +02:00
options_mom_ = set_default_option ( options_mom_ , ' dr_cycle_reduction' , false ) ; % use cycle reduction algorithm to solve the polynomial equation for retrieving the coefficients associated to the endogenous variables in the decision rule
options_mom_ = set_default_option ( options_mom_ , ' dr_cycle_reduction_tol' , 1e-7 ) ; % convergence criterion used in the cycle reduction algorithm
options_mom_ = set_default_option ( options_mom_ , ' dr_logarithmic_reduction' , false ) ; % use logarithmic reduction algorithm to solve the polynomial equation for retrieving the coefficients associated to the endogenous variables in the decision rule
options_mom_ = set_default_option ( options_mom_ , ' dr_logarithmic_reduction_maxiter' , 100 ) ; % maximum number of iterations used in the logarithmic reduction algorithm
options_mom_ = set_default_option ( options_mom_ , ' dr_logarithmic_reduction_tol' , 1e-12 ) ; % convergence criterion used in the cycle reduction algorithm
options_mom_ = set_default_option ( options_mom_ , ' lyapunov_db' , false ) ; % doubling algorithm (disclyap_fast) to solve Lyapunov equation to compute variance-covariance matrix of state variables
options_mom_ = set_default_option ( options_mom_ , ' lyapunov_fp' , false ) ; % fixed-point algorithm to solve Lyapunov equation to compute variance-covariance matrix of state variables
options_mom_ = set_default_option ( options_mom_ , ' lyapunov_srs' , false ) ; % square-root-solver (dlyapchol) algorithm to solve Lyapunov equation to compute variance-covariance matrix of state variables
options_mom_ = set_default_option ( options_mom_ , ' lyapunov_complex_threshold' , 1e-15 ) ; % complex block threshold for the upper triangular matrix in symmetric Lyapunov equation solver
options_mom_ = set_default_option ( options_mom_ , ' lyapunov_fixed_point_tol' , 1e-10 ) ; % convergence criterion used in the fixed point Lyapunov solver
options_mom_ = set_default_option ( options_mom_ , ' lyapunov_doubling_tol' , 1e-16 ) ; % convergence criterion used in the doubling algorithm
options_mom_ = set_default_option ( options_mom_ , ' sylvester_fp' , false ) ; % determines whether to use fixed point algorihtm to solve Sylvester equation (gensylv_fp), faster for large scale models
options_mom_ = set_default_option ( options_mom_ , ' sylvester_fixed_point_tol' , 1e-12 ) ; % convergence criterion used in the fixed point Sylvester solver
2020-12-16 11:33:01 +01:00
options_mom_ = set_default_option ( options_mom_ , ' qz_criterium' , 1 - 1e-6 ) ; % value used to split stable from unstable eigenvalues in reordering the Generalized Schur decomposition used for solving first order problems
2020-12-18 14:37:45 +01:00
% if there are no unit roots one can use 1.0 (or slightly below) which we set as default; if they are possible, you may have have multiple unit roots and the accuracy decreases when computing the eigenvalues in lyapunov_symm
2020-12-16 11:33:01 +01:00
% Note that unit roots are only possible at first-order, at higher order we set it to 1 in pruned_state_space_system and focus only on stationary observables.
2020-06-29 07:40:34 +02:00
options_mom_ = set_default_option ( options_mom_ , ' qz_zero_threshold' , 1e-6 ) ; % value used to test if a generalized eigenvalue is 0/0 in the generalized Schur decomposition
2020-12-18 14:37:45 +01:00
options_mom_ = set_default_option ( options_mom_ , ' schur_vec_tol' , 1e-11 ) ; % tolerance level used to find nonstationary variables in Schur decomposition of the transition matrix.
2022-02-18 00:50:08 +01:00
options_mom_ = set_default_option ( options_mom_ , ' trust_region_initial_step_bound_factor' , 1 ) ; % used in dynare_solve for trust_region
2020-07-10 21:23:07 +02:00
if options_mom_ . order > 2
fprintf ( ' Dynare will use ' ' k_order_solver' ' as the order>2\n' ) ;
options_mom_ . k_order_solver = true ;
end
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
2020-07-10 21:42:18 +02:00
% Step 1b: Options that are set by the preprocessor and need to be carried over
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% options related to VAROBS
if ~ isfield ( options_ , ' varobs' )
error ( ' method_of_moments: VAROBS statement is missing!' )
else
2020-07-10 21:42:18 +02:00
options_mom_ . varobs = options_ . varobs ; % observable variables in declaration order
options_mom_ . obs_nbr = length ( options_mom_ . varobs ) ; % number of observed variables
2020-06-29 07:40:34 +02:00
% Check that each declared observed variable is also an endogenous variable
for i = 1 : options_mom_ . obs_nbr
if ~ any ( strcmp ( options_mom_ . varobs { i } , M_ . endo_names ) )
error ( [ ' method_of_moments: Unknown variable (' options_mom_ . varobs { i } ' )!' ] )
end
end
2020-07-10 21:42:18 +02:00
% Check that a variable is not declared as observed more than once
2020-06-29 07:40:34 +02:00
if length ( unique ( options_mom_ . varobs ) ) < length ( options_mom_ . varobs )
for i = 1 : options_mom_ . obs_nbr
if sum ( strcmp ( options_mom_ . varobs { i } , options_mom_ . varobs ) ) > 1
error ( [ ' method_of_moments: A variable cannot be declared as observed more than once (' options_mom_ . varobs { i } ' )!' ] )
end
end
end
end
% options related to variable declarations
if isfield ( options_ , ' trend_coeffs' )
error ( ' method_of_moments: %s does not allow for trend in data' , options_mom_ . mom . mom_method )
end
% options related to estimated_params and estimated_params_init
options_mom_ . use_calibration_initialization = options_ . use_calibration_initialization ;
2020-07-10 21:42:18 +02:00
% options related to model block
2020-06-29 07:40:34 +02:00
options_mom_ . linear = options_ . linear ;
options_mom_ . use_dll = options_ . use_dll ;
options_mom_ . block = options_ . block ;
options_mom_ . bytecode = options_ . bytecode ;
2020-07-10 21:42:18 +02:00
% options related to steady command
2020-06-29 07:40:34 +02:00
options_mom_ . homotopy_force_continue = options_ . homotopy_force_continue ;
options_mom_ . homotopy_mode = options_ . homotopy_mode ;
options_mom_ . homotopy_steps = options_ . homotopy_steps ;
options_mom_ . markowitz = options_ . markowitz ;
options_mom_ . solve_algo = options_ . solve_algo ;
options_mom_ . solve_tolf = options_ . solve_tolf ;
2020-07-10 21:23:07 +02:00
options_mom_ . solve_tolx = options_ . solve_tolx ;
2020-06-29 07:40:34 +02:00
options_mom_ . steady = options_ . steady ;
options_mom_ . steadystate = options_ . steadystate ;
options_mom_ . steadystate_flag = options_ . steadystate_flag ;
% options related to dataset
options_mom_ . dataset = options_ . dataset ;
options_mom_ . initial_period = options_ . initial_period ;
2020-07-10 21:42:18 +02:00
% options related to endogenous prior restrictions are not supported
2020-06-29 07:40:34 +02:00
options_mom_ . endogenous_prior_restrictions . irf = { } ;
options_mom_ . endogenous_prior_restrictions . moment = { } ;
if ~ isempty ( options_ . endogenous_prior_restrictions . irf ) && ~ isempty ( options_ . endogenous_prior_restrictions . moment )
fprintf ( ' Endogenous prior restrictions are not supported yet and will be skipped.\n' )
end
% -------------------------------------------------------------------------
% Step 1c: Options related to optimizers
% -------------------------------------------------------------------------
% mode_compute = 1, 3, 7, 11, 102, 11, 13
% nothing to be done
% mode_compute = 2
options_mom_ . saopt = options_ . saopt ;
% mode_compute = 4
options_mom_ . csminwel = options_ . csminwel ;
% mode_compute = 5
options_mom_ . newrat = options_ . newrat ;
options_mom_ . gstep = options_ . gstep ;
% mode_compute = 6
options_mom_ . gmhmaxlik = options_ . gmhmaxlik ;
options_mom_ . mh_jscale = options_ . mh_jscale ;
% mode_compute = 8
options_mom_ . simplex = options_ . simplex ;
% mode_compute = 9
options_mom_ . cmaes = options_ . cmaes ;
% mode_compute = 10
options_mom_ . simpsa = options_ . simpsa ;
% mode_compute = 12
options_mom_ . particleswarm = options_ . particleswarm ;
% mode_compute = 101
options_mom_ . solveopt = options_ . solveopt ;
options_mom_ . gradient_method = options_ . gradient_method ;
options_mom_ . gradient_epsilon = options_ . gradient_epsilon ;
2020-07-10 21:23:07 +02:00
options_mom_ . analytic_derivation = 0 ;
2020-12-16 12:03:21 +01:00
options_mom_ . analytic_derivation_mode = 0 ; % needed by get_perturbation_params_derivs.m, ie use efficient sylvester equation method to compute analytical derivatives as in Ratto & Iskrev (2012)
2020-07-10 21:23:07 +02:00
options_mom_ . vector_output = false ; % specifies whether the objective function returns a vector
2020-06-29 07:40:34 +02:00
2021-01-14 10:03:39 +01:00
optimizer_vec = [ options_mom_ . mode_compute ; num2cell ( options_mom_ . additional_optimizer_steps ) ] ; % at each stage one can possibly use different optimizers sequentially
2021-01-22 19:53:57 +01:00
analytic_jacobian_optimizers = [ 1 , 3 , 4 , 13 , 101 ] ; %these are currently supported, see to-do list
2021-01-14 10:03:39 +01:00
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% Step 1d: Other options that need to be initialized
% -------------------------------------------------------------------------
options_mom_ . initialize_estimated_parameters_with_the_prior_mode = 0 ; % needed by set_prior.m
options_mom_ . figures . textwidth = 0.8 ; %needed by plot_priors.m
options_mom_ . ramsey_policy = 0 ; % needed by evaluate_steady_state
2022-03-24 12:55:31 +01:00
options_mom_ = set_default_option ( options_mom_ , ' debug' , false ) ; %neeeded by e.g. check_plot
2020-06-29 07:40:34 +02:00
options_mom_ . risky_steadystate = false ; %needed by resol
options_mom_ . threads = options_ . threads ; %needed by resol
options_mom_ . jacobian_flag = true ;
options_mom_ . gstep = options_ . gstep ;
% options_mom.dsge_var = false; %needed by check_list_of_variables
% options_mom.bayesian_irf = false; %needed by check_list_of_variables
% options_mom.moments_varendo = false; %needed by check_list_of_variables
% options_mom.smoother = false; %needed by check_list_of_variables
% options_mom.filter_step_ahead = []; %needed by check_list_of_variables
% options_mom.forecast = 0;
%options_mom_ = set_default_option(options_mom_,'endo_vars_for_moment_computations_in_estimation',[]);
% -------------------------------------------------------------------------
% Step 1e: Get variable orderings and state space representation
% -------------------------------------------------------------------------
oo_ . dr = set_state_space ( oo_ . dr , M_ , options_mom_ ) ;
% Get index of observed variables in DR order
oo_ . dr . obs_var = [ ] ;
for i = 1 : options_mom_ . obs_nbr
oo_ . dr . obs_var = [ oo_ . dr . obs_var ; find ( strcmp ( options_mom_ . varobs { i } , M_ . endo_names ( oo_ . dr . order_var ) ) ) ] ;
end
% -------------------------------------------------------------------------
2021-08-11 07:30:31 +02:00
% Step 2: Checks and transformations for matched_moments structure
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
2021-08-11 07:30:31 +02:00
M_ . matched_moments_orig = M_ . matched_moments ; %save original structure
2020-06-29 07:40:34 +02:00
2021-08-11 07:30:31 +02:00
% higher-order product moments not supported yet for GMM
if strcmp ( options_mom_ . mom . mom_method , ' GMM' ) && any ( cellfun ( @ sum , M_ . matched_moments ( : , 3 ) ) > 2 )
error ( ' method_of_moments: GMM does not yet support product moments higher than 2. Change row %d in ' ' matched_moments' ' block.' , jm ) ;
end
2020-06-29 07:40:34 +02:00
2021-08-11 07:30:31 +02:00
% check for duplicate moment conditions
2020-08-05 15:30:58 +02:00
for jm = 1 : size ( M_ . matched_moments , 1 )
2021-08-11 07:30:31 +02:00
% expand powers to vector of ones
if any ( M_ . matched_moments { jm , 3 } > 1 )
tmp1 = [ ] ; tmp2 = [ ] ; tmp3 = [ ] ;
for jjm = 1 : length ( M_ . matched_moments { jm , 3 } )
tmp1 = [ tmp1 repmat ( M_ . matched_moments { jm , 1 } ( jjm ) , [ 1 M_ . matched_moments { jm , 3 } ( jjm ) ] ) ] ;
tmp2 = [ tmp2 repmat ( M_ . matched_moments { jm , 2 } ( jjm ) , [ 1 M_ . matched_moments { jm , 3 } ( jjm ) ] ) ] ;
tmp3 = [ tmp3 repmat ( 1 , [ 1 M_ . matched_moments { jm , 3 } ( jjm ) ] ) ] ;
2020-06-29 07:40:34 +02:00
end
2021-08-11 07:30:31 +02:00
M_ . matched_moments { jm , 1 } = tmp1 ;
M_ . matched_moments { jm , 2 } = tmp2 ;
M_ . matched_moments { jm , 3 } = tmp3 ;
2020-06-29 07:40:34 +02:00
end
2021-08-11 07:30:31 +02:00
% shift time structure to focus only on lags
M_ . matched_moments { jm , 2 } = M_ . matched_moments { jm , 2 } - max ( M_ . matched_moments { jm , 2 } ) ;
% sort such that t=0 variable comes first
[ M_ . matched_moments { jm , 2 } , idx_sort ] = sort ( M_ . matched_moments { jm , 2 } , ' descend' ) ;
M_ . matched_moments { jm , 1 } = M_ . matched_moments { jm , 1 } ( idx_sort ) ;
2021-08-16 11:19:28 +02:00
M_ . matched_moments { jm , 3 } = M_ . matched_moments { jm , 3 } ( idx_sort ) ;
2020-06-29 07:40:34 +02:00
end
2021-08-11 07:30:31 +02:00
% find duplicate rows in cell array by making groups according to powers as we can then use cell2mat for the unique function
powers = cellfun ( @ sum , M_ . matched_moments ( : , 3 ) ) ' ;
UniqueMomIdx = [ ] ;
for jpow = unique ( powers )
idx1 = find ( powers == jpow ) ;
[ ~ , idx2 ] = unique ( cell2mat ( M_ . matched_moments ( idx1 , : ) ) , ' rows' ) ;
UniqueMomIdx = [ UniqueMomIdx idx1 ( idx2 ) ] ;
2020-06-29 07:40:34 +02:00
end
2021-08-11 07:30:31 +02:00
% remove duplicate elements
DuplicateMoms = setdiff ( 1 : size ( M_ . matched_moments_orig , 1 ) , UniqueMomIdx ) ;
2021-08-16 11:19:28 +02:00
if ~ isempty ( DuplicateMoms )
2021-08-11 07:30:31 +02:00
fprintf ( ' Found and removed duplicate declared moments in ' ' matched_moments' ' block in rows:\n %s.\n' , num2str ( DuplicateMoms ) )
fprintf ( ' Dynare will continue with remaining moment conditions\n' ) ;
end
if strcmp ( options_mom_ . mom . mom_method , ' SMM' )
% for SMM we can keep the original structure but get rid of duplicate moments
2021-08-16 11:19:28 +02:00
M_ . matched_moments = M_ . matched_moments_orig ( sort ( UniqueMomIdx ) , : ) ;
2021-08-11 07:30:31 +02:00
elseif strcmp ( options_mom_ . mom . mom_method , ' GMM' )
% for GMM we use the transformed matched_moments structure
M_ . matched_moments = M_ . matched_moments ( sort ( UniqueMomIdx ) , : ) ;
2020-06-29 07:40:34 +02:00
end
% Check if both prefilter and first moments were specified
2021-08-11 07:30:31 +02:00
first_moment_indicator = find ( cellfun ( @ ( x ) sum ( abs ( x ) ) == 1 , M_ . matched_moments ( : , 3 ) ) ) ' ;
if options_mom_ . prefilter && ~ isempty ( first_moment_indicator )
fprintf ( ' Centered moments requested (prefilter option is set); therefore, ignore declared first moments in ' ' matched_moments' ' block.\n' ) ;
2021-08-16 11:19:28 +02:00
M_ . matched_moments ( first_moment_indicator , : ) = [ ] ; %remove first moments entries
2020-06-29 07:40:34 +02:00
end
2020-08-05 15:30:58 +02:00
options_mom_ . mom . mom_nbr = size ( M_ . matched_moments , 1 ) ;
2020-06-29 07:40:34 +02:00
% Get maximum lag number for autocovariances/autocorrelations
2020-08-05 15:30:58 +02:00
options_mom_ . ar = max ( cellfun ( @ max , M_ . matched_moments ( : , 2 ) ) ) - min ( cellfun ( @ min , M_ . matched_moments ( : , 2 ) ) ) ;
2020-06-29 07:40:34 +02:00
2021-12-08 09:38:41 +01:00
%check that only observed variables are involved in moments
not_observed_variables = setdiff ( oo_ . dr . inv_order_var ( [ M_ . matched_moments { : , 1 } ] ) , oo_ . dr . obs_var ) ;
if ~ isempty ( not_observed_variables )
error ( ' \nmethod_of_moments: You specified moments involving %s, but it is not a varobs.' , M_ . endo_names { oo_ . dr . order_var ( not_observed_variables ) } )
end
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
% Step 3: Checks and transformations for estimated parameters, priors, and bounds
% -------------------------------------------------------------------------
% Set priors and bounds over the estimated parameters
[ xparam0 , estim_params_ , bayestopt_ , lb , ub , M_ ] = set_prior ( estim_params_ , M_ , options_mom_ ) ;
% Check measurement errors
2020-07-10 21:42:18 +02:00
if ( estim_params_ . nvn || estim_params_ . ncn ) && strcmp ( options_mom_ . mom . mom_method , ' GMM' )
2020-06-29 07:40:34 +02:00
error ( ' method_of_moments: GMM estimation does not support measurement error(s) yet. Please specifiy them as a structural shock.' )
end
% Check if enough moments for estimation
2020-07-10 22:32:39 +02:00
if options_mom_ . mom . mom_nbr < length ( xparam0 )
2020-06-29 07:40:34 +02:00
fprintf ( ' \n' ) ;
error ( ' method_of_moments: We must have at least as many moments as parameters for a method of moments estimation.' )
end
fprintf ( ' \n\n' )
% Check if a _prior_restrictions.m file exists
if exist ( [ M_ . fname ' _prior_restrictions.m' ] , ' file' )
options_mom_ . prior_restrictions . status = 1 ;
options_mom_ . prior_restrictions . routine = str2func ( [ M_ . fname ' _prior_restrictions' ] ) ;
end
bayestopt_laplace = bayestopt_ ;
% Check on specified priors and penalized estimation
2021-08-11 17:31:24 +02:00
if any ( bayestopt_laplace . pshape > 0 ) % prior specified
2020-06-29 07:40:34 +02:00
if ~ options_mom_ . mom . penalized_estimator
fprintf ( ' \nPriors were specified, but the penalized_estimator-option was not set.\n' )
fprintf ( ' Dynare sets penalized_estimator to 1. Conducting %s with penalty.\n' , options_mom_ . mom . mom_method )
options_mom_ . mom . penalized_estimator = 1 ;
end
if any ( setdiff ( [ 0 ; bayestopt_laplace . pshape ] , [ 0 , 3 ] ) )
fprintf ( ' \nNon-normal priors specified. %s with penalty uses a Laplace type of approximation.\n' , options_mom_ . mom . mom_method )
fprintf ( ' Only the prior mean and standard deviation are relevant, all other shape information, except for the parameter bounds, is ignored.\n\n' )
non_normal_priors = bayestopt_laplace . pshape ~= 3 ;
bayestopt_laplace . pshape ( non_normal_priors ) = 3 ;
bayestopt_laplace . p3 ( non_normal_priors ) = - Inf * ones ( sum ( non_normal_priors ) , 1 ) ;
bayestopt_laplace . p4 ( non_normal_priors ) = Inf * ones ( sum ( non_normal_priors ) , 1 ) ;
bayestopt_laplace . p6 ( non_normal_priors ) = bayestopt_laplace . p1 ( non_normal_priors ) ;
bayestopt_laplace . p7 ( non_normal_priors ) = bayestopt_laplace . p2 ( non_normal_priors ) ;
bayestopt_laplace . p5 ( non_normal_priors ) = bayestopt_laplace . p1 ( non_normal_priors ) ;
end
if any ( isinf ( bayestopt_laplace . p2 ) ) %find infinite variance priors
inf_var_pars = bayestopt_laplace . name ( isinf ( bayestopt_laplace . p2 ) ) ;
disp_string = [ inf_var_pars { 1 , : } ] ;
for ii = 2 : size ( inf_var_pars , 1 )
disp_string = [ disp_string , ' , ' , inf_var_pars { ii , : } ] ;
end
fprintf ( ' The parameter(s) %s have infinite prior variance. This implies a flat prior\n' , disp_string )
fprintf ( ' Dynare disables the matrix singularity warning\n' )
2020-07-10 21:42:18 +02:00
if isoctave
warning ( ' off' , ' Octave:singular-matrix' ) ;
else
warning ( ' off' , ' MATLAB:singularMatrix' ) ;
end
2020-06-29 07:40:34 +02:00
end
end
% Check for calibrated covariances before updating parameters
estim_params_ = check_for_calibrated_covariances ( xparam0 , estim_params_ , M_ ) ;
% Checks on parameter calibration and initialization
xparam1_calib = get_all_parameters ( estim_params_ , M_ ) ; %get calibrated parameters
if ~ any ( isnan ( xparam1_calib ) ) %all estimated parameters are calibrated
estim_params_ . full_calibration_detected = 1 ;
else
estim_params_ . full_calibration_detected = 0 ;
end
if options_mom_ . use_calibration_initialization %set calibration as starting values
if ~ isempty ( bayestopt_laplace ) && all ( bayestopt_laplace . pshape == 0 ) && any ( all ( isnan ( [ xparam1_calib xparam0 ] ) , 2 ) )
error ( ' method_of_moments: When using the use_calibration option with %s without prior, the parameters must be explicitly initialized.' , options_mom_ . mom . mom_method )
else
[ xparam0 , estim_params_ ] = do_parameter_initialization ( estim_params_ , xparam1_calib , xparam0 ) ; %get explicitly initialized parameters that have precedence over calibrated values
end
end
2020-07-10 21:42:18 +02:00
% Check initialization
2020-06-29 07:40:34 +02:00
if ~ isempty ( bayestopt_laplace ) && all ( bayestopt_laplace . pshape == 0 ) && any ( isnan ( xparam0 ) )
error ( ' method_of_moments: %s without penalty requires all estimated parameters to be initialized, either in an estimated_params or estimated_params_init-block ' , options_mom_ . mom . mom_method )
end
% Set and check parameter bounds
if ~ isempty ( bayestopt_laplace ) && any ( bayestopt_laplace . pshape > 0 )
% Plot prior densities
if ~ options_mom_ . nograph && options_mom_ . plot_priors
plot_priors ( bayestopt_ , M_ , estim_params_ , options_mom_ )
plot_priors ( bayestopt_laplace , M_ , estim_params_ , options_mom_ , ' Laplace approximated priors' )
end
% Set prior bounds
Bounds = prior_bounds ( bayestopt_laplace , options_mom_ . prior_trunc ) ;
Bounds . lb = max ( Bounds . lb , lb ) ;
Bounds . ub = min ( Bounds . ub , ub ) ;
else % estimated parameters but no declared priors
% No priors are declared so Dynare will estimate the parameters
% with inequality constraints for the parameters.
Bounds . lb = lb ;
Bounds . ub = ub ;
2020-07-10 21:42:18 +02:00
if options_mom_ . mom . penalized_estimator
fprintf ( ' Penalized estimation turned off as you did not declare priors\n' )
options_mom_ . mom . penalized_estimator = 0 ;
end
2020-06-29 07:40:34 +02:00
end
% Set correct bounds for standard deviations and corrrelations
param_of_interest = ( 1 : length ( xparam0 ) ) ' < = estim_params_ . nvx + estim_params_ . nvn ;
LB_below_0 = ( Bounds . lb < 0 & param_of_interest ) ;
Bounds . lb ( LB_below_0 ) = 0 ;
param_of_interest = ( 1 : length ( xparam0 ) ) ' > estim_params_ . nvx + estim_params_ . nvn & ( 1 : length ( xparam0 ) ) ' < estim_params_ . nvx + estim_params_ . nvn + estim_params_ . ncx + estim_params_ . ncn ;
LB_below_minus_1 = ( Bounds . lb < - 1 & param_of_interest ) ;
UB_above_1 = ( Bounds . ub > 1 & param_of_interest ) ;
Bounds . lb ( LB_below_minus_1 ) = - 1 ;
Bounds . ub ( UB_above_1 ) = 1 ;
clear ( ' bayestopt_' , ' LB_below_0' , ' LB_below_minus_1' , ' UB_above_1' , ' param_of_interest' ) ; %make sure stale structure cannot be used
% Test if initial values of the estimated parameters are all between the prior lower and upper bounds
if options_mom_ . use_calibration_initialization
try
check_prior_bounds ( xparam0 , Bounds , M_ , estim_params_ , options_mom_ , bayestopt_laplace )
catch last_error
fprintf ( ' Cannot use parameter values from calibration as they violate the prior bounds.' )
rethrow ( last_error ) ;
end
else
check_prior_bounds ( xparam0 , Bounds , M_ , estim_params_ , options_mom_ , bayestopt_laplace )
end
estim_params_ = get_matrix_entries_for_psd_check ( M_ , estim_params_ ) ;
% Set sigma_e_is_diagonal flag (needed if the shocks block is not declared in the mod file).
M_ . sigma_e_is_diagonal = true ;
if estim_params_ . ncx || any ( nnz ( tril ( M_ . Correlation_matrix , - 1 ) ) ) || isfield ( estim_params_ , ' calibrated_covariances' )
M_ . sigma_e_is_diagonal = false ;
end
% storing prior parameters in MoM info structure for penalized minimization
oo_ . prior . mean = bayestopt_laplace . p1 ;
oo_ . prior . variance = diag ( bayestopt_laplace . p2 .^ 2 ) ;
% Set all parameters
M_ = set_all_parameters ( xparam0 , estim_params_ , M_ ) ;
%provide warning if there is NaN in parameters
test_for_deep_parameters_calibration ( M_ ) ;
% -------------------------------------------------------------------------
% Step 4: Checks and transformations for data
% -------------------------------------------------------------------------
% Check if datafile has same name as mod file
[ ~ , name , ~ ] = fileparts ( options_mom_ . datafile ) ;
if strcmp ( name , M_ . fname )
error ( ' method_of_moments: Data-file and mod-file are not allowed to have the same name. Please change the name of the data file.' )
end
% Build dataset
dataset_ = makedataset ( options_mom_ ) ;
% set options for old interface from the ones for new interface
if ~ isempty ( dataset_ )
options_mom_ . nobs = dataset_ . nobs ;
end
% Check length of data for estimation of second moments
if options_mom_ . ar > options_mom_ . nobs + 1
error ( ' method_of_moments: Data set is too short to compute second moments' ) ;
end
2020-12-18 14:37:45 +01:00
% Provide info on data moments handling
2020-12-16 11:18:53 +01:00
fprintf ( ' Computing data moments. Note that NaN values in the moments (due to leads and lags or missing data) are replaced by the mean of the corresponding moment\n' ) ;
2020-12-18 14:37:45 +01:00
% Get data moments for the method of moments
2021-08-15 21:00:29 +02:00
[ oo_ . mom . data_moments , oo_ . mom . m_data ] = mom . data_moments ( dataset_ . data , oo_ , M_ . matched_moments , options_mom_ ) ;
2020-06-29 07:40:34 +02:00
% Get shock series for SMM and set variance correction factor
if strcmp ( options_mom_ . mom . mom_method , ' SMM' )
2020-07-10 22:32:39 +02:00
options_mom_ . mom . long = round ( options_mom_ . mom . simulation_multiple * options_mom_ . nobs ) ;
options_mom_ . mom . variance_correction_factor = ( 1 + 1 / options_mom_ . mom . simulation_multiple ) ;
2020-06-29 07:40:34 +02:00
% draw shocks for SMM
2020-11-19 10:07:35 +01:00
if ~ isoctave
smmstream = RandStream ( ' mt19937ar' , ' Seed' , options_mom_ . mom . seed ) ;
temp_shocks = randn ( smmstream , options_mom_ . mom . long + options_mom_ . mom . burnin , M_ . exo_nbr ) ;
temp_shocks_ME = randn ( smmstream , options_mom_ . mom . long , length ( M_ . H ) ) ;
else
[ state_u , state_n ] = get_dynare_random_generator_state ; %get state for later resetting
set_dynare_random_generator_state ( options_mom_ . mom . seed , options_mom_ . mom . seed ) ;
temp_shocks = randn ( options_mom_ . mom . long + options_mom_ . mom . burnin , M_ . exo_nbr ) ;
temp_shocks_ME = randn ( options_mom_ . mom . long , length ( M_ . H ) ) ;
set_dynare_random_generator_state ( state_u , state_n ) ; %reset state for later resetting
end
2020-06-29 07:40:34 +02:00
if options_mom_ . mom . bounded_shock_support == 1
temp_shocks ( temp_shocks > 2 ) = 2 ;
temp_shocks ( temp_shocks < - 2 ) = - 2 ;
temp_shocks_ME ( temp_shocks_ME < - 2 ) = - 2 ;
temp_shocks_ME ( temp_shocks_ME < - 2 ) = - 2 ;
end
2020-07-10 22:32:39 +02:00
options_mom_ . mom . shock_series = temp_shocks ;
options_mom_ . mom . ME_shock_series = temp_shocks_ME ;
2020-12-16 10:59:49 +01:00
if options_mom_ . k_order_solver && ~ options_mom_ . pruning % dynare++ routines will be called in simult_.m, store some additional stuff
options_mom_ . DynareRandomStreams . seed = options_mom_ . mom . seed ;
end
2020-06-29 07:40:34 +02:00
end
% -------------------------------------------------------------------------
% Step 5: checks for steady state at initial parameters
% -------------------------------------------------------------------------
% setting steadystate_check_flag option
if options_mom_ . steadystate . nocheck
steadystate_check_flag = 0 ;
else
steadystate_check_flag = 1 ;
end
old_steady_params = M_ . params ; %save initial parameters for check if steady state changes param values
% Check steady state at initial model parameter values
[ oo_ . steady_state , new_steady_params , info ] = evaluate_steady_state ( oo_ . steady_state , M_ , options_mom_ , oo_ , steadystate_check_flag ) ;
if info ( 1 )
fprintf ( ' \nmethod_of_moments: The steady state at the initial parameters cannot be computed.\n' )
print_info ( info , 0 , options_mom_ ) ;
end
% check whether steady state file changes estimated parameters
if isfield ( estim_params_ , ' param_vals' ) && ~ isempty ( estim_params_ . param_vals )
Model_par_varied = M_ ; %store M_ structure
Model_par_varied . params ( estim_params_ . param_vals ( : , 1 ) ) = Model_par_varied . params ( estim_params_ . param_vals ( : , 1 ) ) * 1.01 ; %vary parameters
[ ~ , new_steady_params_2 ] = evaluate_steady_state ( oo_ . steady_state , Model_par_varied , options_mom_ , oo_ , 1 ) ;
changed_par_indices = find ( ( old_steady_params ( estim_params_ . param_vals ( : , 1 ) ) - new_steady_params ( estim_params_ . param_vals ( : , 1 ) ) ) ...
| ( Model_par_varied . params ( estim_params_ . param_vals ( : , 1 ) ) - new_steady_params_2 ( estim_params_ . param_vals ( : , 1 ) ) ) ) ;
if ~ isempty ( changed_par_indices )
fprintf ( ' \nThe steady state file internally changed the values of the following estimated parameters:\n' )
disp ( char ( M_ . param_names ( estim_params_ . param_vals ( changed_par_indices , 1 ) ) ) )
fprintf ( ' This will override parameter values and may lead to wrong results.\n' )
fprintf ( ' Check whether this is really intended.\n' )
warning ( ' The steady state file internally changes the values of the estimated parameters.' )
2020-12-16 12:03:21 +01:00
if strcmp ( options_mom_ . mom . mom_method , ' GMM' ) && options_mom_ . mom . analytic_standard_errors
fprintf ( ' For analytical standard errors, the parameter-Jacobians of the dynamic model and of the steady-state will be computed numerically\n' ) ,
fprintf ( ' (re-set options_mom_.analytic_derivation_mode= -2)' ) ,
options_mom_ . analytic_derivation_mode = - 2 ;
end
2020-06-29 07:40:34 +02:00
end
end
% display warning if some parameters are still NaN
test_for_deep_parameters_calibration ( M_ ) ;
% If steady state of observed variables is non zero, set noconstant equal 0
if all ( abs ( oo_ . steady_state ( oo_ . dr . order_var ( oo_ . dr . obs_var ) ) ) < 1e-9 )
2021-08-20 13:31:31 +02:00
options_mom_ . noconstant = 0 ; %identifying the constant based on just the initial parameter value is not feasible
2020-06-29 07:40:34 +02:00
else
options_mom_ . noconstant = 0 ;
end
% -------------------------------------------------------------------------
% Step 6: checks for objective function at initial parameters
% -------------------------------------------------------------------------
2021-08-15 21:00:29 +02:00
objective_function = str2func ( ' mom.objective_function' ) ;
2021-01-14 10:03:39 +01:00
2020-06-29 07:40:34 +02:00
try
% Check for NaN or complex values of moment-distance-funtion evaluated
% at initial parameters and identity weighting matrix
2020-07-10 22:32:39 +02:00
oo_ . mom . Sw = eye ( options_mom_ . mom . mom_nbr ) ;
2020-06-29 07:40:34 +02:00
tic_id = tic ;
2020-08-05 15:30:58 +02:00
[ fval , info , ~ , ~ , ~ , oo_ , M_ ] = feval ( objective_function , xparam0 , Bounds , oo_ , estim_params_ , M_ , options_mom_ ) ;
2020-06-29 07:40:34 +02:00
elapsed_time = toc ( tic_id ) ;
if isnan ( fval )
error ( ' method_of_moments: The initial value of the objective function is NaN' )
elseif imag ( fval )
error ( ' method_of_moments: The initial value of the objective function is complex' )
end
if info ( 1 ) > 0
disp ( ' method_of_moments: Error in computing the objective function for initial parameter values' )
print_info ( info , options_mom_ . noprint , options_mom_ )
end
fprintf ( ' Initial value of the moment objective function with %4.1f times identity weighting matrix: %6.4f \n\n' , options_mom_ . mom . weighting_matrix_scaling_factor , fval ) ;
fprintf ( ' Time required to compute objective function once: %5.4f seconds \n' , elapsed_time ) ;
catch last_error % if check fails, provide info on using calibration if present
if estim_params_ . full_calibration_detected %calibrated model present and no explicit starting values
skipline ( 1 ) ;
fprintf ( ' There was an error in computing the moments for initial parameter values.\n' )
fprintf ( ' If this is not a problem with the setting of options (check the error message below),\n' )
fprintf ( ' you should try using the calibrated version of the model as starting values. To do\n' )
fprintf ( ' this, add an empty estimated_params_init-block with use_calibration option immediately before the estimation\n' )
fprintf ( ' command (and after the estimated_params-block so that it does not get overwritten):\n' ) ;
skipline ( 2 ) ;
end
rethrow ( last_error ) ;
end
% -------------------------------------------------------------------------
% Step 7a: Method of moments estimation: print some info
% -------------------------------------------------------------------------
fprintf ( ' \n---------------------------------------------------\n' )
if strcmp ( options_mom_ . mom . mom_method , ' SMM' )
fprintf ( ' Simulated method of moments with' ) ;
elseif strcmp ( options_mom_ . mom . mom_method , ' GMM' )
fprintf ( ' General method of moments with' ) ;
end
if options_mom_ . prefilter
fprintf ( ' \n - centered moments (prefilter=1)' ) ;
else
fprintf ( ' \n - uncentered moments (prefilter=0)' ) ;
end
if options_mom_ . mom . penalized_estimator
2020-07-10 21:42:18 +02:00
fprintf ( ' \n - penalized estimation using deviation from prior mean and weighted with prior precision' ) ;
2020-06-29 07:40:34 +02:00
end
2021-01-14 10:03:39 +01:00
2021-01-06 13:57:07 +01:00
for i = 1 : length ( optimizer_vec )
if i == 1
str = ' - optimizer (mode_compute' ;
else
str = ' (additional_optimizer_steps' ;
end
2021-01-07 10:33:09 +01:00
switch optimizer_vec { i }
case 0
fprintf ( ' \n %s=0): no minimization' , str ) ;
case 1
fprintf ( ' \n %s=1): fmincon' , str ) ;
case 2
fprintf ( ' \n %s=2): continuous simulated annealing' , str ) ;
case 3
fprintf ( ' \n %s=3): fminunc' , str ) ;
case 4
fprintf ( ' \n %s=4): csminwel' , str ) ;
case 5
fprintf ( ' \n %s=5): newrat' , str ) ;
case 6
fprintf ( ' \n %s=6): gmhmaxlik' , str ) ;
case 7
fprintf ( ' \n %s=7): fminsearch' , str ) ;
case 8
fprintf ( ' \n %s=8): Dynare Nelder-Mead simplex' , str ) ;
case 9
fprintf ( ' \n %s=9): CMA-ES' , str ) ;
case 10
fprintf ( ' \n %s=10): simpsa' , str ) ;
case 11
2021-01-10 17:30:35 +01:00
error ( ' \nmethod_of_moments: online_auxiliary_filter (mode_compute=11) is only supported with likelihood-based estimation techniques' ) ;
2021-01-07 10:33:09 +01:00
case 12
fprintf ( ' \n %s=12): particleswarm' , str ) ;
case 101
fprintf ( ' \n %s=101): SolveOpt' , str ) ;
case 102
fprintf ( ' \n %s=102): simulannealbnd' , str ) ;
case 13
fprintf ( ' \n %s=13): lsqnonlin' , str ) ;
otherwise
if ischar ( optimizer_vec { i } )
fprintf ( ' \n %s=%s): user-defined' , str , optimizer_vec { i } ) ;
else
error ( ' method_of_moments: Unknown optimizer, please contact the developers ' )
end
2021-01-06 13:57:07 +01:00
end
if options_mom_ . silent_optimizer
fprintf ( ' (silent)' ) ;
end
2021-01-14 10:03:39 +01:00
if strcmp ( options_mom_ . mom . mom_method , ' GMM' ) && options_mom_ . mom . analytic_jacobian && ismember ( optimizer_vec { i } , analytic_jacobian_optimizers )
fprintf ( ' (using analytical Jacobian)' ) ;
end
2020-06-29 07:40:34 +02:00
end
fprintf ( ' \n - perturbation order: %d' , options_mom_ . order )
if options_mom_ . order > 1 && options_mom_ . pruning
fprintf ( ' (with pruning)' )
end
2020-12-16 12:03:21 +01:00
if strcmp ( options_mom_ . mom . mom_method , ' GMM' ) && options_mom_ . mom . analytic_standard_errors
fprintf ( ' \n - standard errors: analytic derivatives' ) ;
else
fprintf ( ' \n - standard errors: numerical derivatives' ) ;
end
2020-07-10 22:32:39 +02:00
fprintf ( ' \n - number of matched moments: %d' , options_mom_ . mom . mom_nbr ) ;
2020-12-16 12:03:21 +01:00
fprintf ( ' \n - number of parameters: %d' , length ( xparam0 ) ) ;
fprintf ( ' \n\n' ) ;
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
2020-07-10 21:42:18 +02:00
% Step 7b: Iterated method of moments estimation
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
if size ( options_mom_ . mom . weighting_matrix , 1 ) > 1 && ~ ( any ( strcmpi ( ' diagonal' , options_mom_ . mom . weighting_matrix ) ) || any ( strcmpi ( ' optimal' , options_mom_ . mom . weighting_matrix ) ) )
2020-07-10 21:42:18 +02:00
fprintf ( ' \nYou did not specify the use of an optimal or diagonal weighting matrix. There is no point in running an iterated method of moments.\n' )
2020-06-29 07:40:34 +02:00
end
2020-07-10 21:42:18 +02:00
for stage_iter = 1 : size ( options_mom_ . mom . weighting_matrix , 1 )
2020-06-29 07:40:34 +02:00
fprintf ( ' Estimation stage %u\n' , stage_iter ) ;
2020-07-10 21:42:18 +02:00
Woptflag = false ;
2020-06-29 07:40:34 +02:00
switch lower ( options_mom_ . mom . weighting_matrix { stage_iter } )
case ' identity_matrix'
fprintf ( ' - identity weighting matrix\n' ) ;
2020-07-10 21:42:18 +02:00
weighting_matrix = eye ( options_mom_ . mom . mom_nbr ) ;
2020-06-29 07:40:34 +02:00
case ' diagonal'
2020-07-10 21:42:18 +02:00
fprintf ( ' - diagonal of optimal weighting matrix (Bartlett kernel with %d lags)\n' , options_mom_ . mom . bartlett_kernel_lag ) ;
if stage_iter == 1
fprintf ( ' and using data-moments as initial estimate of model-moments\n' ) ;
2021-08-15 21:00:29 +02:00
weighting_matrix = diag ( diag ( mom . optimal_weighting_matrix ( oo_ . mom . m_data , oo_ . mom . data_moments , options_mom_ . mom . bartlett_kernel_lag ) ) ) ;
2020-07-10 21:42:18 +02:00
else
fprintf ( ' and using previous stage estimate of model-moments\n' ) ;
2021-08-15 21:00:29 +02:00
weighting_matrix = diag ( diag ( mom . optimal_weighting_matrix ( oo_ . mom . m_data , oo_ . mom . model_moments , options_mom_ . mom . bartlett_kernel_lag ) ) ) ;
2020-07-10 21:42:18 +02:00
end
2020-06-29 07:40:34 +02:00
case ' optimal'
2020-07-10 21:42:18 +02:00
fprintf ( ' - optimal weighting matrix (Bartlett kernel with %d lags)\n' , options_mom_ . mom . bartlett_kernel_lag ) ;
if stage_iter == 1
fprintf ( ' and using data-moments as initial estimate of model-moments\n' ) ;
2021-08-15 21:00:29 +02:00
weighting_matrix = mom . optimal_weighting_matrix ( oo_ . mom . m_data , oo_ . mom . data_moments , options_mom_ . mom . bartlett_kernel_lag ) ;
2020-07-10 21:42:18 +02:00
else
fprintf ( ' and using previous stage estimate of model-moments\n' ) ;
2021-08-15 21:00:29 +02:00
weighting_matrix = mom . optimal_weighting_matrix ( oo_ . mom . m_data , oo_ . mom . model_moments , options_mom_ . mom . bartlett_kernel_lag ) ;
2020-07-10 21:42:18 +02:00
Woptflag = true ;
end
2020-06-29 07:40:34 +02:00
otherwise %user specified matrix in file
2020-07-10 21:42:18 +02:00
fprintf ( ' - user-specified weighting matrix\n' ) ;
2020-06-29 07:40:34 +02:00
try
load ( options_mom_ . mom . weighting_matrix { stage_iter } , ' weighting_matrix' )
catch
error ( [ ' method_of_moments: No matrix named ' ' weighting_matrix' ' could be found in ' , options_mom_ . mom . weighting_matrix { stage_iter } , ' .mat' ] )
end
[ nrow , ncol ] = size ( weighting_matrix ) ;
2020-07-10 21:42:18 +02:00
if ~ isequal ( nrow , ncol ) || ~ isequal ( nrow , length ( oo_ . mom . data_moments ) ) %check if square and right size
2020-06-29 07:40:34 +02:00
error ( [ ' method_of_moments: weighting_matrix must be square and have ' , num2str ( length ( oo_ . mom . data_moments ) ) , ' rows and columns' ] )
2020-07-10 21:42:18 +02:00
end
2020-06-29 07:40:34 +02:00
end
2020-07-10 21:42:18 +02:00
try %check for positive definiteness of weighting_matrix
oo_ . mom . Sw = chol ( weighting_matrix ) ;
catch
error ( ' method_of_moments: Specified weighting_matrix is not positive definite. Check whether your model implies stochastic singularity.' )
end
for optim_iter = 1 : length ( optimizer_vec )
2021-01-14 10:03:39 +01:00
options_mom_ . current_optimizer = optimizer_vec { optim_iter } ;
2021-01-06 13:57:07 +01:00
if optimizer_vec { optim_iter } == 0
xparam1 = xparam0 ; %no minimization, evaluate objective at current values
fval = feval ( objective_function , xparam1 , Bounds , oo_ , estim_params_ , M_ , options_mom_ ) ;
2020-06-29 07:40:34 +02:00
else
2021-01-06 13:57:07 +01:00
if optimizer_vec { optim_iter } == 13
2021-01-14 10:03:39 +01:00
options_mom_ . vector_output = true ;
else
options_mom_ . vector_output = false ;
end
if strcmp ( options_mom_ . mom . mom_method , ' GMM' ) && options_mom_ . mom . analytic_jacobian && ismember ( optimizer_vec { optim_iter } , analytic_jacobian_optimizers ) %do this only for gradient-based optimizers
options_mom_ . mom . compute_derivs = true ;
2021-01-06 13:57:07 +01:00
else
2021-01-14 10:03:39 +01:00
options_mom_ . mom . compute_derivs = false ;
2021-01-06 13:57:07 +01:00
end
2021-01-14 10:03:39 +01:00
2021-01-22 19:53:57 +01:00
[ xparam1 , fval , exitflag ] = dynare_minimize_objective ( objective_function , xparam0 , optimizer_vec { optim_iter } , options_mom_ , [ Bounds . lb Bounds . ub ] , bayestopt_laplace . name , bayestopt_laplace , [ ] , ...
2021-01-06 13:57:07 +01:00
Bounds , oo_ , estim_params_ , M_ , options_mom_ ) ;
if options_mom_ . vector_output
fval = fval ' * fval ;
end
2020-06-29 07:40:34 +02:00
end
2020-07-10 21:42:18 +02:00
fprintf ( ' \nStage %d Iteration %d: value of minimized moment distance objective function: %12.10f.\n' , stage_iter , optim_iter , fval )
2020-06-29 07:40:34 +02:00
if options_mom_ . mom . verbose
2020-07-10 21:42:18 +02:00
oo_ . mom = display_estimation_results_table ( xparam1 , NaN ( size ( xparam1 ) ) , M_ , options_mom_ , estim_params_ , bayestopt_laplace , oo_ . mom , prior_dist_names , sprintf ( ' %s (STAGE %d ITERATION %d) VERBOSE' , options_mom_ . mom . mom_method , stage_iter , optim_iter ) , sprintf ( ' verbose_%s_stage_%d_iter_%d' , lower ( options_mom_ . mom . mom_method ) , stage_iter , optim_iter ) ) ;
2020-06-29 07:40:34 +02:00
end
xparam0 = xparam1 ;
end
2020-07-10 21:42:18 +02:00
options_mom_ . vector_output = false ;
% Update M_ and DynareResults (in particular to get oo_.mom.model_moments)
2020-06-29 07:40:34 +02:00
M_ = set_all_parameters ( xparam1 , estim_params_ , M_ ) ;
2020-12-16 12:03:21 +01:00
if strcmp ( options_mom_ . mom . mom_method , ' GMM' ) && options_mom_ . mom . analytic_standard_errors
options_mom_ . mom . compute_derivs = true ; % for GMM we compute derivatives analytically in the objective function with this flag
end
2020-08-05 15:30:58 +02:00
[ fval , ~ , ~ , ~ , ~ , oo_ ] = feval ( objective_function , xparam1 , Bounds , oo_ , estim_params_ , M_ , options_mom_ ) ;
2020-12-16 12:03:21 +01:00
options_mom_ . mom . compute_derivs = false ; % reset to not compute derivatives in objective function during optimization
2021-08-15 21:00:29 +02:00
SE = mom . standard_errors ( xparam1 , objective_function , Bounds , oo_ , estim_params_ , M_ , options_mom_ , Woptflag ) ;
2020-06-29 07:40:34 +02:00
2020-07-10 21:42:18 +02:00
% Store results in output structure
2020-06-29 07:40:34 +02:00
oo_ . mom = display_estimation_results_table ( xparam1 , SE , M_ , options_mom_ , estim_params_ , bayestopt_laplace , oo_ . mom , prior_dist_names , sprintf ( ' %s (STAGE %u)' , options_mom_ . mom . mom_method , stage_iter ) , sprintf ( ' %s_stage_%u' , lower ( options_mom_ . mom . mom_method ) , stage_iter ) ) ;
end
2020-07-10 22:32:39 +02:00
% -------------------------------------------------------------------------
% Step 8: J test
% -------------------------------------------------------------------------
if options_mom_ . mom . mom_nbr > length ( xparam1 )
%get optimal weighting matrix for J test, if necessary
if ~ Woptflag
2021-08-15 21:00:29 +02:00
W_opt = mom . optimal_weighting_matrix ( oo_ . mom . m_data , oo_ . mom . model_moments , options_mom_ . mom . bartlett_kernel_lag ) ;
2020-07-10 22:32:39 +02:00
oo_j = oo_ ;
oo_j . mom . Sw = chol ( W_opt ) ;
2020-08-05 15:30:58 +02:00
[ fval ] = feval ( objective_function , xparam1 , Bounds , oo_j , estim_params_ , M_ , options_mom_ ) ;
2020-07-10 22:32:39 +02:00
end
% Compute J statistic
if strcmp ( options_mom_ . mom . mom_method , ' SMM' )
Variance_correction_factor = options_mom_ . mom . variance_correction_factor ;
elseif strcmp ( options_mom_ . mom . mom_method , ' GMM' )
Variance_correction_factor = 1 ;
end
oo_ . mom . J_test . j_stat = dataset_ . nobs * Variance_correction_factor * fval / options_mom_ . mom . weighting_matrix_scaling_factor ;
oo_ . mom . J_test . degrees_freedom = length ( oo_ . mom . model_moments ) - length ( xparam1 ) ;
oo_ . mom . J_test . p_val = 1 - chi2cdf ( oo_ . mom . J_test . j_stat , oo_ . mom . J_test . degrees_freedom ) ;
fprintf ( ' \nvalue of J-test statistic: %f\n' , oo_ . mom . J_test . j_stat )
fprintf ( ' p-value of J-test statistic: %f\n' , oo_ . mom . J_test . p_val )
2020-06-29 07:40:34 +02:00
end
2020-07-10 21:42:18 +02:00
% -------------------------------------------------------------------------
% Step 9: Display estimation results
% -------------------------------------------------------------------------
2021-08-11 07:30:31 +02:00
title = [ ' Comparison of data moments and model moments (' , options_mom_ . mom . mom_method , ' )' ] ;
headers = { ' Moment' , ' Data' , ' Model' } ;
for jm = 1 : size ( M_ . matched_moments , 1 )
lables_tmp = ' E[' ;
lables_tmp_tex = ' E \left[ ' ;
for jvar = 1 : length ( M_ . matched_moments { jm , 1 } )
lables_tmp = [ lables_tmp M_ . endo_names { M_ . matched_moments { jm , 1 } ( jvar ) } ] ;
lables_tmp_tex = [ lables_tmp_tex , ' {' , M_ . endo_names_tex { M_ . matched_moments { jm , 1 } ( jvar ) } , ' }' ] ;
if M_ . matched_moments { jm , 2 } ( jvar ) ~= 0
lables_tmp = [ lables_tmp , ' (' , num2str ( M_ . matched_moments { jm , 2 } ( jvar ) ) , ' )' ] ;
lables_tmp_tex = [ lables_tmp_tex , ' _{t' , num2str ( M_ . matched_moments { jm , 2 } ( jvar ) ) , ' }' ] ;
else
lables_tmp_tex = [ lables_tmp_tex , ' _{t}' ] ;
end
if M_ . matched_moments { jm , 3 } ( jvar ) > 1
lables_tmp = [ lables_tmp , ' ^' , num2str ( M_ . matched_moments { jm , 3 } ( jvar ) ) ] ;
lables_tmp_tex = [ lables_tmp_tex , ' ^{' , num2str ( M_ . matched_moments { jm , 3 } ( jvar ) ) ' }' ] ;
end
if jvar == length ( M_ . matched_moments { jm , 1 } )
lables_tmp = [ lables_tmp , ' ]' ] ;
lables_tmp_tex = [ lables_tmp_tex , ' \right]' ] ;
else
lables_tmp = [ lables_tmp , ' *' ] ;
lables_tmp_tex = [ lables_tmp_tex , ' \times ' ] ;
end
end
labels { jm , 1 } = lables_tmp ;
labels_TeX { jm , 1 } = lables_tmp_tex ;
end
data_mat = [ oo_ . mom . data_moments oo_ . mom . model_moments ] ;
2020-06-29 07:40:34 +02:00
dyntable ( options_mom_ , title , headers , labels , data_mat , cellofchararraymaxlength ( labels ) + 2 , 10 , 7 ) ;
2021-08-16 11:19:28 +02:00
if options_mom_ . TeX
2021-08-11 07:30:31 +02:00
dyn_latex_table ( M_ , options_mom_ , title , [ ' comparison_moments_' , options_mom_ . mom . mom_method ] , headers , labels_TeX , data_mat , cellofchararraymaxlength ( labels ) + 2 , 10 , 7 ) ;
2020-06-29 07:40:34 +02:00
end
if options_mom_ . mode_check . status
2021-08-15 21:00:29 +02:00
mom . check_plot ( objective_function , xparam1 , SE , options_mom_ , M_ , estim_params_ , Bounds , bayestopt_laplace , ...
2020-08-05 15:30:58 +02:00
Bounds , oo_ , estim_params_ , M_ , options_mom_ )
2020-06-29 07:40:34 +02:00
end
fprintf ( ' \n==== Method of Moments Estimation (%s) Completed ====\n\n' , options_mom_ . mom . mom_method )
% -------------------------------------------------------------------------
2020-07-10 21:42:18 +02:00
% Step 9: Clean up
2020-06-29 07:40:34 +02:00
% -------------------------------------------------------------------------
2020-07-10 21:42:18 +02:00
%reset warning state
2022-04-15 14:32:54 +02:00
warning_config ;
2021-09-17 15:18:39 +02:00
if isoctave && isfield ( options_ , ' prior_restrictions' ) && ...
isfield ( options_ . prior_restrictions , ' routine' )
% Octave crashes if it tries to save function handles (to the _results.mat file)
% See https://savannah.gnu.org/bugs/?43215
options_ . prior_restrictions . routine = [ ] ;
end