2023-10-02 11:12:31 +02:00
function oo_ = initial_estimation_checks ( objective_function,xparam1,dataset_,dataset_info,M_,estim_params_,options_,bayestopt_,BoundsInfo,oo_)
% function oo_ = initial_estimation_checks(objective_function,xparam1,dataset_,dataset_info,M_,estim_params_,options_,bayestopt_,BoundsInfo,oo_)
2008-01-21 13:17:46 +01:00
% Checks data (complex values, ML evaluation, initial values, BK conditions,..)
2011-09-19 16:38:38 +02:00
%
2008-01-21 13:17:46 +01:00
% INPUTS
2013-11-06 08:26:22 +01:00
% objective_function [function handle] of the objective function
2023-10-02 11:12:31 +02:00
% xparam1 [vector] of parameters to be estimated
% dataset_ [dseries] object storing the dataset
% dataset_info [structure] storing informations about the sample.
2023-10-24 22:21:15 +02:00
% M_ [structure] describing the model
2023-10-02 11:12:31 +02:00
% estim_params_ [structure] characterizing parameters to be estimated
% options_ [structure] describing the options
% bayestopt_ [structure] describing the priors
2016-03-25 20:20:28 +01:00
% BoundsInfo [structure] containing prior bounds
2023-10-02 11:12:31 +02:00
% oo_ [structure] storing the results
2011-09-19 16:38:38 +02:00
%
2008-01-21 13:17:46 +01:00
% OUTPUTS
2023-10-02 11:12:31 +02:00
% oo_ [structure] storing the results
2011-09-19 16:38:38 +02:00
%
2008-01-21 13:17:46 +01:00
% SPECIAL REQUIREMENTS
% none
2023-03-24 12:29:42 +01:00
% Copyright © 2003-2023 Dynare Team
2008-08-01 14:40:33 +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/>.
2008-01-21 13:17:46 +01:00
2015-10-11 10:49:15 +02:00
%get maximum number of simultaneously observed variables for stochastic
%singularity check
2023-10-02 11:12:31 +02:00
maximum_number_non_missing_observations = max ( sum ( ~ isnan ( dataset_ . data ( 2 : end , : ) ) , 2 ) ) ;
init_number_non_missing_observations = sum ( ~ isnan ( dataset_ . data ( 1 , : ) ) , 2 ) ;
2015-10-11 10:49:15 +02:00
2023-10-02 11:12:31 +02:00
if options_ . heteroskedastic_filter
if options_ . order > 1
2021-05-02 17:07:12 +02:00
error ( ' initial_estimation_checks:: heteroskedastic shocks are only supported with the Kalman filter/smoother' )
end
2023-10-02 11:12:31 +02:00
observations_by_period = sum ( ~ isnan ( dataset_ . data ) , 2 ) ;
base_shocks = find ( diag ( M_ . Sigma_e ) ) ;
zero_shocks = ~ ismember ( 1 : M_ . exo_nbr , base_shocks ) ;
2021-05-02 17:07:12 +02:00
non_zero_shocks_by_period = repmat ( length ( base_shocks ) , size ( observations_by_period ) ) ;
% check periods for which base shocks are scaled to zero
2023-10-02 11:12:31 +02:00
non_zero_shocks_by_period = non_zero_shocks_by_period - sum ( M_ . heteroskedastic_shocks . Qscale ( base_shocks , 1 : options_ . nobs ) == 0 , 1 ) ' ;
2021-05-02 17:07:12 +02:00
% check periods for which base shocks are set to zero
2023-10-02 11:12:31 +02:00
non_zero_shocks_by_period = non_zero_shocks_by_period - sum ( M_ . heteroskedastic_shocks . Qvalue ( base_shocks , 1 : options_ . nobs ) == 0 , 1 ) ' ;
2021-05-02 17:07:12 +02:00
% check periods for which other shocks are set to a positive number
2023-10-02 11:12:31 +02:00
non_zero_shocks_by_period = non_zero_shocks_by_period + sum ( M_ . heteroskedastic_shocks . Qvalue ( zero_shocks , 1 : options_ . nobs ) > 0 , 1 ) ' ;
2021-05-02 17:07:12 +02:00
end
2023-10-02 11:12:31 +02:00
if options_ . order > 1
if any ( any ( isnan ( dataset_ . data ) ) )
2020-01-10 19:08:51 +01:00
error ( ' initial_estimation_checks:: particle filtering does not support missing observations' )
end
2023-10-02 11:12:31 +02:00
if options_ . prefilter == 1
2020-01-10 19:08:51 +01:00
error ( ' initial_estimation_checks:: particle filtering does not support the prefilter option' )
end
2023-10-02 11:12:31 +02:00
if bayestopt_ . with_trend
2020-01-10 19:08:51 +01:00
error ( ' initial_estimation_checks:: particle filtering does not support trends' )
end
2023-10-02 11:12:31 +02:00
if options_ . order > 3 && options_ . particle . pruning == 1
2022-08-30 14:16:14 +02:00
error ( ' initial_estimation_checks:: the particle filter with order>3 does not support pruning' )
2021-01-26 09:26:05 +01:00
end
2023-10-02 11:12:31 +02:00
if options_ . particle . pruning ~= options_ . pruning
2021-12-27 13:03:47 +01:00
warning ( ' initial_estimation_checks:: the pruning settings differ between the particle filter and the one used for IRFs/simulations. Make sure this is intended.' )
2021-01-26 09:26:05 +01:00
end
end
2023-10-02 11:12:31 +02:00
if options_ . occbin . likelihood . status || options_ . occbin . smoother . status
if options_ . prefilter
2022-03-29 12:16:48 +02:00
error ( ' initial_estimation_checks:: Occbin is incompatible with the prefilter option due to the sample mean generally not corresponding to the steady state with an occasionally binding constraint.' )
end
2023-10-02 11:12:31 +02:00
if ~ options_ . occbin . likelihood . inversion_filter && ( options_ . kalman_algo == 2 || options_ . kalman_algo == 4 )
2022-05-31 17:36:48 +02:00
error ( ' initial_estimation_checks:: Occbin is incompatible with the selected univariate Kalman filter.' )
end
2023-10-02 11:12:31 +02:00
if options_ . fast_kalman_filter
2022-05-31 17:36:48 +02:00
error ( ' initial_estimation_checks:: Occbin is incompatible with the fast Kalman filter.' )
end
2022-03-29 12:16:48 +02:00
end
2023-10-02 11:12:31 +02:00
if ( options_ . occbin . likelihood . status && options_ . occbin . likelihood . inversion_filter ) || ( options_ . occbin . smoother . status && options_ . occbin . smoother . inversion_filter )
err_index = find ( diag ( M_ . Sigma_e ) ~= 0 ) ;
if length ( err_index ) ~= length ( options_ . varobs )
2021-05-17 21:24:25 +02:00
fprintf ( ' initial_estimation_checks:: The IVF requires exactly as many shocks as observables.' )
end
2023-10-02 11:12:31 +02:00
var_index = find ( any ( isnan ( dataset_ . data ) ) ) ;
2021-05-17 21:24:25 +02:00
if ~ isempty ( var_index )
fprintf ( ' initial_estimation_checks:: The IVF requires exactly as many shocks as observables.\n' )
fprintf ( ' initial_estimation_checks:: The data series %s contains NaN, I am therefore dropping shock %s for these time points.\n' , ...
2023-10-02 11:12:31 +02:00
options_ . varobs { var_index } , M_ . exo_names { options_ . occbin . likelihood . IVF_shock_observable_mapping ( var_index ) } )
2021-05-17 21:24:25 +02:00
end
end
2021-01-26 09:26:05 +01:00
2023-10-02 11:12:31 +02:00
if options_ . order > 1 || ( options_ . order == 1 && ~ ischar ( options_ . mode_compute ) && options_ . mode_compute == 11 )
if options_ . order == 1 && options_ . mode_compute == 11
2021-01-26 09:26:05 +01:00
disp_string = ' mode_compute=11' ;
else
disp_string = ' particle filtering' ;
end
2023-10-02 11:12:31 +02:00
if M_ . H == 0
2021-01-26 09:26:05 +01:00
error ( ' initial_estimation_checks:: %s requires measurement error on the observables' , disp_string )
2020-12-08 22:49:41 +01:00
else
2023-10-02 11:12:31 +02:00
if sum ( diag ( M_ . H ) > 0 ) < length ( options_ . varobs )
2021-01-26 09:26:05 +01:00
error ( ' initial_estimation_checks:: %s requires as many measurement errors as observed variables' , disp_string )
2021-01-16 11:21:14 +01:00
else
2023-10-02 11:12:31 +02:00
[ ~ , flag ] = chol ( M_ . H ) ;
2021-01-16 11:21:14 +01:00
if flag
error ( ' initial_estimation_checks:: the measurement error matrix must be positive definite' )
end
2020-12-08 22:49:41 +01:00
end
end
2015-10-20 15:49:07 +02:00
end
2023-10-02 11:12:31 +02:00
non_zero_ME = length ( estim_params_ . H_entries_to_check_for_positive_definiteness ) ;
2019-06-03 11:02:24 +02:00
2021-05-02 11:48:42 +02:00
print_init_check_warning = false ;
2023-10-02 11:12:31 +02:00
if maximum_number_non_missing_observations > M_ . exo_nbr + non_zero_ME
2012-06-14 14:49:10 +02:00
error ( [ ' initial_estimation_checks:: Estimation can' ' t take place because there are less declared shocks than observed variables!' ] )
end
2023-10-02 11:12:31 +02:00
if init_number_non_missing_observations > M_ . exo_nbr + non_zero_ME
if options_ . no_init_estimation_check_first_obs
2021-05-02 11:48:42 +02:00
print_init_check_warning = true ;
else
error ( [ ' initial_estimation_checks:: Estimation can' ' t take place because there are less declared shocks than observed variables in first period!' ] )
end
end
2014-06-16 17:41:59 +02:00
2023-10-02 11:12:31 +02:00
if options_ . heteroskedastic_filter
2021-05-02 17:07:12 +02:00
if any ( observations_by_period > ( non_zero_shocks_by_period + non_zero_ME ) )
error ( [ ' initial_estimation_checks:: Estimation can' ' t take place because too many shocks have been calibrated with a zero variance: Check heteroskedastic block and shocks calibration!' ] )
end
else
2023-10-02 11:12:31 +02:00
if maximum_number_non_missing_observations > length ( find ( diag ( M_ . Sigma_e ) ) ) + non_zero_ME
2021-05-02 17:07:12 +02:00
error ( [ ' initial_estimation_checks:: Estimation can' ' t take place because too many shocks have been calibrated with a zero variance!' ] )
end
2009-12-16 18:17:34 +01:00
end
2023-10-02 11:12:31 +02:00
if init_number_non_missing_observations > length ( find ( diag ( M_ . Sigma_e ) ) ) + non_zero_ME
if options_ . no_init_estimation_check_first_obs
2021-05-02 11:48:42 +02:00
print_init_check_warning = true ;
else
error ( [ ' initial_estimation_checks:: Estimation can' ' t take place because too many shocks have been calibrated with a zero variance in first period!' ] )
end
end
if print_init_check_warning
fprintf ( ' ESTIMATION_CHECKS: You decided to ignore test of stochastic singularity in first_obs.\n' ) ;
fprintf ( ' ESTIMATION_CHECKS: If this was not done on purpose (typically when observing a stock variable [capital] in first period, on top of its flow [investment]),\n' ) ;
fprintf ( ' ESTIMATION_CHECKS: it may lead to a crash or provide undesired/wrong results later on!\n' ) ;
end
2009-12-16 18:17:34 +01:00
2023-10-02 11:12:31 +02:00
if ( any ( bayestopt_ . pshape > 0 ) && options_ . mh_replic ) && options_ . mh_nblck < 1
2017-05-16 15:10:20 +02:00
error ( [ ' initial_estimation_checks:: Bayesian estimation cannot be conducted with mh_nblocks=0.' ] )
2016-03-06 21:19:17 +01:00
end
2023-09-01 16:27:54 +02:00
% check and display warnings if steady-state solves static model (except if diffuse_filter == 1) and if steady-state changes estimated parameters
2023-10-02 11:12:31 +02:00
[ oo_ . steady_state ] = check_steady_state_changes_parameters ( M_ , estim_params_ , oo_ , options_ , [ options_ . diffuse_filter == 0 options_ . diffuse_filter == 0 ] ) ;
2012-03-30 11:12:59 +02:00
2023-09-01 21:07:55 +02:00
% check and display warning if negative values of stderr or corr params are outside unit circle for Bayesian estimation
2023-10-02 11:12:31 +02:00
if any ( bayestopt_ . pshape )
check_prior_stderr_corr ( estim_params_ , bayestopt_ ) ;
2013-11-06 08:26:22 +01:00
end
2014-09-17 20:09:33 +02:00
% display warning if some parameters are still NaN
2023-10-02 11:12:31 +02:00
test_for_deep_parameters_calibration ( M_ ) ;
2014-09-17 20:09:33 +02:00
2023-10-02 11:12:31 +02:00
[ lnprior , ~ , ~ , info ] = priordens ( xparam1 , bayestopt_ . pshape , bayestopt_ . p6 , bayestopt_ . p7 , bayestopt_ . p3 , bayestopt_ . p4 ) ;
2018-11-14 15:02:15 +01:00
if any ( info )
2023-10-02 11:12:31 +02:00
fprintf ( ' The prior density evaluated at the initial values is Inf for the following parameters: %s\n' , bayestopt_ . name { info , 1 } )
2014-09-17 20:09:33 +02:00
error ( ' The initial value of the prior is -Inf' )
end
2016-08-10 12:41:20 +02:00
2023-10-02 11:12:31 +02:00
if isfield ( M_ , ' filter_initial_state' ) && ~ isempty ( M_ . filter_initial_state )
state_indices = oo_ . dr . order_var ( oo_ . dr . restrict_var_list ( bayestopt_ . mf0 ) ) ;
2021-01-18 17:46:19 +01:00
for ii = 1 : size ( state_indices , 1 )
2023-10-02 11:12:31 +02:00
if ~ isempty ( M_ . filter_initial_state { state_indices ( ii ) , 1 } )
2021-01-18 17:46:19 +01:00
try
2023-10-02 11:12:31 +02:00
evaluate_expression ( M_ . filter_initial_state { state_indices ( ii ) , 2 } , M_ , oo_ )
2021-01-18 17:46:19 +01:00
catch
2023-10-02 11:12:31 +02:00
fprintf ( ' Unable to evaluate the expression\n %s \nfor the filter_initial_state of variable %s\n' , M_ . filter_initial_state { state_indices ( ii ) , 2 } , M_ . endo_names ( state_indices ( ii ) , : ) )
2021-01-18 17:46:19 +01:00
end
end
end
end
2023-10-02 11:12:31 +02:00
if ~ isreal ( dataset_ . data )
2021-07-14 19:30:50 +02:00
error ( ' initial_estimation_checks: the data contains complex values.' )
end
2012-03-30 11:12:59 +02:00
% Evaluate the likelihood.
2023-10-02 11:12:31 +02:00
ana_deriv = options_ . analytic_derivation ;
options_ . analytic_derivation = 0 ;
if ~ isequal ( options_ . mode_compute , 11 ) || ...
( isequal ( options_ . mode_compute , 11 ) && isequal ( options_ . order , 1 ) )
2016-10-02 12:54:36 +02:00
%shut off potentially automatic switch to diffuse filter for the
%purpose of checking stochastic singularity
2023-10-02 11:12:31 +02:00
use_univariate_filters_if_singularity_is_detected_old = options_ . use_univariate_filters_if_singularity_is_detected ;
options_ . use_univariate_filters_if_singularity_is_detected = 0 ;
[ fval , info ] = feval ( objective_function , xparam1 , dataset_ , dataset_info , options_ , M_ , estim_params_ , bayestopt_ , BoundsInfo , oo_ . dr , oo_ . steady_state , oo_ . exo_steady_state , oo_ . exo_det_steady_state ) ;
2016-10-02 12:54:36 +02:00
if info ( 1 ) == 50
2016-11-04 12:28:01 +01:00
fprintf ( ' \ninitial_estimation_checks:: The forecast error variance in the multivariate Kalman filter became singular.\n' )
fprintf ( ' initial_estimation_checks:: This is often a sign of stochastic singularity, but can also sometimes happen by chance\n' )
fprintf ( ' initial_estimation_checks:: for a particular combination of parameters and data realizations.\n' )
fprintf ( ' initial_estimation_checks:: If you think the latter is the case, you should try with different initial values for the estimated parameters.\n' )
error ( ' initial_estimation_checks:: The forecast error variance in the multivariate Kalman filter became singular.' )
2016-10-02 12:54:36 +02:00
end
2021-05-27 21:04:35 +02:00
if info ( 1 ) == 201 || info ( 1 ) == 202
2023-10-02 11:12:31 +02:00
message = get_error_message ( info , options_ ) ;
2021-05-27 21:04:35 +02:00
error ( ' initial_estimation_checks:: %s.' , message )
2021-01-16 11:21:14 +01:00
end
2017-05-16 15:10:20 +02:00
%reset options
2023-10-02 11:12:31 +02:00
options_ . use_univariate_filters_if_singularity_is_detected = use_univariate_filters_if_singularity_is_detected_old ;
2017-05-16 15:10:20 +02:00
else
2016-06-01 15:51:13 +02:00
info = 0 ;
2014-08-29 15:36:07 +02:00
fval = 0 ;
end
2023-10-02 11:12:31 +02:00
if options_ . debug
oo_ . likelihood_at_initial_parameters = fval ;
2014-09-20 19:57:43 +02:00
end
2023-10-02 11:12:31 +02:00
options_ . analytic_derivation = ana_deriv ;
2011-10-12 21:46:50 +02:00
2023-10-02 11:12:31 +02:00
if options_ . mode_compute == 13
2021-01-22 14:48:18 +01:00
error ( ' Options mode_compute=13 is only compatible with quadratic objective functions' )
end
2012-06-13 15:47:01 +02:00
if isnan ( fval )
error ( ' The initial value of the likelihood is NaN' )
elseif imag ( fval )
error ( ' The initial value of the likelihood is complex' )
end
2005-02-18 20:54:39 +01:00
2009-12-16 18:17:34 +01:00
if info ( 1 ) > 0
2023-10-02 11:12:31 +02:00
if options_ . order > 1
[ eigenvalues_ ] = check ( M_ , options_ , oo_ ) ;
if any ( abs ( 1 - abs ( eigenvalues_ ) ) < abs ( options_ . qz_criterium - 1 ) )
2017-04-02 20:49:41 +02:00
error ( ' Your model has at least one unit root and you are using a nonlinear filter. Please set nonlinear_filter_initialization=3.' )
2017-03-20 17:30:41 +01:00
end
else
2017-05-16 15:10:20 +02:00
disp ( ' Error in computing likelihood for initial parameter values' )
2023-10-02 11:12:31 +02:00
print_info ( info , options_ . noprint , options_ )
2017-03-20 17:30:41 +01:00
end
2009-12-16 18:17:34 +01:00
end
2023-10-02 11:12:31 +02:00
if options_ . prefilter == 1
if ( ~ options_ . loglinear && any ( abs ( oo_ . steady_state ( bayestopt_ . mfys ) ) > 1e-9 ) ) || ( options_ . loglinear && any ( abs ( log ( oo_ . steady_state ( bayestopt_ . mfys ) ) ) > 1e-9 ) )
2014-06-15 12:26:36 +02:00
disp ( [ ' You are trying to estimate a model with a non zero steady state for the observed endogenous' ] )
disp ( [ ' variables using demeaned data!' ] )
error ( ' You should change something in your mod file...' )
end
2009-12-16 18:17:34 +01:00
end
2023-10-02 11:12:31 +02:00
if ~ isequal ( options_ . mode_compute , 11 )
2014-08-29 15:36:07 +02:00
disp ( [ ' Initial value of the log posterior (or likelihood): ' num2str ( - fval ) ] ) ;
end
2021-01-18 17:46:19 +01:00
2023-10-02 11:12:31 +02:00
if options_ . mh_tune_jscale . status && ( options_ . mh_tune_jscale . maxiter < options_ . mh_tune_jscale . stepsize )
2021-06-01 11:23:07 +02:00
warning ( ' You specified mh_tune_jscale, but the maximum number of iterations is smaller than the step size. No update will take place.' )
end
2023-10-02 11:12:31 +02:00
if ~ isempty ( options_ . conditional_variance_decomposition ) && ~ options_ . moments_varendo
2021-12-10 14:13:19 +01:00
disp ( ' The conditional_variance_decomposition-option will be ignored. You need to set moments_varendo' ) ;
end
2021-01-18 17:46:19 +01:00
function evaluate_expression ( expression,M_,oo_)
% function evaluate_expression(expression,M_,oo_)
%evaluates expressions relying on M_ and oo_ having their original names
2023-03-24 12:29:42 +01:00
eval ( expression ) ;