2009-12-16 18:17:34 +01:00
function dynare_estimation_1 ( var_list_,dname)
% function dynare_estimation_1(var_list_,dname)
% runs the estimation of the model
2011-09-17 15:38:49 +02:00
%
2009-12-16 18:17:34 +01:00
% INPUTS
% var_list_: selected endogenous variables vector
% dname: alternative directory name
2011-09-17 15:38:49 +02:00
%
2009-12-16 18:17:34 +01:00
% OUTPUTS
% none
%
% SPECIAL REQUIREMENTS
% none
2023-09-01 21:42:51 +02:00
% Copyright © 2003-2023 Dynare Team
2009-12-16 18:17:34 +01: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/>.
2009-12-16 18:17:34 +01:00
2014-06-16 17:41:59 +02:00
global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info
2009-12-16 18:17:34 +01:00
2023-09-01 21:42:51 +02:00
dispString = ' Estimation::mcmc' ;
2021-07-22 17:46:08 +02:00
if ~ exist ( [ M_ . dname filesep ' Output' ] , ' dir' )
2022-04-20 10:36:56 +02:00
if isoctave && octave_ver_less_than ( ' 7' ) && ~ exist ( M_ . dname )
2021-09-15 18:35:30 +02:00
% See https://savannah.gnu.org/bugs/index.php?61166
% This workaround is needed for recursive estimation.
mkdir ( M_ . dname )
end
2021-07-22 17:46:08 +02:00
mkdir ( M_ . dname , ' Output' ) ;
end
2017-03-16 15:45:08 +01:00
if isempty ( estim_params_ )
mode_compute_o = options_ . mode_compute ;
mh_replic_o = options_ . mh_replic ;
options_ . mode_compute = 0 ;
options_ . mh_replic = 0 ;
reset_options_related_to_estimation = true ;
else
reset_options_related_to_estimation = false ;
end
2016-06-16 22:40:54 +02:00
%store qz_criterium
qz_criterium_old = options_ . qz_criterium ;
2017-03-20 20:29:19 +01:00
if isnan ( options_ . first_obs )
first_obs_nan_indicator = true ;
else
first_obs_nan_indicator = false ;
end
2016-06-16 22:40:54 +02:00
2012-03-03 16:27:25 +01:00
% Set particle filter flag.
if options_ . order > 1
2019-12-19 22:52:39 +01:00
if options_ . particle . status
2013-07-10 16:16:32 +02:00
skipline ( )
2012-03-05 08:46:52 +01:00
disp ( ' Estimation using a non linear filter!' )
2013-07-10 16:16:32 +02:00
skipline ( )
2015-05-27 12:55:10 +02:00
if ~ options_ . nointeractive && ismember ( options_ . mode_compute , [ 1 , 3 , 4 ] ) && ~ strcmpi ( options_ . particle . filter_algorithm , ' gf' ) % Known gradient-based optimizers
2017-05-16 15:10:20 +02:00
disp ( ' You are using a gradient-based mode-finder. Particle filtering introduces discontinuities in the' )
2013-07-10 16:15:28 +02:00
disp ( ' objective function w.r.t the parameters. Thus, should use a non-gradient based optimizer.' )
2013-07-08 19:34:31 +02:00
fprintf ( ' \nPlease choose a mode-finder:\n' )
2013-07-10 16:03:49 +02:00
fprintf ( ' \t 0 - Continue using gradient-based method (it is most likely that you will no get any sensible result).\n' )
2013-07-08 19:34:31 +02:00
fprintf ( ' \t 6 - Monte Carlo based algorithm\n' )
2013-07-10 16:03:49 +02:00
fprintf ( ' \t 7 - Nelder-Mead simplex based optimization routine (Matlab optimization toolbox required)\n' )
fprintf ( ' \t 8 - Nelder-Mead simplex based optimization routine (Dynare' ' s implementation)\n' )
2013-07-08 19:34:31 +02:00
fprintf ( ' \t 9 - CMA-ES (Covariance Matrix Adaptation Evolution Strategy) algorithm\n' )
2013-07-10 16:03:49 +02:00
choice = [ ] ;
while isempty ( choice )
choice = input ( ' Please enter your choice: ' ) ;
if isnumeric ( choice ) && isint ( choice ) && ismember ( choice , [ 0 6 7 8 9 ] )
if choice
options_ . mode_compute = choice ;
end
else
fprintf ( ' \nThis is an invalid choice (you have to choose between 0, 6, 7, 8 and 9).\n' )
choice = [ ] ;
end
2013-07-08 19:34:31 +02:00
end
end
2012-03-05 08:46:52 +01:00
else
2019-12-19 22:52:39 +01:00
error ( ' For estimating the model with a second order approximation using a non linear filter, one should have options_.particle.status=true;' )
2012-03-05 08:46:52 +01:00
end
2012-03-03 16:27:25 +01:00
end
2023-09-27 08:06:37 +02:00
%% set objective function
2011-09-19 16:38:38 +02:00
if ~ options_ . dsge_var
2012-03-05 08:46:52 +01:00
if options_ . particle . status
2012-03-03 16:27:25 +01:00
objective_function = str2func ( ' non_linear_dsge_likelihood' ) ;
2021-05-11 11:40:51 +02:00
[ options_ . particle ] = check_particle_filter_options ( options_ . particle ) ;
2012-03-03 16:27:25 +01:00
else
2021-05-17 21:24:25 +02:00
if options_ . occbin . likelihood . status && options_ . occbin . likelihood . inversion_filter
objective_function = str2func ( ' occbin.IVF_posterior' ) ;
2023-01-06 11:54:24 +01:00
elseif options_ . conditional_likelihood . status && options_ . conditional_likelihood . order == 1
objective_function = str2func ( ' dsge_conditional_likelihood_1' ) ;
2021-05-17 21:24:25 +02:00
else
objective_function = str2func ( ' dsge_likelihood' ) ;
end
2012-03-03 16:27:25 +01:00
end
2011-09-19 16:38:38 +02:00
else
2013-11-16 23:33:37 +01:00
objective_function = str2func ( ' dsge_var_likelihood' ) ;
2011-09-19 16:38:38 +02:00
end
2014-10-20 16:18:54 +02:00
[ dataset_ , dataset_info , xparam1 , hh , M_ , options_ , oo_ , estim_params_ , bayestopt_ , bounds ] = ...
2014-06-16 17:41:59 +02:00
dynare_estimation_init ( var_list_ , dname , [ ] , M_ , options_ , oo_ , estim_params_ , bayestopt_ ) ;
2011-09-17 15:38:49 +02:00
2013-11-16 23:26:19 +01:00
if options_ . dsge_var
check_dsge_var_model ( M_ , estim_params_ , bayestopt_ ) ;
2014-06-23 10:55:08 +02:00
if dataset_info . missing . state
error ( ' Estimation::DsgeVarLikelihood: I cannot estimate a DSGE-VAR model with missing observations!' )
end
if options_ . noconstant
2021-12-08 12:54:03 +01:00
dataset_info = var_sample_moments ( options_ . dsge_varlag , - 1 , dataset_ , dataset_info ) ;
2014-06-23 10:55:08 +02:00
else
% The steady state is non zero ==> a constant in the VAR is needed!
2021-12-08 12:54:03 +01:00
dataset_info = var_sample_moments ( options_ . dsge_varlag , 0 , dataset_ , dataset_info ) ;
2014-06-23 10:55:08 +02:00
end
2012-06-06 15:58:48 +02:00
end
2012-06-06 18:24:03 +02:00
% Set sigma_e_is_diagonal flag (needed if the shocks block is not declared in the mod file).
2019-03-19 14:26:16 +01:00
M_ . sigma_e_is_diagonal = true ;
2013-10-30 14:26:30 +01:00
if estim_params_ . ncx || any ( nnz ( tril ( M_ . Correlation_matrix , - 1 ) ) ) || isfield ( estim_params_ , ' calibrated_covariances' )
2019-03-19 14:26:16 +01:00
M_ . sigma_e_is_diagonal = false ;
2012-06-06 15:58:48 +02:00
end
2011-09-17 15:38:49 +02:00
data = dataset_ . data ;
2014-06-16 17:41:59 +02:00
data_index = dataset_info . missing . aindex ;
missing_value = dataset_info . missing . state ;
2009-12-16 18:17:34 +01:00
2011-09-17 15:38:49 +02:00
% Set number of observations
2014-06-16 17:41:59 +02:00
gend = dataset_ . nobs ;
2017-10-10 10:05:59 +02:00
2011-09-17 15:38:49 +02:00
% Get the number of parameters to be estimated.
2009-12-16 18:17:34 +01:00
nvx = estim_params_ . nvx ; % Variance of the structural innovations (number of parameters).
nvn = estim_params_ . nvn ; % Variance of the measurement innovations (number of parameters).
ncx = estim_params_ . ncx ; % Covariance of the structural innovations (number of parameters).
ncn = estim_params_ . ncn ; % Covariance of the measurement innovations (number of parameters).
np = estim_params_ . np ; % Number of deep parameters.
nx = nvx + nvn + ncx + ncn + np ; % Total number of parameters to be estimated.
2017-10-10 10:05:59 +02:00
2009-12-16 18:17:34 +01:00
if ~ isempty ( estim_params_ )
2013-10-30 14:26:30 +01:00
M_ = set_all_parameters ( xparam1 , estim_params_ , M_ ) ;
2009-12-16 18:17:34 +01:00
end
2011-10-12 21:46:50 +02:00
2013-10-30 21:43:33 +01:00
%% perform initial estimation checks;
try
2014-10-20 16:18:54 +02:00
oo_ = initial_estimation_checks ( objective_function , xparam1 , dataset_ , dataset_info , M_ , estim_params_ , options_ , bayestopt_ , bounds , oo_ ) ;
2013-11-08 15:02:30 +01:00
catch % if check fails, provide info on using calibration if present
e = lasterror ( ) ;
2014-07-20 12:46:14 +02:00
if estim_params_ . full_calibration_detected %calibrated model present and no explicit starting values
2013-10-30 21:43:33 +01:00
skipline ( 1 ) ;
fprintf ( ' ESTIMATION_CHECKS: There was an error in computing the likelihood for initial parameter values.\n' )
2016-06-19 17:03:48 +02:00
fprintf ( ' ESTIMATION_CHECKS: If this is not a problem with the setting of options (check the error message below),\n' )
fprintf ( ' ESTIMATION_CHECKS: you should try using the calibrated version of the model as starting values. To do\n' )
2017-05-16 15:10:20 +02:00
fprintf ( ' ESTIMATION_CHECKS: this, add an empty estimated_params_init-block with use_calibration option immediately before the estimation\n' )
2013-10-30 21:43:33 +01:00
fprintf ( ' ESTIMATION_CHECKS: command (and after the estimated_params-block so that it does not get overwritten):\n' ) ;
skipline ( 2 ) ;
end
2013-11-08 15:02:30 +01:00
rethrow ( e ) ;
2013-10-30 21:43:33 +01:00
end
2009-12-16 18:17:34 +01:00
2023-09-27 08:06:37 +02:00
%% Run smoother if no estimation or mode-finding are requested
2021-09-21 17:31:39 +02:00
if isequal ( options_ . mode_compute , 0 ) && isempty ( options_ . mode_file ) && ~ options_ . mh_posterior_mode_estimation
2021-01-17 16:39:10 +01:00
if options_ . order == 1 && ~ options_ . particle . status
if options_ . smoother
2021-05-17 21:24:25 +02:00
if options_ . occbin . smoother . status && options_ . occbin . smoother . inversion_filter
2023-09-27 08:06:37 +02:00
[ ~ , info , ~ , ~ , ~ , ~ , ~ , ~ , ~ , ~ , oo_ . dr , atT , innov ] = occbin . IVF_posterior ( xparam1 , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , prior_bounds ( bayestopt_ , options_ . prior_trunc ) , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
2022-11-23 16:46:40 +01:00
if ismember ( info ( 1 ) , [ 303 , 304 , 306 ] )
fprintf ( ' \nIVF: smoother did not succeed. No results will be written to oo_.\n' )
else
updated_variables = atT * nan ;
measurement_error = [ ] ;
ys = oo_ . dr . ys ;
trend_coeff = zeros ( length ( options_ . varobs_id ) , 1 ) ;
bayestopt_ . mf = bayestopt_ . smoother_var_list ( bayestopt_ . smoother_mf ) ;
options_nk = options_ . nk ;
options_ . nk = [ ] ; %unset options_.nk and reset it later
[ oo_ ] = store_smoother_results ( M_ , oo_ , options_ , bayestopt_ , dataset_ , dataset_info , atT , innov , measurement_error , updated_variables , ys , trend_coeff ) ;
options_ . nk = options_nk ;
end
2021-05-17 21:24:25 +02:00
else
if options_ . occbin . smoother . status
2023-09-15 13:40:10 +02:00
[ atT , innov , measurement_error , updated_variables , ys , trend_coeff , aK , T , R , P , PK , decomp , Trend , state_uncertainty , oo_ , bayestopt_ ] = occbin . DSGE_smoother ( xparam1 , gend , transpose ( data ) , data_index , missing_value , M_ , oo_ , options_ , bayestopt_ , estim_params_ , dataset_ , dataset_info ) ;
2023-02-06 14:58:42 +01:00
if oo_ . occbin . smoother . error_flag ( 1 ) == 0
2022-11-14 17:51:26 +01:00
[ oo_ ] = store_smoother_results ( M_ , oo_ , options_ , bayestopt_ , dataset_ , dataset_info , atT , innov , measurement_error , updated_variables , ys , trend_coeff , aK , P , PK , decomp , Trend , state_uncertainty ) ;
2023-02-06 14:58:42 +01:00
else
fprintf ( ' \nOccbin: smoother did not succeed. No results will be written to oo_.\n' )
2022-11-14 17:51:26 +01:00
end
2021-05-17 21:24:25 +02:00
else
2023-09-15 13:40:10 +02:00
[ atT , innov , measurement_error , updated_variables , ys , trend_coeff , aK , T , R , P , PK , decomp , Trend , state_uncertainty , oo_ , bayestopt_ ] = DsgeSmoother ( xparam1 , gend , transpose ( data ) , data_index , missing_value , M_ , oo_ , options_ , bayestopt_ , estim_params_ ) ;
2022-11-14 17:51:26 +01:00
[ oo_ ] = store_smoother_results ( M_ , oo_ , options_ , bayestopt_ , dataset_ , dataset_info , atT , innov , measurement_error , updated_variables , ys , trend_coeff , aK , P , PK , decomp , Trend , state_uncertainty ) ;
2021-05-17 21:24:25 +02:00
end
end
2021-01-17 16:39:10 +01:00
if options_ . forecast > 0
oo_ . forecast = dyn_forecast ( var_list_ , M_ , options_ , oo_ , ' smoother' , dataset_info ) ;
end
end
2021-01-17 20:06:49 +01:00
%reset qz_criterium
options_ . qz_criterium = qz_criterium_old ;
return
2021-01-17 16:39:10 +01:00
else %allow to continue, e.g. with MCMC_jumping_covariance
if options_ . smoother
error ( ' Estimation:: Particle Smoothers are not yet implemented.' )
2021-01-10 17:12:59 +01:00
end
2009-12-16 18:17:34 +01:00
end
end
2015-11-28 17:36:51 +01:00
%% Estimation of the posterior mode or likelihood mode
2023-09-14 15:40:13 +02:00
2011-01-28 14:01:57 +01:00
if ~ isequal ( options_ . mode_compute , 0 ) && ~ options_ . mh_posterior_mode_estimation
2023-09-14 15:40:13 +02:00
optimizer_vec = [ options_ . mode_compute ; num2cell ( options_ . additional_optimizer_steps ) ] ;
for optim_iter = 1 : length ( optimizer_vec )
current_optimizer = optimizer_vec { optim_iter } ;
2017-05-16 15:10:20 +02:00
2023-09-27 08:06:37 +02:00
[ xparam1 , fval , ~ , hh , options_ , Scale , new_rat_hess_info ] = dynare_minimize_objective ( objective_function , xparam1 , current_optimizer , options_ , [ bounds . lb bounds . ub ] , bayestopt_ . name , bayestopt_ , hh , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
fprintf ( ' \nFinal value of minus the log posterior (or likelihood):%f \n' , fval ) ;
2014-12-04 09:18:33 +01:00
2023-09-14 15:40:13 +02:00
if isnumeric ( current_optimizer )
if current_optimizer == 5
2023-09-27 08:06:37 +02:00
newratflag = new_rat_hess_info . newratflag ;
new_rat_hess_info = new_rat_hess_info . new_rat_hess_info ;
2023-09-14 15:40:13 +02:00
elseif current_optimizer == 6 %save scaling factor
2023-09-27 08:06:37 +02:00
save ( [ M_ . dname filesep ' Output' filesep M_ . fname ' _optimal_mh_scale_parameter.mat' ] , ' Scale' ) ;
options_ . mh_jscale = Scale ;
bayestopt_ . jscale ( : ) = options_ . mh_jscale ;
end
2023-09-14 15:40:13 +02:00
end
if ~ isnumeric ( current_optimizer ) || ~ isequal ( current_optimizer , 6 ) %always already computes covariance matrix
2023-09-27 08:06:37 +02:00
if options_ . cova_compute == 1 %user did not request covariance not to be computed
if options_ . analytic_derivation && strcmp ( func2str ( objective_function ) , ' dsge_likelihood' )
ana_deriv_old = options_ . analytic_derivation ;
options_ . analytic_derivation = 2 ;
[ ~ , ~ , ~ , ~ , hh ] = feval ( objective_function , xparam1 , ...
dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
options_ . analytic_derivation = ana_deriv_old ;
2023-09-14 15:40:13 +02:00
elseif ~ isnumeric ( current_optimizer ) || ~ ( isequal ( current_optimizer , 5 ) && newratflag ~= 1 && strcmp ( func2str ( objective_function ) , ' dsge_likelihood' ) )
2023-09-27 08:06:37 +02:00
% enter here if i) not mode_compute_5, ii) if mode_compute_5 and newratflag==1;
% with flag==0 or 2 and dsge_likelihood, we force to use
% the hessian from outer product gradient of optimizer 5 below
if options_ . hessian . use_penalized_objective
penalized_objective_function = str2func ( ' penalty_objective_function' ) ;
hh = hessian ( penalized_objective_function , xparam1 , options_ . gstep , objective_function , fval , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
else
hh = hessian ( objective_function , xparam1 , options_ . gstep , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
end
hh = reshape ( hh , nx , nx ) ;
2023-09-14 15:40:13 +02:00
elseif isnumeric ( current_optimizer ) && isequal ( current_optimizer , 5 )
2023-09-27 08:06:37 +02:00
% other numerical hessian options available with optimizer
% 5 and dsge_likelihood
%
% if newratflag == 0
% compute outer product gradient of optimizer 5
%
% if newratflag == 2
% compute 'mixed' outer product gradient of optimizer 5
% with diagonal elements computed with numerical second order derivatives
%
% uses univariate filters, so to get max # of available
% densities for outer product gradient
kalman_algo0 = options_ . kalman_algo ;
compute_hessian = 1 ;
if ~ ( ( options_ . kalman_algo == 2 ) || ( options_ . kalman_algo == 4 ) )
options_ . kalman_algo = 2 ;
if options_ . lik_init == 3
options_ . kalman_algo = 4 ;
end
elseif newratflag == 0 % hh already contains outer product gradient with univariate filter
compute_hessian = 0 ;
2023-09-14 15:40:13 +02:00
end
2023-09-27 08:06:37 +02:00
if compute_hessian
crit = options_ . newrat . tolerance . f ;
newratflag = newratflag > 0 ;
hh = reshape ( mr_hessian ( xparam1 , objective_function , fval , newratflag , crit , new_rat_hess_info , [ bounds . lb bounds . ub ] , bayestopt_ . p2 , 0 , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) , nx , nx ) ;
end
options_ . kalman_algo = kalman_algo0 ;
2023-09-14 20:17:01 +02:00
end
2012-04-27 15:57:58 +02:00
end
2009-12-16 18:17:34 +01:00
end
2023-09-27 08:06:37 +02:00
parameter_names = bayestopt_ . name ;
2011-02-04 17:17:48 +01:00
end
2023-09-14 15:40:13 +02:00
if options_ . cova_compute || current_optimizer == 5 || current_optimizer == 6
2021-07-22 17:46:08 +02:00
save ( [ M_ . dname filesep ' Output' filesep M_ . fname ' _mode.mat' ] , ' xparam1' , ' hh' , ' parameter_names' , ' fval' ) ;
2011-02-04 17:17:48 +01:00
else
2021-07-22 17:46:08 +02:00
save ( [ M_ . dname filesep ' Output' filesep M_ . fname ' _mode.mat' ] , ' xparam1' , ' parameter_names' , ' fval' ) ;
2011-02-04 17:17:48 +01:00
end
2009-12-16 18:17:34 +01:00
end
2011-05-13 12:32:23 +02:00
if ~ options_ . mh_posterior_mode_estimation && options_ . cova_compute
2023-09-01 15:59:20 +02:00
check_hessian_at_the_mode ( hh , xparam1 , M_ , estim_params_ , options_ , bounds ) ;
2009-12-16 18:17:34 +01:00
end
2023-09-20 11:31:06 +02:00
%% create mode_check_plots
2019-03-19 14:26:16 +01:00
if options_ . mode_check . status && ~ options_ . mh_posterior_mode_estimation
2014-12-04 09:18:33 +01:00
ana_deriv_old = options_ . analytic_derivation ;
2012-07-05 10:22:36 +02:00
options_ . analytic_derivation = 0 ;
2023-09-15 10:06:49 +02:00
mode_check ( objective_function , xparam1 , hh , options_ , M_ , estim_params_ , bayestopt_ , bounds , false , ...
2023-09-27 08:06:37 +02:00
dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
2014-12-04 09:18:33 +01:00
options_ . analytic_derivation = ana_deriv_old ;
2009-12-16 18:17:34 +01:00
end
2016-06-13 11:03:41 +02:00
oo_ . posterior . optimization . mode = [ ] ;
2013-03-17 22:49:28 +01:00
oo_ . posterior . optimization . Variance = [ ] ;
2016-07-20 17:37:17 +02:00
oo_ . posterior . optimization . log_density = [ ] ;
2015-09-25 12:57:44 +02:00
invhess = [ ] ;
2011-05-13 14:34:53 +02:00
if ~ options_ . mh_posterior_mode_estimation
2016-06-13 11:03:41 +02:00
oo_ . posterior . optimization . mode = xparam1 ;
2016-07-20 17:37:17 +02:00
if exist ( ' fval' , ' var' )
oo_ . posterior . optimization . log_density = - fval ;
end
2011-05-13 14:34:53 +02:00
if options_ . cova_compute
2016-09-05 12:16:07 +02:00
hsd = sqrt ( diag ( hh ) ) ;
invhess = inv ( hh ./ ( hsd * hsd ' ) ) ./ ( hsd * hsd ' ) ;
2011-05-13 14:34:53 +02:00
stdh = sqrt ( diag ( invhess ) ) ;
2013-03-17 22:49:28 +01:00
oo_ . posterior . optimization . Variance = invhess ;
2011-05-13 14:34:53 +02:00
end
2009-12-16 18:17:34 +01:00
else
2010-09-01 22:15:47 +02:00
variances = bayestopt_ . p2 .* bayestopt_ . p2 ;
idInf = isinf ( variances ) ;
variances ( idInf ) = 1 ;
invhess = options_ . mh_posterior_mode_estimation * diag ( variances ) ;
xparam1 = bayestopt_ . p5 ;
idNaN = isnan ( xparam1 ) ;
xparam1 ( idNaN ) = bayestopt_ . p1 ( idNaN ) ;
2015-09-25 12:42:17 +02:00
outside_bound_pars = find ( xparam1 < bounds . lb | xparam1 > bounds . ub ) ;
xparam1 ( outside_bound_pars ) = bayestopt_ . p1 ( outside_bound_pars ) ;
2009-12-16 18:17:34 +01:00
end
2011-05-13 12:32:23 +02:00
if ~ options_ . cova_compute
stdh = NaN ( length ( xparam1 ) , 1 ) ;
end
2009-12-16 18:17:34 +01:00
2021-05-11 11:40:51 +02:00
if options_ . particle . status && isfield ( options_ . particle , ' posterior_sampler' )
if strcmpi ( options_ . particle . posterior_sampler , ' Herbst_Schorfheide' )
2023-09-27 08:06:37 +02:00
Herbst_Schorfheide_sampler ( objective_function , xparam1 , bounds , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state )
2021-05-11 11:40:51 +02:00
elseif strcmpi ( options_ . particle . posterior_sampler , ' DSMH' )
2023-09-27 08:06:37 +02:00
DSMH_sampler ( objective_function , xparam1 , bounds , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state )
2021-05-11 11:40:51 +02:00
end
end
2023-09-27 08:06:37 +02:00
2011-02-10 15:54:23 +01:00
if any ( bayestopt_ . pshape > 0 ) && ~ options_ . mh_posterior_mode_estimation
2013-05-21 16:38:17 +02:00
% display results table and store parameter estimates and standard errors in results
2020-06-26 12:06:32 +02:00
oo_ = display_estimation_results_table ( xparam1 , stdh , M_ , options_ , estim_params_ , bayestopt_ , oo_ , prior_dist_names , ' Posterior' , ' posterior' ) ;
2013-05-21 16:38:17 +02:00
% Laplace approximation to the marginal log density:
2011-05-13 14:55:10 +02:00
if options_ . cova_compute
estim_params_nbr = size ( xparam1 , 1 ) ;
2019-11-21 11:32:13 +01:00
if ispd ( invhess )
log_det_invhess = log ( det ( invhess ./ ( stdh * stdh ' ) ) ) + 2 * sum ( log ( stdh ) ) ;
2023-09-27 08:06:37 +02:00
likelihood = feval ( objective_function , xparam1 , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
2019-11-21 11:32:13 +01:00
oo_ . MarginalDensity . LaplaceApproximation = . 5 * estim_params_nbr * log ( 2 * pi ) + . 5 * log_det_invhess - likelihood ;
else
oo_ . MarginalDensity . LaplaceApproximation = NaN ;
end
2013-07-10 16:16:32 +02:00
skipline ( )
2011-09-22 11:17:31 +02:00
disp ( sprintf ( ' Log data density [Laplace approximation] is %f.' , oo_ . MarginalDensity . LaplaceApproximation ) )
2013-07-10 16:16:32 +02:00
skipline ( )
2009-12-16 18:17:34 +01:00
end
2016-06-13 11:40:41 +02:00
if options_ . dsge_var
2018-11-13 17:58:42 +01:00
[ ~ , ~ , ~ , ~ , ~ , ~ , ~ , oo_ . dsge_var . posterior_mode . PHI_tilde , oo_ . dsge_var . posterior_mode . SIGMA_u_tilde , oo_ . dsge_var . posterior_mode . iXX , oo_ . dsge_var . posterior_mode . prior ] = ...
2023-09-27 08:06:37 +02:00
feval ( objective_function , xparam1 , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
2016-06-13 11:40:41 +02:00
end
2012-03-15 15:32:31 +01:00
elseif ~ any ( bayestopt_ . pshape > 0 ) && ~ options_ . mh_posterior_mode_estimation
2020-06-26 12:06:32 +02:00
oo_ = display_estimation_results_table ( xparam1 , stdh , M_ , options_ , estim_params_ , bayestopt_ , oo_ , prior_dist_names , ' Maximum Likelihood' , ' mle' ) ;
2009-12-16 18:17:34 +01:00
end
if np > 0
pindx = estim_params_ . param_vals ( : , 1 ) ;
2021-07-22 17:46:08 +02:00
save ( [ M_ . dname filesep ' Output' filesep M_ . fname ' _params.mat' ] , ' pindx' ) ;
2009-12-16 18:17:34 +01:00
end
2023-09-01 16:13:23 +02:00
invhess = set_mcmc_jumping_covariance ( invhess , nx , options_ . MCMC_jumping_covariance , bayestopt_ , ' dynare_estimation_1' ) ;
2016-12-27 12:07:22 +01:00
2011-02-10 15:54:23 +01:00
if ( any ( bayestopt_ . pshape > 0 ) && options_ . mh_replic ) || ...
( any ( bayestopt_ . pshape > 0 ) && options_ . load_mh_file ) %% not ML estimation
2023-09-01 16:10:52 +02:00
%reset bounds as lb and ub must only be operational during mode-finding
bounds = set_mcmc_prior_bounds ( xparam1 , bayestopt_ , options_ , ' dynare_estimation_1' ) ;
2018-05-16 16:15:42 +02:00
% Tunes the jumping distribution's scale parameter
if options_ . mh_tune_jscale . status
2020-03-10 14:13:49 +01:00
if strcmp ( options_ . posterior_sampler_options . posterior_sampling_method , ' random_walk_metropolis_hastings' )
2023-09-01 23:02:21 +02:00
options_ . mh_jscale = tune_mcmc_mh_jscale_wrapper ( invhess , options_ , M_ , objective_function , xparam1 , bounds , ...
2023-09-27 08:06:37 +02:00
dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , bounds , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
2019-12-20 16:28:06 +01:00
bayestopt_ . jscale ( : ) = options_ . mh_jscale ;
2023-09-01 23:02:21 +02:00
fprintf ( ' mh_jscale has been set equal to %s\n' , num2str ( options_ . mh_jscale ) ) ;
2018-05-16 16:15:42 +02:00
else
warning ( ' mh_tune_jscale is only available with Random Walk Metropolis Hastings!' )
end
end
2009-12-16 18:17:34 +01:00
% runs MCMC
2017-01-17 19:23:27 +01:00
if options_ . mh_replic || options_ . load_mh_file
2016-05-13 21:35:59 +02:00
posterior_sampler_options = options_ . posterior_sampler_options . current_options ;
2015-09-25 12:57:44 +02:00
posterior_sampler_options . invhess = invhess ;
2023-09-01 15:48:28 +02:00
[ posterior_sampler_options , options_ , bayestopt_ ] = check_posterior_sampler_options ( posterior_sampler_options , M_ . fname , M_ . dname , options_ , bounds , bayestopt_ ) ;
2016-05-13 21:35:59 +02:00
% store current options in global
options_ . posterior_sampler_options . current_options = posterior_sampler_options ;
2017-01-17 19:23:27 +01:00
if options_ . mh_replic
ana_deriv_old = options_ . analytic_derivation ;
options_ . analytic_derivation = 0 ;
2023-09-13 18:09:38 +02:00
posterior_sampler ( objective_function , posterior_sampler_options . proposal_distribution , xparam1 , posterior_sampler_options , bounds , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , oo_ , dispString ) ;
2017-01-17 19:23:27 +01:00
options_ . analytic_derivation = ana_deriv_old ;
end
2009-12-16 18:17:34 +01:00
end
2015-09-25 12:39:05 +02:00
%% Here I discard first mh_drop percent of the draws:
2023-09-13 18:09:38 +02:00
CutSample ( M_ , options_ , dispString ) ;
2010-09-01 22:15:47 +02:00
if options_ . mh_posterior_mode_estimation
2023-09-01 15:48:28 +02:00
[ ~ , ~ , posterior_mode , ~ ] = compute_mh_covariance_matrix ( bayestopt_ , M_ . fname , M_ . dname ) ;
2021-09-21 17:31:39 +02:00
oo_ = fill_mh_mode ( posterior_mode ' , NaN ( length ( posterior_mode ) , 1 ) , M_ , options_ , estim_params_ , bayestopt_ , oo_ , ' posterior' ) ;
2016-06-16 22:40:54 +02:00
%reset qz_criterium
options_ . qz_criterium = qz_criterium_old ;
2010-09-01 22:15:47 +02:00
return
2010-02-11 14:26:30 +01:00
else
2016-12-17 16:05:17 +01:00
%get stored results if required
if options_ . load_mh_file && options_ . load_results_after_load_mh
2021-07-22 17:46:08 +02:00
oo_load_mh = load ( [ M_ . dname filesep ' Output' filesep M_ . fname ' _results' ] , ' oo_' ) ;
2016-12-17 16:05:17 +01:00
end
2017-05-16 15:10:20 +02:00
if ~ options_ . nodiagnostic
2016-12-17 16:05:17 +01:00
if ( options_ . mh_replic > 0 || ( options_ . load_mh_file && ~ options_ . load_results_after_load_mh ) )
2023-09-08 09:44:43 +02:00
oo_ = mcmc_diagnostics ( options_ , estim_params_ , M_ , oo_ ) ;
2016-12-17 16:05:17 +01:00
elseif options_ . load_mh_file && options_ . load_results_after_load_mh
if isfield ( oo_load_mh . oo_ , ' convergence' )
oo_ . convergence = oo_load_mh . oo_ . convergence ;
end
end
2009-12-16 18:17:34 +01:00
end
2010-09-01 22:15:47 +02:00
%% Estimation of the marginal density from the Mh draws:
2016-12-17 16:05:17 +01:00
if options_ . mh_replic || ( options_ . load_mh_file && ~ options_ . load_results_after_load_mh )
2023-09-20 11:31:06 +02:00
[ ~ , oo_ ] = marginal_density ( M_ , options_ , estim_params_ , oo_ , bayestopt_ ) ;
2013-11-03 11:40:36 +01:00
% Store posterior statistics by parameter name
2020-06-26 12:06:32 +02:00
oo_ = GetPosteriorParametersStatistics ( estim_params_ , M_ , options_ , bayestopt_ , oo_ , prior_dist_names ) ;
2012-11-29 14:26:39 +01:00
if ~ options_ . nograph
oo_ = PlotPosteriorDistributions ( estim_params_ , M_ , options_ , bayestopt_ , oo_ ) ;
end
2013-11-03 11:40:36 +01:00
% Store posterior mean in a vector and posterior variance in
% a matrix
2013-03-17 22:49:28 +01:00
[ oo_ . posterior . metropolis . mean , oo_ . posterior . metropolis . Variance ] ...
2012-04-21 21:28:03 +02:00
= GetPosteriorMeanVariance ( M_ , options_ . mh_drop ) ;
2016-12-17 16:05:17 +01:00
elseif options_ . load_mh_file && options_ . load_results_after_load_mh
2017-05-16 15:10:20 +02:00
%% load fields from previous MCMC run stored in results-file
2016-12-17 16:05:17 +01:00
field_names = { ' posterior_mode' , ' posterior_std_at_mode' , ...% fields set by marginal_density
2023-09-27 08:06:37 +02:00
' posterior_mean' , ' posterior_hpdinf' , ' posterior_hpdsup' , ' posterior_median' , ' posterior_variance' , ' posterior_std' , ' posterior_deciles' , ' posterior_density' , ...% fields set by GetPosteriorParametersStatistics
' prior_density' , ...%fields set by PlotPosteriorDistributions
} ;
2016-12-17 16:05:17 +01:00
for field_iter = 1 : size ( field_names , 2 )
if isfield ( oo_load_mh . oo_ , field_names { 1 , field_iter } )
oo_ . ( field_names { 1 , field_iter } ) = oo_load_mh . oo_ . ( field_names { 1 , field_iter } ) ;
end
2017-05-16 15:10:20 +02:00
end
2016-12-17 16:05:17 +01:00
% field set by marginal_density
if isfield ( oo_load_mh . oo_ , ' MarginalDensity' ) && isfield ( oo_load_mh . oo_ . MarginalDensity , ' ModifiedHarmonicMean' )
oo_ . MarginalDensity . ModifiedHarmonicMean = oo_load_mh . oo_ . MarginalDensity . ModifiedHarmonicMean ;
2017-05-16 15:10:20 +02:00
end
2016-12-17 16:05:17 +01:00
% field set by GetPosteriorMeanVariance
if isfield ( oo_load_mh . oo_ , ' posterior' ) && isfield ( oo_load_mh . oo_ . posterior , ' metropolis' )
oo_ . posterior . metropolis = oo_load_mh . oo_ . posterior . metropolis ;
end
2009-12-16 18:17:34 +01:00
end
2018-11-13 17:58:42 +01:00
[ error_flag , ~ , options_ ] = metropolis_draw ( 1 , options_ , estim_params_ , M_ ) ;
2020-01-23 17:55:55 +01:00
if ~ ( ~ isempty ( options_ . sub_draws ) && options_ . sub_draws == 0 )
if options_ . bayesian_irf
if error_flag
2023-09-01 21:42:51 +02:00
error ( ' %s: I cannot compute the posterior IRFs!' , dispString )
2020-01-23 17:55:55 +01:00
end
2023-09-14 20:17:01 +02:00
oo_ = PosteriorIRF ( ' posterior' , options_ , estim_params_ , oo_ , M_ , bayestopt_ , dataset_ , dataset_info , dispString ) ;
2013-12-18 16:39:41 +01:00
end
2020-01-23 17:55:55 +01:00
if options_ . moments_varendo
if error_flag
2023-09-01 21:42:51 +02:00
error ( ' %s: I cannot compute the posterior moments for the endogenous variables!' , dispString )
2020-01-23 17:55:55 +01:00
end
2021-01-25 15:55:10 +01:00
if options_ . load_mh_file && options_ . mh_replic == 0 %user wants to recompute results
2023-09-27 08:06:37 +02:00
[ MetropolisFolder , info ] = CheckPath ( ' metropolis' , M_ . dname ) ;
if ~ info
generic_post_data_file_name = { ' Posterior2ndOrderMoments' , ' decomposition' , ' PosteriorVarianceDecomposition' , ' correlation' , ' PosteriorCorrelations' , ' conditional decomposition' , ' PosteriorConditionalVarianceDecomposition' } ;
for ii = 1 : length ( generic_post_data_file_name )
delete_stale_file ( [ MetropolisFolder filesep M_ . fname ' _' generic_post_data_file_name { 1 , ii } ' *' ] ) ;
end
% restore compatibility for loading pre-4.6.2 runs where estim_params_ was not saved; see 6e06acc7 and !1944
NumberOfDrawsFiles = length ( dir ( [ M_ . dname ' /metropolis/' M_ . fname ' _posterior_draws*' ] ) ) ;
if NumberOfDrawsFiles > 0
temp = load ( [ M_ . dname ' /metropolis/' M_ . fname ' _posterior_draws1' ] ) ;
if ~ isfield ( temp , ' estim_params_' )
for file_iter = 1 : NumberOfDrawsFiles
save ( [ M_ . dname ' /metropolis/' M_ . fname ' _posterior_draws' num2str ( file_iter ) ] , ' estim_params_' , ' -append' )
end
end
end
end
2021-01-25 15:55:10 +01:00
end
2023-09-16 10:05:46 +02:00
oo_ = compute_moments_varendo ( ' posterior' , options_ , M_ , oo_ , estim_params_ , var_list_ ) ;
2013-12-18 16:39:41 +01:00
end
2020-01-23 17:55:55 +01:00
if options_ . smoother || ~ isempty ( options_ . filter_step_ahead ) || options_ . forecast
if error_flag
2023-09-01 21:42:51 +02:00
error ( ' %s: I cannot compute the posterior statistics!' , dispString )
2020-01-23 17:55:55 +01:00
end
2021-01-17 16:39:10 +01:00
if options_ . order == 1 && ~ options_ . particle . status
2023-09-14 20:17:01 +02:00
oo_ = prior_posterior_statistics ( ' posterior' , dataset_ , dataset_info , M_ , oo_ , options_ , estim_params_ , bayestopt_ , dispString ) ; %get smoothed and filtered objects and forecasts
2021-01-17 16:39:10 +01:00
else
2023-09-01 21:42:51 +02:00
error ( ' %s: Particle Smoothers are not yet implemented.' , dispString )
2021-01-17 16:39:10 +01:00
end
2013-12-18 16:39:41 +01:00
end
2020-01-23 17:55:55 +01:00
else
2023-09-01 21:42:51 +02:00
fprintf ( ' %s: sub_draws was set to 0. Skipping posterior computations.' , dispString ) ;
2010-09-01 22:15:47 +02:00
end
2017-10-03 15:32:17 +02:00
xparam1 = get_posterior_parameters ( ' mean' , M_ , estim_params_ , oo_ , options_ ) ;
2014-10-15 09:49:07 +02:00
M_ = set_all_parameters ( xparam1 , estim_params_ , M_ ) ;
2010-09-13 21:34:15 +02:00
end
2023-09-20 11:31:06 +02:00
else
M_ = set_all_parameters ( xparam1 , estim_params_ , M_ ) ; %set to posterior mode
2010-09-13 21:34:15 +02:00
end
2010-09-01 22:15:47 +02:00
2012-06-06 17:04:27 +02:00
if options_ . particle . status
2016-06-16 22:40:54 +02:00
%reset qz_criterium
options_ . qz_criterium = qz_criterium_old ;
2012-06-06 17:04:27 +02:00
return
end
2023-09-20 11:31:06 +02:00
%Run and store classical smoother if needed
2017-05-16 12:42:01 +02:00
if ( ~ ( ( any ( bayestopt_ . pshape > 0 ) && options_ . mh_replic ) || ( any ( bayestopt_ . pshape > 0 ) && options_ . load_mh_file ) ) ...
2023-09-27 08:06:37 +02:00
|| ~ options_ . smoother ) && ~ options_ . partial_information % to be fixed
2022-07-26 14:36:25 +02:00
%% ML estimation, or posterior mode without Metropolis-Hastings or Metropolis without Bayesian smoothed variables
2023-09-20 11:31:06 +02:00
oo_ = save_display_classical_smoother_results ( xparam1 , M_ , oo_ , options_ , bayestopt_ , dataset_ , dataset_info , estim_params_ ) ;
2010-09-01 22:15:47 +02:00
end
2011-09-17 15:38:49 +02:00
if options_ . forecast > 0 && options_ . mh_replic == 0 && ~ options_ . load_mh_file
2015-03-02 10:45:12 +01:00
oo_ . forecast = dyn_forecast ( var_list_ , M_ , options_ , oo_ , ' smoother' , dataset_info ) ;
2009-12-16 18:17:34 +01:00
end
2016-06-16 22:40:54 +02:00
%reset qz_criterium
options_ . qz_criterium = qz_criterium_old ;
2017-03-16 15:45:08 +01:00
if reset_options_related_to_estimation
options_ . mode_compute = mode_compute_o ;
options_ . mh_replic = mh_replic_o ;
end
2017-03-20 20:29:19 +01:00
if first_obs_nan_indicator
options_ . first_obs = NaN ;
2019-03-19 14:26:16 +01:00
end