2014-10-20 16:18:54 +02:00
function DynareResults = initial_estimation_checks ( objective_function,xparam1,DynareDataset,DatasetInfo,Model,EstimatedParameters,DynareOptions,BayesInfo,BoundsInfo,DynareResults)
2016-03-25 20:20:28 +01:00
% function DynareResults = initial_estimation_checks(objective_function,xparam1,DynareDataset,DatasetInfo,Model,EstimatedParameters,DynareOptions,BayesInfo,BoundsInfo,DynareResults)
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
% xparam1: [vector] of parameters to be estimated
2014-06-16 17:41:59 +02:00
% DynareDataset: [dseries] object storing the dataset
% DataSetInfo: [structure] storing informations about the sample.
2013-11-06 08:26:22 +01:00
% Model: [structure] decribing the model
% EstimatedParameters [structure] characterizing parameters to be estimated
% DynareOptions [structure] describing the options
% BayesInfo [structure] describing the priors
2016-03-25 20:20:28 +01:00
% BoundsInfo [structure] containing prior bounds
2013-11-06 08:26:22 +01:00
% DynareResults [structure] storing the results
2011-09-19 16:38:38 +02:00
%
2008-01-21 13:17:46 +01:00
% OUTPUTS
2011-10-12 21:46:50 +02:00
% DynareResults structure of temporary results
2011-09-19 16:38:38 +02:00
%
2008-01-21 13:17:46 +01:00
% SPECIAL REQUIREMENTS
% none
2017-10-10 10:05:59 +02:00
% Copyright (C) 2003-2018 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
2021-05-02 11:48:42 +02:00
maximum_number_non_missing_observations = max ( sum ( ~ isnan ( DynareDataset . data ( 2 : end , : ) ) , 2 ) ) ;
init_number_non_missing_observations = sum ( ~ isnan ( DynareDataset . data ( 1 , : ) ) , 2 ) ;
2015-10-11 10:49:15 +02:00
2021-05-02 17:07:12 +02:00
if DynareOptions . heteroskedastic_filter
if DynareOptions . order > 1
error ( ' initial_estimation_checks:: heteroskedastic shocks are only supported with the Kalman filter/smoother' )
end
observations_by_period = sum ( ~ isnan ( DynareDataset . data ) , 2 ) ;
base_shocks = find ( diag ( Model . Sigma_e ) ) ;
zero_shocks = ~ ismember ( 1 : Model . exo_nbr , base_shocks ) ;
non_zero_shocks_by_period = repmat ( length ( base_shocks ) , size ( observations_by_period ) ) ;
% check periods for which base shocks are scaled to zero
non_zero_shocks_by_period = non_zero_shocks_by_period - sum ( Model . heteroskedastic_shocks . Qscale ( base_shocks , 1 : DynareOptions . nobs ) == 0 , 1 ) ' ;
% check periods for which base shocks are set to zero
non_zero_shocks_by_period = non_zero_shocks_by_period - sum ( Model . heteroskedastic_shocks . Qvalue ( base_shocks , 1 : DynareOptions . nobs ) == 0 , 1 ) ' ;
% check periods for which other shocks are set to a positive number
non_zero_shocks_by_period = non_zero_shocks_by_period + sum ( Model . heteroskedastic_shocks . Qvalue ( zero_shocks , 1 : DynareOptions . nobs ) > 0 , 1 ) ' ;
end
2021-01-16 11:21:14 +01:00
if DynareOptions . order > 1
2020-01-10 19:08:51 +01:00
if any ( any ( isnan ( DynareDataset . data ) ) )
error ( ' initial_estimation_checks:: particle filtering does not support missing observations' )
end
if DynareOptions . prefilter == 1
error ( ' initial_estimation_checks:: particle filtering does not support the prefilter option' )
end
if BayesInfo . with_trend
error ( ' initial_estimation_checks:: particle filtering does not support trends' )
end
2021-01-26 09:26:05 +01:00
if DynareOptions . order > 2 && DynareOptions . particle . pruning == 1
error ( ' initial_estimation_checks:: the particle filter with order>2 does not support pruning' )
end
if DynareOptions . particle . pruning ~= DynareOptions . pruning
warning ( ' initial_estimation_checks:: the pruning settings differ between the particle filter and the one used for IRFs/simulations. Make sure this is intended.\n' )
end
end
2021-05-17 21:24:25 +02:00
if ( DynareOptions . occbin . likelihood . status && DynareOptions . occbin . likelihood . inversion_filter ) || ( DynareOptions . occbin . smoother . status && DynareOptions . occbin . smoother . inversion_filter )
err_index = find ( diag ( Model . Sigma_e ) ~= 0 ) ;
if length ( err_index ) ~= length ( DynareOptions . varobs )
fprintf ( ' initial_estimation_checks:: The IVF requires exactly as many shocks as observables.' )
end
var_index = find ( any ( isnan ( DynareDataset . data ) ) ) ;
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' , ...
DynareOptions . varobs { var_index } , Model . exo_names { DynareOptions . occbin . likelihood . IVF_shock_observable_mapping ( var_index ) } )
end
end
2021-01-26 09:26:05 +01:00
if DynareOptions . order > 1 || ( DynareOptions . order == 1 && ~ ischar ( DynareOptions . mode_compute ) && DynareOptions . mode_compute == 11 )
if DynareOptions . order == 1 && DynareOptions . mode_compute == 11
disp_string = ' mode_compute=11' ;
else
disp_string = ' particle filtering' ;
end
2020-12-08 22:49:41 +01:00
if Model . 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
2021-01-16 11:21:14 +01:00
if sum ( diag ( Model . H ) > 0 ) < length ( DynareOptions . 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
[ ~ , flag ] = chol ( Model . H ) ;
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
2019-06-03 11:02:24 +02:00
non_zero_ME = length ( EstimatedParameters . H_entries_to_check_for_positive_definiteness ) ;
2021-05-02 11:48:42 +02:00
print_init_check_warning = false ;
2019-06-03 11:02:24 +02:00
if maximum_number_non_missing_observations > Model . 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
2021-05-02 11:48:42 +02:00
if init_number_non_missing_observations > Model . exo_nbr + non_zero_ME
if DynareOptions . no_init_estimation_check_first_obs
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
2021-05-02 17:07:12 +02:00
if DynareOptions . heteroskedastic_filter
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
if maximum_number_non_missing_observations > length ( find ( diag ( Model . Sigma_e ) ) ) + non_zero_ME
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
2021-05-02 11:48:42 +02:00
if init_number_non_missing_observations > length ( find ( diag ( Model . Sigma_e ) ) ) + non_zero_ME
if DynareOptions . no_init_estimation_check_first_obs
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
2016-03-06 21:19:17 +01:00
if ( any ( BayesInfo . pshape > 0 ) && DynareOptions . mh_replic ) && DynareOptions . 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
2015-02-11 12:58:36 +01:00
old_steady_params = Model . params ; %save initial parameters for check if steady state changes param values
% % check if steady state solves static model (except if diffuse_filter == 1)
[ DynareResults . steady_state , new_steady_params ] = evaluate_steady_state ( DynareResults . steady_state , Model , DynareOptions , DynareResults , DynareOptions . diffuse_filter == 0 ) ;
2015-04-20 16:45:51 +02:00
if isfield ( EstimatedParameters , ' param_vals' ) && ~ isempty ( EstimatedParameters . param_vals )
2015-03-01 13:36:21 +01:00
%check whether steady state file changes estimated parameters
Model_par_varied = Model ; %store Model structure
Model_par_varied . params ( EstimatedParameters . param_vals ( : , 1 ) ) = Model_par_varied . params ( EstimatedParameters . param_vals ( : , 1 ) ) * 1.01 ; %vary parameters
2018-11-13 17:58:42 +01:00
[ ~ , new_steady_params_2 ] = evaluate_steady_state ( DynareResults . steady_state , Model_par_varied , DynareOptions , DynareResults , DynareOptions . diffuse_filter == 0 ) ;
2015-02-11 12:58:36 +01:00
2015-03-01 13:36:21 +01:00
changed_par_indices = find ( ( old_steady_params ( EstimatedParameters . param_vals ( : , 1 ) ) - new_steady_params ( EstimatedParameters . param_vals ( : , 1 ) ) ) ...
2017-05-16 15:10:20 +02:00
| ( Model_par_varied . params ( EstimatedParameters . param_vals ( : , 1 ) ) - new_steady_params_2 ( EstimatedParameters . param_vals ( : , 1 ) ) ) ) ;
2015-02-11 12:58:36 +01:00
2015-03-01 13:36:21 +01:00
if ~ isempty ( changed_par_indices )
fprintf ( ' \nThe steady state file internally changed the values of the following estimated parameters:\n' )
2017-10-10 10:05:59 +02:00
disp ( char ( Model . param_names ( EstimatedParameters . param_vals ( changed_par_indices , 1 ) ) ) )
2015-03-01 13:36:21 +01:00
fprintf ( ' This will override the parameter values drawn from the proposal density and may lead to wrong results.\n' )
2017-05-16 15:10:20 +02:00
fprintf ( ' Check whether this is really intended.\n' )
2015-03-01 13:36:21 +01:00
warning ( ' The steady state file internally changes the values of the estimated parameters.' )
end
2015-02-11 12:58:36 +01:00
end
2012-03-30 11:12:59 +02:00
2013-11-06 08:26:22 +01:00
if any ( BayesInfo . pshape ) % if Bayesian estimation
nvx = EstimatedParameters . nvx ;
2017-05-16 15:10:20 +02:00
if nvx && any ( BayesInfo . p3 ( 1 : nvx ) < 0 )
2013-11-06 08:26:22 +01:00
warning ( ' Your prior allows for negative standard deviations for structural shocks. Due to working with variances, Dynare will be able to continue, but it is recommended to change your prior.' )
end
offset = nvx ;
nvn = EstimatedParameters . nvn ;
2017-05-16 15:10:20 +02:00
if nvn && any ( BayesInfo . p3 ( 1 + offset : offset + nvn ) < 0 )
2013-11-06 08:26:22 +01:00
warning ( ' Your prior allows for negative standard deviations for measurement error. Due to working with variances, Dynare will be able to continue, but it is recommended to change your prior.' )
end
offset = nvx + nvn ;
2017-05-16 15:10:20 +02:00
ncx = EstimatedParameters . ncx ;
if ncx && ( any ( BayesInfo . p3 ( 1 + offset : offset + ncx ) < - 1 ) || any ( BayesInfo . p4 ( 1 + offset : offset + ncx ) > 1 ) )
2016-05-01 17:52:57 +02:00
warning ( ' Your prior allows for correlations between structural shocks larger than +-1 and will not integrate to 1 due to truncation. Please change your prior' )
2013-11-06 08:26:22 +01:00
end
offset = nvx + nvn + ncx ;
2017-05-16 15:10:20 +02:00
ncn = EstimatedParameters . ncn ;
if ncn && ( any ( BayesInfo . p3 ( 1 + offset : offset + ncn ) < - 1 ) || any ( BayesInfo . p4 ( 1 + offset : offset + ncn ) > 1 ) )
2016-05-01 17:52:57 +02:00
warning ( ' Your prior allows for correlations between measurement errors larger than +-1 and will not integrate to 1 due to truncation. Please change your prior' )
2013-11-06 08:26:22 +01:00
end
end
2014-09-17 20:09:33 +02:00
% display warning if some parameters are still NaN
2014-09-25 09:02:02 +02:00
test_for_deep_parameters_calibration ( Model ) ;
2014-09-17 20:09:33 +02:00
2018-11-13 17:58:42 +01:00
[ lnprior , ~ , ~ , info ] = priordens ( xparam1 , BayesInfo . pshape , BayesInfo . p6 , BayesInfo . p7 , BayesInfo . p3 , BayesInfo . p4 ) ;
2018-11-14 15:02:15 +01:00
if any ( info )
2014-09-17 20:09:33 +02:00
fprintf ( ' The prior density evaluated at the initial values is Inf for the following parameters: %s\n' , BayesInfo . name { info , 1 } )
error ( ' The initial value of the prior is -Inf' )
end
2016-08-10 12:41:20 +02:00
2021-01-18 17:46:19 +01:00
if isfield ( Model , ' filter_initial_state' ) && ~ isempty ( Model . filter_initial_state )
state_indices = DynareResults . dr . order_var ( DynareResults . dr . restrict_var_list ( BayesInfo . mf0 ) ) ;
for ii = 1 : size ( state_indices , 1 )
if ~ isempty ( Model . filter_initial_state { state_indices ( ii ) , 1 } )
try
evaluate_expression ( Model . filter_initial_state { state_indices ( ii ) , 2 } , Model , DynareResults )
catch
fprintf ( ' Unable to evaluate the expression\n %s \nfor the filter_initial_state of variable %s\n' , Model . filter_initial_state { state_indices ( ii ) , 2 } , Model . endo_names ( state_indices ( ii ) , : ) )
end
end
end
end
2016-08-10 12:41:20 +02:00
if DynareOptions . ramsey_policy
%test whether specification matches
inst_nbr = size ( DynareOptions . instruments , 1 ) ;
if inst_nbr ~= 0
orig_endo_aux_nbr = Model . orig_endo_nbr + min ( find ( [ Model . aux_vars . type ] == 6 ) ) - 1 ;
implied_inst_nbr = orig_endo_aux_nbr - Model . orig_eq_nbr ;
if inst_nbr > implied_inst_nbr
error ( ' You have specified more instruments than there are omitted equations' )
elseif inst_nbr < implied_inst_nbr
error ( ' You have specified fewer instruments than there are omitted equations' )
end
end
end
2021-07-14 19:30:50 +02:00
if ~ isreal ( DynareDataset . data )
error ( ' initial_estimation_checks: the data contains complex values.' )
end
2012-03-30 11:12:59 +02:00
% Evaluate the likelihood.
2012-08-21 15:46:35 +02:00
ana_deriv = DynareOptions . analytic_derivation ;
DynareOptions . analytic_derivation = 0 ;
2015-05-27 18:06:48 +02:00
if ~ isequal ( DynareOptions . mode_compute , 11 ) || ...
( isequal ( DynareOptions . mode_compute , 11 ) && isequal ( DynareOptions . 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
use_univariate_filters_if_singularity_is_detected_old = DynareOptions . use_univariate_filters_if_singularity_is_detected ;
DynareOptions . use_univariate_filters_if_singularity_is_detected = 0 ;
[ fval , info ] = feval ( objective_function , xparam1 , DynareDataset , DatasetInfo , DynareOptions , Model , EstimatedParameters , BayesInfo , BoundsInfo , DynareResults ) ;
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
message = get_error_message ( info , DynareOptions ) ;
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
2016-10-02 12:54:36 +02:00
DynareOptions . 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
2014-09-20 19:57:43 +02:00
if DynareOptions . debug
DynareResults . likelihood_at_initial_parameters = fval ;
end
2012-08-21 15:46:35 +02:00
DynareOptions . analytic_derivation = ana_deriv ;
2011-10-12 21:46:50 +02:00
2021-01-22 14:48:18 +01:00
if DynareOptions . mode_compute == 13
error ( ' Options mode_compute=13 is only compatible with quadratic objective functions' )
end
2012-05-31 14:42:52 +02:00
% if DynareOptions.mode_compute==5
% if ~strcmp(func2str(objective_function),'dsge_likelihood')
% error('Options mode_compute=5 is not compatible with non linear filters or Dsge-VAR models!')
% end
% 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
2017-03-20 17:30:41 +01:00
if DynareOptions . order > 1
[ eigenvalues_ ] = check ( Model , DynareOptions , DynareResults ) ;
2017-04-05 14:14:56 +02:00
if any ( abs ( 1 - abs ( eigenvalues_ ) ) < abs ( DynareOptions . 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' )
print_info ( info , DynareOptions . noprint , DynareOptions )
2017-03-20 17:30:41 +01:00
end
2009-12-16 18:17:34 +01:00
end
2014-06-15 12:26:36 +02:00
if DynareOptions . prefilter == 1
if ( ~ DynareOptions . loglinear && any ( abs ( DynareResults . steady_state ( BayesInfo . mfys ) ) > 1e-9 ) ) || ( DynareOptions . loglinear && any ( abs ( log ( DynareResults . steady_state ( BayesInfo . mfys ) ) ) > 1e-9 ) )
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
2014-08-29 15:36:07 +02:00
if ~ isequal ( DynareOptions . mode_compute , 11 )
disp ( [ ' Initial value of the log posterior (or likelihood): ' num2str ( - fval ) ] ) ;
end
2021-01-18 17:46:19 +01:00
2021-06-01 11:23:07 +02:00
if DynareOptions . mh_tune_jscale . status && ( DynareOptions . mh_tune_jscale . maxiter < DynareOptions . mh_tune_jscale . stepsize )
warning ( ' You specified mh_tune_jscale, but the maximum number of iterations is smaller than the step size. No update will take place.' )
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
eval ( expression ) ;