Compare commits

...

107 Commits

Author SHA1 Message Date
Sébastien Villemot 7bf0395a27 Merge branch 'cet-octave-one-more-time' into 'master'
Fixes for CET tests on Octave

See merge request Dynare/dynare!2254
2023-12-22 09:17:15 +00:00
Willi Mutschler ee2545f84d
Fixes for CET tests on Octave
- the mode file was previously saved as '-v7.3', now it is '-v6'
- mode_compute=1 and additional_optimizer=1 do not work under Octave
2023-12-22 09:48:56 +01:00
Sébastien Villemot dd1669082e Merge branch 'Octave' into 'master'
graph_comparison_irfs.m: compatibility fix for Octave

See merge request Dynare/dynare!2252
2023-12-22 08:42:23 +00:00
Johannes Pfeifer 9c28f5feaf graph_comparison_irfs.m: compatibility fix for Octave 2023-12-21 21:17:53 +01:00
Sébastien Villemot 31ce155852
Bump major version number 2023-12-21 16:06:46 +01:00
Sébastien Villemot c36b695cd9 Merge branch 'get_mean' into 'master'
get_mean.m: remove globals and fix internal logic

See merge request Dynare/dynare!2250
2023-12-21 14:37:22 +00:00
Sébastien Villemot 6cad684980
Merge branch 'dynare-plot_initval_decomp'
Ref. !2249
2023-12-21 14:04:06 +01:00
Marco Ratto a4e6531420
check existence of oo_.initval_decomposition and, if absent, compute it
Closes: #1913
2023-12-21 14:03:51 +01:00
Sébastien Villemot d09a206c7c
Merge branch 'dynare-bugfixes'
Ref. !2248
2023-12-21 14:02:51 +01:00
Marco Ratto fbf62255c6
fix undefined new filter option 2023-12-21 14:02:20 +01:00
Marco Ratto e918589e02
fix undefined index j using wildcard
Closes: #1915
2023-12-21 14:02:13 +01:00
Sébastien Villemot 368c93214e
Build system: make xvfb-run optional for running the Octave testsuite
xvfb-run is a Debian-specific program.

Closes: #1892
2023-12-21 13:46:34 +01:00
Johannes Pfeifer 8deeaa7252 Add version of get_mean without globals 2023-12-21 13:41:17 +01:00
Johannes Pfeifer e3e6f4c9b4 🐛 get_mean.m: fix internal logic 2023-12-21 13:40:23 +01:00
Sébastien Villemot 5216cec249
Build system: update comment about GSL_CBLAS_LIB with newly-opened issue against Meson 2023-12-21 11:57:18 +01:00
Sébastien Villemot cae5a00e80
Windows package: bump dependencies 2023-12-21 11:20:44 +01:00
Sébastien Villemot 42e2f77e4a
Emacs mode: add IRF matching keywords 2023-12-21 11:20:27 +01:00
Sébastien Villemot 7a5684bf4b Merge branch 'bayesian_irf_matching' into 'master'
IRF Matching

See merge request Dynare/dynare!2191
2023-12-21 09:21:35 +00:00
Willi Mutschler c4bf6d079f
Add documentation for irf matching 2023-12-21 02:40:27 +01:00
Willi Mutschler c46eef685d
irf_matching: add test for interface 2023-12-21 01:49:40 +01:00
Willi Mutschler 2f07fa2921
irf_matching: adaptations for new interface 2023-12-21 01:49:40 +01:00
Willi Mutschler f14bbc73b1
preprocessor: add new matched_irfs and matched_irfs_weights blocks 2023-12-21 01:49:40 +01:00
Willi Mutschler 329f0d2d54
method_of_moments: Remove unused output from IRF Matching for GMM/SMM 2023-12-21 01:48:28 +01:00
Willi Mutschler 68b92a1ab9
method_of_moments: fixes required by changes introduced with SMC
60c0ed0180 changed:
- the call to GetPosteriorMeanVariance
2023-12-21 01:48:28 +01:00
Willi Mutschler 8987576ff5
irf_matching: make test files finish faster 2023-12-21 01:48:28 +01:00
Willi Mutschler 9148b5b210
irf_matching: add message for explosive irfs to get_error_message 2023-12-21 01:48:28 +01:00
Willi Mutschler 0b839467e6
method_of_moments: consistently use uppercases for NaN, Inf, IRFs 2023-12-21 01:48:28 +01:00
Willi Mutschler 547bdcc99b
irf_matching: fixed CET (2016) test and some cosmetical changes 2023-12-21 01:48:28 +01:00
Willi Mutschler 0787589479
method_of_moments: use / instead of filesep for latex filenames 2023-12-21 01:48:28 +01:00
Willi Mutschler 37efafe475
method_of_moments: cosmetical changes to comments and messages 2023-12-21 01:48:28 +01:00
Willi Mutschler 7f60674dae
irf_matching: Add CET (2016, Econometrica) test 2023-12-21 01:48:28 +01:00
Willi Mutschler bd3ca58727
method_of_moments: remove spurious diag(diag(x)) 2023-12-21 01:48:28 +01:00
Willi Mutschler 65f8b56fb0
irf_matching: add checks for inverse and logdet of weighting matrix 2023-12-21 01:48:28 +01:00
Willi Mutschler 2521314c39
irf_matching: make comparison graph prettier 2023-12-21 01:48:28 +01:00
Willi Mutschler 378e38c8c2
method_of_moments: remove to do list and maintaining authors 2023-12-21 01:48:28 +01:00
Willi Mutschler c59daa6139
method_of_moments: use underscore instead of camel case for variables 2023-12-21 01:48:28 +01:00
Willi Mutschler 937ee0ef77
irf_matching: add steady-state as input to irf_matching_file 2023-12-21 01:48:28 +01:00
Willi Mutschler 8515a195ab
method_of_moments: add irf_matching to run script 2023-12-21 01:48:28 +01:00
Willi Mutschler 8a29933c6e
method_of_moments: adapt comparison and display scripts for irf_matching 2023-12-21 01:48:28 +01:00
Willi Mutschler f210ffa3ae
method_of_moments: add irf_matching to print_info_on_estimation_settings 2023-12-21 01:48:28 +01:00
Willi Mutschler 20ec0a6c97
method_of_moments: add irf_matching to objective_function 2023-12-21 01:48:28 +01:00
Willi Mutschler e9871d7d47
method_of_moments: cosmetical changes 2023-12-21 01:48:28 +01:00
Willi Mutschler 459842e4f6
irfmatching: add mode_compute_irf_matching function 2023-12-21 01:48:28 +01:00
Willi Mutschler 2d8bcd6918
irfmatching: add function to translate irf_matching blocks into useful structures
This needs to be adapted once we implement an interface in the preprocessor
2023-12-21 01:48:28 +01:00
Willi Mutschler c45c0efeba
irfmatching: add options and checks to options_mom_ 2023-12-21 01:48:28 +01:00
Willi Mutschler 613b3869e1
irfmatching: add function to check for existence of irf_matching_file 2023-12-21 01:48:28 +01:00
Willi Mutschler 95bfb84014
method_of_moments: cosmetical changes to headers, comments, semicolons 2023-12-21 01:48:28 +01:00
Willi Mutschler 37c7ca2d97
method_of_moments: don't use oo_ as input 2023-12-21 01:48:28 +01:00
Willi Mutschler dedbb3be57
method_of_moments: rename Bounds to BoundsInfo 2023-12-21 01:48:28 +01:00
Sébastien Villemot d7850a2bbe Merge branch 'bugfixes' into 'master'
Bugfixes for parallel and estimation

See merge request Dynare/dynare!2244
2023-12-20 19:24:39 +00:00
Willi Mutschler b435aa7f27
Cosmetical change for use_mh_covariance_matrix
With use_mh_covariance_matrix we do not load previous simulations, but only base the proposal density on a previous run; so skip the display.
2023-12-20 18:22:41 +01:00
Willi Mutschler f8a6020d2b
🐛 Fix bug in 4a6783
options_ is missing as an input argument for compute_posterior_covariance_matrix
2023-12-20 18:22:41 +01:00
Willi Mutschler 5f1ae3bb19
🐛 Fix bugs in parallel toolbox introduced in 47af0c
1. 'fGlobalVar' was misspelled
2. Removing the eval crashes the parallel option as global variables are not passed correctly. Because it originally was an assignment where the variable named options_ was assigned to fGlobalVar.options_, but after 47af0cdewe only assign the string 'options_' stored in GlobalNames{j}.
2023-12-20 18:22:41 +01:00
Sébastien Villemot bc69f6a102
Initial scripts for packaging Dynare for MATLAB Online
[skip ci]
2023-12-20 17:24:19 +01:00
Sébastien Villemot 8b9d1d1346
Merge branch 'NK_baseline' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2245
2023-12-20 14:04:32 +01:00
Sébastien Villemot 38d1c0538a
Merge branch 'posterior_moments' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2242
2023-12-20 14:03:18 +01:00
Johannes Pfeifer 774cb18aac posterior_moments.m: do not request density if output is not used
removes indicator and replaces it by nargout-check
2023-12-20 09:14:03 +01:00
Johannes Pfeifer b215eedb4b NK_baseline.mod: set up shocks block in a way that standard deviation parameters can be estimated 2023-12-20 08:39:21 +01:00
Sébastien Villemot fb18777e58
Merge branch 'mc_analysis' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2243
2023-12-19 18:34:37 +01:00
Sébastien Villemot 311808db0a
Merge branch 'header_fix' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2241
2023-12-19 18:32:46 +01:00
Sébastien Villemot 52b92ce64d
Merge branch 'parallel' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2240
2023-12-19 18:32:24 +01:00
Johannes Pfeifer ba52789020 _mc_analysis: move all files to estimation folder for consistency 2023-12-19 14:45:29 +01:00
Johannes Pfeifer c52c21ca24 posterior moments: explicitly load required variables 2023-12-19 14:45:29 +01:00
Sébastien Villemot e649fa5494
Merge branch 'ep' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2239
2023-12-19 09:55:23 +01:00
Sébastien Villemot 346d2acbdf
Merge branch 'outputs' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2238
2023-12-19 09:54:38 +01:00
Johannes Pfeifer 278e767ea1 closeSlave.m: remove duplicated condition and restore warning 2023-12-19 09:04:27 +01:00
Johannes Pfeifer 90ced5ca47 slaveParallel.m: minor cleanup 2023-12-19 09:03:30 +01:00
Sébastien Villemot c9db9809d0
Drop unused options_.minimal_workspace 2023-12-18 20:42:16 +01:00
Sébastien Villemot 70b9d9277a Merge branch 'occbin_bugfixes_marco' into 'master'
Improvements to OccBin filtering/smoothing

See merge request Dynare/dynare!2237
2023-12-18 18:55:12 +00:00
Johannes Pfeifer 78abd68c9f EP: gracefully handle error 2023-12-18 17:08:28 +01:00
Johannes Pfeifer 4512e85cb2 Restore outputs erroneously removed in 735bd66d 2023-12-18 17:07:01 +01:00
Johannes Pfeifer d7ae0d0039 OccBin: improve consistency - Make name of opts_simul subfield homogeneous for likelihood computation and smoother - fill the new field opts_regime with init_binding_indicator init_regime_history, to avoid possible conflics with simulations done in realtime filtering steps - smoother: use init_binding_indicator and init_regime_history options set in options_.occbin.smoother 2023-12-18 16:16:50 +01:00
Marco Ratto ac346ef83d occbin.kalman_update_engine.m: embed use_relaxation and extend to work with 2 constraints 2023-12-18 16:16:49 +01:00
Marco Ratto 9b165d7785 occbin.map_regime.m: trap case where indicator is empty 2023-12-18 16:16:48 +01:00
Johannes Pfeifer 7b94310fd4 occbin.solver.m: fix header 2023-12-18 16:16:47 +01:00
Marco Ratto 8348cf009a OccBin: enhance search of filtered regime, using new kalman_update_engine.m
brute_force_regime_guess (default) and loss_function_regime_guess (optional, more time consuming) may be used to search for better solution (i.e. a solution providing better data density). Governed by options_.occbin.likelihood.number_of_initial_periods_with_extra_regime_guess
where the latter is 0 by default and can be set by user
2023-12-18 16:16:46 +01:00
Marco Ratto 75f5a463df OccBin smoother: trap realtime smoother error and use linear smoother for first guess 2023-12-18 16:16:45 +01:00
Marco Ratto e8d82ad840 Occbin: make convergence criteria for periodic solution more precise;
Also allows periodic loops to be a solution (periodic_solution_strict=false), provided regime is found that does not violate constraint in expectation AND the number of periods in violation is smaller than max allowed (periodic_solution_threshold= INTEGER)
2023-12-18 16:16:44 +01:00
Johannes Pfeifer ab6ea60967 Occbin smoother: try using smoothed shocks from linear smoother as last resort to initialize guess sequence of regimes 2023-12-18 16:16:43 +01:00
Marco Ratto 90fbb9559e 🐛 Occbin smoother: ensure all shocks are plotted with heteroskedastic_filter 2023-12-18 16:16:42 +01:00
Marco Ratto 3f1a37614f OccBin: store simul.piecewise and simul.linear in oo_.occbin.smoother, for easier post-processing of results 2023-12-18 16:16:40 +01:00
Marco Ratto ee5faf0783 🐛 Occbin smoother: set periods to the smpl size
Prevents crash if periods was too small
2023-12-18 16:16:39 +01:00
Marco Ratto cf7be44257 occbin.solver: initialize output ss to avoid crashes when call to resol fails 2023-12-18 16:16:38 +01:00
Sébastien Villemot c363355dbf
Merge branch 'obs_check' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2236
2023-12-18 15:55:20 +01:00
Sébastien Villemot d50330aad3
Merge branch 'cosmetics' of git.dynare.org:JohannesPfeifer/dynare
Ref. !2235
2023-12-18 15:55:06 +01:00
Sébastien Villemot 380e78be53
user_has_matlab_license: fix spurious messages when toolbox is not present
This is effectively a partial revert of
735bd66d4d.
2023-12-18 15:47:45 +01:00
Sébastien Villemot 84a7b4b2cf
Merge branch 'dynare-PF_globals'
Ref. !2229
2023-12-18 11:51:46 +01:00
Johannes Pfeifer 48380a1370
Do not assign variables to base workspace by default
Related to https://git.dynare.org/Dynare/preprocessor/-/issues/95
2023-12-18 11:51:27 +01:00
Johannes Pfeifer 3faaffacc6
perfect foresight: remove globals 2023-12-18 11:51:21 +01:00
Sébastien Villemot e9ffb16ec6 Merge branch 'model_comp_tol' into 'master'
fs2000_model_comparison.mod: increase test tolerance due to problems on some runners

See merge request Dynare/dynare!2234
2023-12-18 10:11:43 +00:00
Stéphane Adjemian (Ryûk) 4982ce06b4
Remove unnecessary square brackets. 2023-12-18 10:49:49 +01:00
Johannes Pfeifer 37e4d68264 load_m_file_data_legacy.m: fix check for correct number of observations 2023-12-18 10:30:35 +01:00
Johannes Pfeifer 4d6d4953e7 GetPosteriorParametersStatistics.m and check_bounds_and_definiteness_estimation.m: cosmetic changes 2023-12-18 09:50:18 +01:00
Stéphane Adjemian (Ryûk) c399f54581
Remove call to eval. 2023-12-18 08:57:12 +01:00
Stéphane Adjemian (Ryûk) 735bd66d4d
Remove unused output arguments. 2023-12-18 07:48:27 +01:00
Stéphane Adjemian (Ryûk) 7468a903b7
Remove initialize_dataset routine.
This routine was no longer used in other parts of the code.
2023-12-17 19:00:37 +01:00
Stéphane Adjemian (Ryûk) c841f1474c
isinf(X)~= ⇔ isinf(X). 2023-12-17 08:30:56 +01:00
Stéphane Adjemian (Ryûk) b6619b342b
Remove unused variable. 2023-12-16 23:30:43 +01:00
Stéphane Adjemian (Ryûk) fef466ef34
Remove unused variable. 2023-12-16 23:13:15 +01:00
Stéphane Adjemian (Ryûk) 52be9d08c1
Cosmetic change (do not change index value in a for-loop). 2023-12-16 23:08:29 +01:00
Stéphane Adjemian (Ryûk) 5d8861ff29
Cosmetic change. 2023-12-16 23:03:02 +01:00
Stéphane Adjemian (Ryûk) 743de7da5c
Remove increment on for-loop index. 2023-12-16 23:03:02 +01:00
Stéphane Adjemian (Ryûk) e962cb4dba
Move the dseries submodule from the modules folder.
Makes no sense anymore to keep it there since it was the only git submdule.
2023-12-16 23:02:57 +01:00
Stéphane Adjemian (Ryûk) cf4c6cdf14
Update dseries submodule (rewrite two patches). 2023-12-16 22:26:43 +01:00
Stéphane Adjemian (Guts) 7915b91fdb
Error takes sprintf like arguments directly. 2023-12-16 22:24:26 +01:00
Johannes Pfeifer 72a8d53df8 fs2000_model_comparison.mod: increase test tolerance due to problems on some runners 2023-12-15 21:44:10 +01:00
Johannes Pfeifer dbcc0aeb9f GetPosteriorMeanVariance.m: fix header
[skip CI]
2023-12-14 16:01:51 +01:00
302 changed files with 6533 additions and 2042 deletions

View File

@ -11,12 +11,12 @@ variables:
# - if VERSION was already set (when manually running a pipeline), use it
# - if we are in the official Dynare repository:
# + if on a tag: use the tag
# + if on master: use 6-unstable-$TIMESTAMP-$COMMIT
# + if on master: use 7-unstable-$TIMESTAMP-$COMMIT
# + on another branch: use $BRANCH-$TIMESTAMP-$COMMIT
# - if in a personal repository: use $USER-$TIMESTAMP-$COMMIT
before_script:
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ -n $CI_COMMIT_TAG ]]; then export VERSION=$CI_COMMIT_TAG; fi'
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ $CI_COMMIT_REF_NAME == master ]]; then export VERSION=6-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ $CI_COMMIT_REF_NAME == master ]]; then export VERSION=7-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]]; then export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
- 'if [[ -z $VERSION ]]; then export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'

2
.gitmodules vendored
View File

@ -11,7 +11,7 @@
path = matlab/utilities/tests
url = ../../Dynare/m-unit-tests.git
[submodule "matlab/modules/dseries"]
path = matlab/modules/dseries
path = matlab/dseries
url = ../../Dynare/dseries.git
branch = master
[submodule "preprocessor"]

View File

@ -2,7 +2,6 @@ function build_internal_documentation()
% The name of the function should be explicit...
datafiles = [];
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'initialize_dataset'}];
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'descriptive_statistics'}];
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'compute_stdv'}];
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'compute_cova'}];
@ -81,4 +80,4 @@ if rows(miscfiles)
fprintf(fid,'\n\n\n');
end
end
fclose(fid);
fclose(fid);

View File

@ -21,6 +21,8 @@ Bibliography
* Brooks, Stephen P., and Andrew Gelman (1998): “General methods for monitoring convergence of iterative simulations,” *Journal of Computational and Graphical Statistics*, 7, pp. 434455.
* Cardoso, Margarida F., R. L. Salcedo and S. Feyo de Azevedo (1996): “The simplex simulated annealing approach to continuous non-linear optimization,” *Computers & Chemical Engineering*, 20(9), 1065-1080.
* Chib, Siddhartha and Srikanth Ramamurthy (2010): “Tailored randomized block MCMC methods with application to DSGE models,” *Journal of Econometrics*, 155, 1938.
* Christiano, Lawrence J., Martin Eichenbaum and Charles L. Evans (2005): “Nominal Rigidities and the Dynamic Effects of a Shock to Monetary Policy,” *Journal of Political Economy*, 113(1), 145.
* Christiano, Lawrence J., Mathias Trabandt, and Karl Walentin (2010): “DSGE Models for Monetary Policy Analysis,” In: *Handbook of Monetary Economics 3*, 285367.
* Christiano, Lawrence J., Mathias Trabandt and Karl Walentin (2011): “Introducing financial frictions and unemployment into a small open economy model,” *Journal of Economic Dynamics and Control*, 35(12), 19992041.
* Christoffel, Kai, Günter Coenen and Anders Warne (2010): “Forecasting with DSGE models,” *ECB Working Paper Series*, 1185.
* Collard, Fabrice (2001): “Stochastic simulations with Dynare: A practical guide”.

View File

@ -8,6 +8,20 @@
Dynare misc commands
####################
.. matcomm:: send_endogenous_variables_to_workspace
Puts the simulation results for the endogenous variables stored in ``oo_.endo_simul``
into vectors with the same name as the respective variables into the base workspace.
.. matcomm:: send_exogenous_variables_to_workspace
Puts the simulation results for the exogenous variables stored in ``oo_.exo_simul``
into vectors with the same name as the respective variables into the base workspace.
.. matcomm:: send_irfs_to_workspace
Puts the IRFs stored in ``oo_.irfs`` into vectors with the same name into the base workspace.
.. command:: prior_function(OPTIONS);
Executes a user-defined function on parameter draws from the prior

File diff suppressed because it is too large Load Diff

View File

@ -26,13 +26,17 @@
* The model is written in the beginning of period stock notation. To make the model
* conform with Dynares end of period stock notation, we use the
* predetermined_variables-command.
*
*
* The model has been implemented in detrended form, i.e. the \mu_{i,t} are actually
* the the growth rates of the original \mu_{i,t}^{orig} in the paper, i.e.
* log(\mu_{i,t})=log(\mu_{i,t}^{orig}/\mu_{i,t-1}^{orig})
*
* Please note that the following copyright notice only applies to this Dynare
* implementation of the model.
*/
/*
* Copyright © 2013-2020 Dynare Team
* Copyright © 2013-2023 Dynare Team
*
* This file is part of Dynare.
*
@ -151,12 +155,12 @@ gammmaPI =1.29;
PIbar = 1.01;
rhod = 0.12;
rhophi = 0.93;
sigma_A = -3.97;
sigma_d = -1.51;
sigma_A = exp(-3.97);
sigma_d = exp(-1.51);
sigma_phi =-2.36;
sigma_mu =-5.43;
sigma_m =-5.85;
sigma_phi =exp(-2.36);
sigma_mu =exp(-5.43);
sigma_m =exp(-5.85);
Lambdamu=3.4e-3;
LambdaA = 2.8e-3;
@ -214,7 +218,7 @@ mc=(1/(1-alppha))^(1-alppha)*(1/alppha)^alppha*w^(1-alppha)*r^alppha;
1=thetap*(PI(-1)^chi/PI)^(1-epsilon)+(1-thetap)*PIstar^(1-epsilon);
[name='Taylor Rule']
R/Rbar=(R(-1)/Rbar)^gammmaR*((PI/PIbar)^gammmaPI*((yd/yd(-1)*mu_z)/exp(LambdaYd))^gammmay)^(1-gammmaR)*exp(epsm);
R/Rbar=(R(-1)/Rbar)^gammmaR*((PI/PIbar)^gammmaPI*((yd/yd(-1)*mu_z)/exp(LambdaYd))^gammmay)^(1-gammmaR)*exp(sigma_m*epsm);
[name='Resource constraint']
yd=c+x+mu_z^(-1)*mu_I^(-1)*(gammma1*(u-1)+gammma2/2*(u-1)^2)*k;
@ -235,24 +239,24 @@ PIstarw=wstar/w;
//exogenous processes
[name='Preference Shock']
log(d)=rhod*log(d(-1))+epsd;
log(d)=rhod*log(d(-1))+sigma_d*epsd;
[name='Labor disutility Shock']
log(phi)=rhophi*log(phi(-1))+epsphi;
log(phi)=rhophi*log(phi(-1))+sigma_phi*epsphi;
[name='Investment specific technology']
log(mu_I)=Lambdamu+epsmu_I;
log(mu_I)=Lambdamu+sigma_mu*epsmu_I;
[name='Neutral technology']
log(mu_A)=LambdaA+epsA;
log(mu_A)=LambdaA+sigma_A*epsA;
[name='Defininition composite technology']
mu_z=mu_A^(1/(1-alppha))*mu_I^(alppha/(1-alppha));
end;
shocks;
var epsd; stderr exp(sigma_d);
var epsphi; stderr exp(sigma_phi);
var epsmu_I; stderr exp(sigma_mu);
var epsA; stderr exp(sigma_A);
var epsm; stderr exp(sigma_m);
var epsd; stderr 1;
var epsphi; stderr 1;
var epsmu_I; stderr 1;
var epsA; stderr 1;
var epsm; stderr 1;
end;
steady;

View File

@ -34,7 +34,7 @@ global oo_
oo_.bvar.log_marginal_data_density=NaN(maxnlags,1);
for nlags = 1:maxnlags
[ny, nx, posterior, prior] = bvar.toolbox(nlags);
[ny, ~, posterior, prior] = bvar.toolbox(nlags);
oo_.bvar.posterior{nlags}=posterior;
oo_.bvar.prior{nlags}=prior;
@ -75,8 +75,8 @@ function w = matrictint(S, df, XXi)
k=size(XXi,1);
ny=size(S,1);
[cx,p]=chol(XXi);
[cs,q]=chol(S);
[cx,p] = chol(XXi); %second output required to prevent error
[cs,p] = chol(S); %second output required to prevent error
if any(diag(cx)<100*eps)
error('singular XXi')

View File

@ -33,7 +33,7 @@ global options_ oo_ M_
if options_.forecast == 0
error('bvar.forecast: you must specify "forecast" option')
end
[ny, nx, posterior, prior, forecast_data] = bvar.toolbox(nlags);
[ny, nx, posterior, ~, forecast_data] = bvar.toolbox(nlags);
sims_no_shock = NaN(options_.forecast, ny, options_.bvar_replic);
sims_with_shocks = NaN(options_.forecast, ny, options_.bvar_replic);
@ -95,7 +95,7 @@ end
if p > 0
skipline()
disp(['Some of the VAR models sampled from the posterior distribution'])
disp('Some of the VAR models sampled from the posterior distribution')
disp(['were found to be explosive (' num2str(p/options_.bvar_replic) ' percent).'])
skipline()
end

View File

@ -35,7 +35,7 @@ if nargin==1
identification = 'Cholesky';
end
[ny, nx, posterior, prior] = bvar.toolbox(nlags);
[ny, nx, posterior] = bvar.toolbox(nlags);
S_inv_upper_chol = chol(inv(posterior.S));
@ -96,7 +96,7 @@ end
if p > 0
skipline()
disp(['Some of the VAR models sampled from the posterior distribution'])
disp('Some of the VAR models sampled from the posterior distribution')
disp(['were found to be explosive (' int2str(p) ' samples).'])
skipline()
end

View File

@ -292,23 +292,23 @@ end
%
if is_gauss_newton
[params1, SSR, exitflag] = gauss_newton(resfun, params0);
[params1, SSR] = gauss_newton(resfun, params0);
elseif is_lsqnonlin
if ismember('levenberg-marquardt', varargin)
% Levenberg Marquardt does not handle boundary constraints.
[params1, SSR, ~, exitflag] = lsqnonlin(resfun, params0, [], [], optimset(varargin{:}));
[params1, SSR] = lsqnonlin(resfun, params0, [], [], optimset(varargin{:}));
else
[params1, SSR, ~, exitflag] = lsqnonlin(resfun, params0, bounds(:,1), bounds(:,2), optimset(varargin{:}));
[params1, SSR] = lsqnonlin(resfun, params0, bounds(:,1), bounds(:,2), optimset(varargin{:}));
end
else
% Estimate the parameters by minimizing the sum of squared residuals.
[params1, SSR, exitflag] = dynare_minimize_objective(ssrfun, params0, ...
minalgo, ...
options_, ...
bounds, ...
parameter_names, ...
[], ...
[]);
[params1, SSR] = dynare_minimize_objective(ssrfun, params0, ...
minalgo, ...
options_, ...
bounds, ...
parameter_names, ...
[], ...
[]);
end
% Revert local modifications to the options.

View File

@ -147,7 +147,7 @@ for i=1:r
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% a --> Define the random vector x0 for the factors. Note that x0 takes value in the hypercube
% [0,...,1-Delta]*[0,...,1-Delta]*[0,...,1-Delta]*[0,...,1-Delta]
MyInt = repmat([0:(1/(p-1)):(1-Delta)],NumFact,1); % Construct all possible values of the factors
MyInt = repmat(0:(1/(p-1)):(1-Delta),NumFact,1); % Construct all possible values of the factors
% OLD VERSION - it needs communication toolbox
% w = randint(NumFact,1,[1,size(MyInt,2)]);

View File

@ -212,7 +212,7 @@ if ~isempty(indx_irf)
indx_irf_matrix(:,plot_indx(ij)) = indx_irf_matrix(:,plot_indx(ij)) + indx_irf(:,ij);
for ik=1:size(mat_irf{ij},2)
[Mean,Median,Var,HPD,Distrib] = ...
posterior_moments(mat_irf{ij}(:,ik),0,options_.mh_conf_sig);
posterior_moments(mat_irf{ij}(:,ik),options_.mh_conf_sig);
irf_mean{plot_indx(ij)} = [irf_mean{plot_indx(ij)}; Mean];
irf_median{plot_indx(ij)} = [irf_median{plot_indx(ij)}; Median];
irf_var{plot_indx(ij)} = [irf_var{plot_indx(ij)}; Var];
@ -417,7 +417,7 @@ if ~isempty(indx_moment)
indx_moment_matrix(:,plot_indx(ij)) = indx_moment_matrix(:,plot_indx(ij)) + indx_moment(:,ij);
for ik=1:size(mat_moment{ij},2)
[Mean,Median,Var,HPD,Distrib] = ...
posterior_moments(mat_moment{ij}(:,ik),0,options_.mh_conf_sig);
posterior_moments(mat_moment{ij}(:,ik),options_.mh_conf_sig);
moment_mean{plot_indx(ij)} = [moment_mean{plot_indx(ij)}; Mean];
moment_median{plot_indx(ij)} = [moment_median{plot_indx(ij)}; Median];
moment_var{plot_indx(ij)} = [moment_var{plot_indx(ij)}; Var];

View File

@ -720,7 +720,7 @@ function indmcf = redform_mcf(y0, x0, options_mcf, options_, fname, parnames, es
hh_fig=dyn_figure(options_.nodisplay,'name',options_mcf.amcf_title);
[~, ~, ~, ~, post_deciles] = posterior_moments(y0,1,0.9);
[~, ~, ~, ~, post_deciles] = posterior_moments(y0,0.9);
post_deciles = [-inf; post_deciles; inf];
for jt=1:10

View File

@ -89,7 +89,7 @@ lpmat0=zeros(Nsam,0);
xparam1=[];
%% prepare prior bounds
[~,~,~,lb,ub,~] = set_prior(estim_params_,M_,options_); %Prepare bounds
[~,~,~,lb,ub] = set_prior(estim_params_,M_,options_); %Prepare bounds
if ~isempty(bayestopt_) && any(bayestopt_.pshape > 0)
% Set prior bounds
bounds = prior_bounds(bayestopt_, options_.prior_trunc);
@ -600,4 +600,4 @@ end
skipline(1);
xparam1=x0;
save([OutputDirectoryName filesep 'prior_ok.mat'],'xparam1');
save([OutputDirectoryName filesep 'prior_ok.mat'],'xparam1');

View File

@ -142,11 +142,11 @@ mapkeys = unique(cell2mat([keys(unanticipated_p_shocks) keys(unanticipated_t_sho
%% Simulation
options_.periods = jm.periods;
perfect_foresight_setup;
oo_=perfect_foresight_setup(M_, options_, oo_);
% no surprise shocks present
if isempty(mapkeys)
perfect_foresight_solver;
oo_=perfect_foresight_solver(M_, options_, oo_);
return
end
@ -161,7 +161,7 @@ end
if mapkeys(1) ~= 1
% if first unanticipated shock is not in period 1
% simulate until first unanticipated shock and save
perfect_foresight_solver;
oo_=perfect_foresight_solver(M_, options_, oo_);
yy = [yy oo_.endo_simul(:, 2:mapkeys(1)+1)];
end
@ -203,7 +203,7 @@ for i = 1:length(mapkeys)
last_period = this_period;
assert(rows(oo_.exo_simul) == oo_exo_simul_rows, 'error encountered setting oo_.exo_simul');
oo_.endo_simul(:, 1) = yy(:, end);
perfect_foresight_solver;
oo_=perfect_foresight_solver(M_, options_, oo_);
if next_period > 0
yy = [yy oo_.endo_simul(:, 2:next_period-this_period+1)];
else

View File

@ -206,7 +206,7 @@ if info(1) == 0 %no errors in solution
options_ident_local.no_identification_spectrum = 1; %do not recompute dSPECTRUM
options_ident_local.ar = nlags; %store new lag number
options_.ar = nlags; %store new lag number
[~, ~, ~, ~, ~, ~, MOMENTS, dMOMENTS, ~, ~, ~, ~] = identification.get_jacobians(estim_params_, M_, options_, options_ident_local, indpmodel, indpstderr, indpcorr, indvobs, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
[~, ~, ~, ~, ~, ~, MOMENTS, dMOMENTS] = identification.get_jacobians(estim_params_, M_, options_, options_ident_local, indpmodel, indpstderr, indpcorr, indvobs, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
ind_dMOMENTS = (find(max(abs(dMOMENTS'),[],1) > tol_deriv)); %new index with non-zero rows
end

View File

@ -86,7 +86,7 @@ else
Xparnonzero = Xpar(:,ind1); % focus on non-zero columns
end
[eu, ee2, ee1] = svd( [Xparnonzero Xrest], 0 );
[~, ~, ee1] = svd( [Xparnonzero Xrest], 0 );
condX = cond([Xparnonzero Xrest]);
rankX = rank(X, tol_rank);
icheck = 0; %initialize flag which is equal to 0 if we already found all single parameters that are not identified
@ -94,7 +94,7 @@ if param_nbr > 0 && (rankX<rankrequired)
% search for singular values associated to ONE individual parameter
% Compute an orthonormal basis for the null space using the columns of ee1 that correspond
% to singular values equal to zero and associated to an individual parameter
ee0 = [rankX+1:size([Xparnonzero Xrest],2)]; %look into last columns with singular values of problematic parameter sets (except single parameters)
ee0 = rankX+1:size([Xparnonzero Xrest],2); %look into last columns with singular values of problematic parameter sets (except single parameters)
ind11 = ones(length(ind1),1); %initialize
for j=1:length(ee0)
% check if nullspace is spanned by only one parameter
@ -118,7 +118,7 @@ if icheck
else
Xparnonzero = Xpar(:,ind1); % focus on non-zero columns
end
[eu, ee2, ee1] = svd( [Xparnonzero Xrest], 0 );
[~, ~, ee1] = svd( [Xparnonzero Xrest], 0 );
condX = cond([Xparnonzero Xrest]);
rankX = rank(X,tol_rank);
end
@ -151,9 +151,9 @@ if param_nbr>0 && (rankX<rankrequired || min(1-Mco)<tol_rank)
if length(ind1)<param_nbr
% single parameters with zero columns
ixno = ixno + 1;
indno(ixno,:) = (~ismember([1:param_nbr],ind1));
indno(ixno,:) = (~ismember(1:param_nbr,ind1));
end
ee0 = [rankX+1:size([Xparnonzero Xrest],2)]; %look into last columns with singular values of problematic parameter sets (except single parameters)
ee0 = rankX+1:size([Xparnonzero Xrest],2); %look into last columns with singular values of problematic parameter sets (except single parameters)
for j=1:length(ee0)
% linearly dependent parameters
ixno = ixno + 1;

View File

@ -54,7 +54,7 @@ tol_rank = options_ident.tol_rank;
checks_via_subsets = options_ident.checks_via_subsets;
%% Display settings
disp([' ']),
disp(' '),
fprintf('Note that differences in the criteria could be due to numerical settings,\n')
fprintf('numerical errors or the method used to find problematic parameter sets.\n')
fprintf('Settings:\n')
@ -157,7 +157,7 @@ for jide = 1:4
disp(' !!!WARNING!!!');
if SampleSize>1
if non_minimal_state_space_error
fprintf(['\n The minimal state space could not be computed for %u out of %u cases.\n'],SampleSize-EffectiveSampleSize,SampleSize);
fprintf('\n The minimal state space could not be computed for %u out of %u cases.\n',SampleSize-EffectiveSampleSize,SampleSize);
end
if jide==2
if sum(ide.ino & ide.minimal_state_space)>0

View File

@ -209,7 +209,7 @@ function [mSYS,U] = minrealold(SYS,tol)
a = SYS.A;
b = SYS.B;
c = SYS.C;
[ns,nu] = size(b);
[ns,~] = size(b);
[am,bm,cm,U,k] = ControllabilityStaircaseRosenbrock(a,b,c,tol);
kk = sum(k);
nu = ns - kk;
@ -219,7 +219,7 @@ function [mSYS,U] = minrealold(SYS,tol)
cm = cm(:,nu+1:ns);
ns = ns - nu;
if ns
[am,bm,cm,t,k] = ObservabilityStaircaseRosenbrock(am,bm,cm,tol);
[am,bm,cm,~,k] = ObservabilityStaircaseRosenbrock(am,bm,cm,tol);
kk = sum(k);
nu = ns - kk;
nn = nn + nu;
@ -242,8 +242,8 @@ end
function [abar,bbar,cbar,t,k] = ControllabilityStaircaseRosenbrock(a, b, c, tol)
% Controllability staircase algorithm of Rosenbrock, 1968
[ra,ca] = size(a);
[rb,cb] = size(b);
[ra,~] = size(a);
[~,cb] = size(b);
ptjn1 = eye(ra);
ajn1 = a;
bjn1 = b;
@ -255,8 +255,8 @@ function [abar,bbar,cbar,t,k] = ControllabilityStaircaseRosenbrock(a, b, c, tol)
tol = ra*norm(a,1)*eps;
end
for jj = 1 : ra
[uj,sj,vj] = svd(bjn1);
[rsj,csj] = size(sj);
[uj,sj] = svd(bjn1);
[rsj,~] = size(sj);
%p = flip(eye(rsj),2);
p = eye(rsj);
p = p(:,end:-1:1);
@ -264,7 +264,7 @@ function [abar,bbar,cbar,t,k] = ControllabilityStaircaseRosenbrock(a, b, c, tol)
uj = uj*p;
bb = uj'*bjn1;
roj = rank(bb,tol);
[rbb,cbb] = size(bb);
[rbb,~] = size(bb);
sigmaj = rbb - roj;
sigmajn1 = sigmaj;
k(jj) = roj;

View File

@ -78,7 +78,7 @@ else
end
%% compute Kalman transition matrices and steady state with updated parameters
[dr,info,M_.params] = compute_decision_rules(M_,options_,dr, steady_state, exo_steady_state, exo_det_steady_state);
[dr,~,M_.params] = compute_decision_rules(M_,options_,dr, steady_state, exo_steady_state, exo_det_steady_state);
options_ = rmfield(options_,'options_ident');
pruned = pruned_SS.pruned_state_space_system(M_, options_, dr, indvar, nlags, useautocorr, 0);

View File

@ -493,7 +493,7 @@ else
post_median=NaN(1,nparam);
hpd_interval=NaN(nparam,2);
for i=1:nparam
[~, post_median(:,i), ~, hpd_interval(i,:)] = posterior_moments(VVV(:,i),0,0.9);
[~, post_median(:,i), ~, hpd_interval(i,:)] = posterior_moments(VVV(:,i),0.9);
end
bar(post_median)
hold on, plot(hpd_interval,'--*r'),

View File

@ -302,7 +302,7 @@ options_.mode_compute = 0;
options_.plot_priors = 0;
options_.smoother = 1;
options_.options_ident = [];
[dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_, bayestopt_, bounds] = dynare_estimation_init(M_.endo_names, fname, 1, M_, options_, oo_, estim_params_, bayestopt_);
[~, dataset_info, ~, ~, M_, options_, oo_, estim_params_, bayestopt_] = dynare_estimation_init(M_.endo_names, fname, 1, M_, options_, oo_, estim_params_, bayestopt_);
% set method to compute identification Jacobians (kronflag). Default:0
options_ident = set_default_option(options_ident,'analytic_derivation_mode', options_.analytic_derivation_mode); % if not set by user, inherit default global one
@ -470,7 +470,7 @@ if iload <=0
end
options_ident.tittxt = parameters; %title text for graphs and figures
% perform identification analysis for single point
[ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, derivatives_info_point, info, error_indicator_point] = ...
[ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, ~, info, error_indicator_point] = ...
identification.analysis(M_,options_,oo_,bayestopt_,estim_params_,params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end implies initialization of persistent variables
if info(1)~=0
% there are errors in the solution algorithm
@ -487,7 +487,7 @@ if iload <=0
params = Prior.draw();
options_ident.tittxt = 'Random_prior_params'; %title text for graphs and figures
% perform identification analysis
[ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, derivatives_info_point, info, error_indicator_point] = ...
[ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, ~, info, error_indicator_point] = ...
identification.analysis(M_,options_,oo_,bayestopt_,estim_params_,params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1);
end
end
@ -542,7 +542,7 @@ if iload <=0
end
options_ident.tittxt = []; % clear title text for graphs and figures
% run identification analysis
[ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_dynamic, ide_derivatives_info, info, error_indicator] = ...
[ide_moments, ide_spectrum, ide_minimal, ~, ide_reducedform, ide_dynamic, ~, info, error_indicator] = ...
identification.analysis(M_,options_,oo_,bayestopt_,estim_params_,params, indpmodel, indpstderr, indpcorr, options_MC, dataset_info, prior_exist, 0); % the 0 implies that we do not initialize persistent variables anymore
if iteration==0 && info(1)==0 % preallocate storage in the first admissable run
@ -911,7 +911,7 @@ if SampleSize > 1
fprintf('\nTesting %s.\n',tittxt);
if ~iload
options_ident.tittxt = tittxt; %title text for graphs and figures
[ide_moments_max, ide_spectrum_max, ide_minimal_max, ide_hess_max, ide_reducedform_max, ide_dynamic_max, derivatives_info_max, info_max, error_indicator_max] = ...
[ide_moments_max, ide_spectrum_max, ide_minimal_max, ide_hess_max, ide_reducedform_max, ide_dynamic_max, ~, ~, error_indicator_max] = ...
identification.analysis(M_,options_,oo_,bayestopt_,estim_params_,pdraws(jmax,:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end initializes some persistent variables
save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_max', 'ide_moments_max', 'ide_spectrum_max', 'ide_minimal_max','ide_reducedform_max', 'ide_dynamic_max', 'jmax', '-append');
end
@ -978,4 +978,4 @@ end
%reset warning state
warning_config;
fprintf('\n==== Identification analysis completed ====\n\n')
fprintf('\n==== Identification analysis completed ====\n\n')

View File

@ -1,22 +1,28 @@
function oo_ = Jtest(xparam, objective_function, Woptflag, oo_, options_mom_, bayestopt_, Bounds, estim_params_, M_, nobs)
% function oo_ = Jtest(xparam, objective_function, Woptflag, oo_, options_mom_, bayestopt_, Bounds, estim_params_, M_, nobs)
function J_test = Jtest(xparam, objective_function, Q, model_moments, m_data, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% J_test = Jtest(xparam, objective_function, Q, model_moments, m_data, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% -------------------------------------------------------------------------
% Computes the J-test statistic and p-value given a GMM/SMM estimation
% -------------------------------------------------------------------------
% Computes the J-test statistic and p-value for a GMM/SMM estimation
% =========================================================================
% INPUTS
% xparam: [vector] estimated parameter vector
% objective_function: [function handle] objective function
% Woptflag: [logical] flag if optimal weighting matrix has already been computed
% oo_: [struct] results
% options_mom_: [struct] options
% bayestopt_: [struct] information on priors
% Bounds: [struct] bounds on parameters
% estim_params_: [struct] information on estimated parameters
% M_: [struct] information on the model
% nobs: [scalar] number of observations
% xparam: [vector] estimated parameter vector
% objective_function: [function handle] objective function
% Q: [scalar] value of moments distance criterion
% model_moments: [vector] model moments
% m_data: [matrix] selected empirical moments at each point in time
% data_moments: [vector] empirical moments
% weighting_info: [struct] information on weighting matrix
% options_mom_: [struct] options
% M_: [struct] model information
% estim_params_: [struct] estimated parameters
% bayestopt_: [struct] info on prior distributions
% BoundsInfo: [struct] info bounds on parameters
% dr: [struct] reduced form model
% endo_steady_state: [vector] steady state of endogenous variables (initval)
% exo_steady_state: [vector] steady state of exogenous variables (initval)
% exo_det_steady_state: [vector] steady state of deterministic exogenous variables (initval)
% -------------------------------------------------------------------------
% OUTPUT
% oo_: [struct] updated results
% J_test: [struct] results of J test
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
@ -24,7 +30,8 @@ function oo_ = Jtest(xparam, objective_function, Woptflag, oo_, options_mom_, ba
% This function calls
% o mom.objective_function
% o mom.optimal_weighting_matrix
% =========================================================================
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
@ -41,27 +48,26 @@ function oo_ = Jtest(xparam, objective_function, Woptflag, oo_, options_mom_, ba
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
if options_mom_.mom.mom_nbr > length(xparam)
% Get optimal weighting matrix for J test, if necessary
if ~Woptflag
W_opt = mom.optimal_weighting_matrix(oo_.mom.m_data, oo_.mom.model_moments, options_mom_.mom.bartlett_kernel_lag);
oo_J = oo_;
oo_J.mom.Sw = chol(W_opt);
fval = feval(objective_function, xparam, Bounds, oo_J, estim_params_, M_, options_mom_);
if ~weighting_info.Woptflag
W_opt = mom.optimal_weighting_matrix(m_data, model_moments, options_mom_.mom.bartlett_kernel_lag);
weighting_info.Sw = chol(W_opt);
fval = feval(objective_function, xparam, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
else
fval = oo_.mom.Q;
fval = Q;
end
% Compute J statistic
if strcmp(options_mom_.mom.mom_method,'SMM')
Variance_correction_factor = options_mom_.mom.variance_correction_factor;
variance_correction_factor = options_mom_.mom.variance_correction_factor;
elseif strcmp(options_mom_.mom.mom_method,'GMM')
Variance_correction_factor = 1;
variance_correction_factor = 1;
end
oo_.mom.J_test.j_stat = nobs*Variance_correction_factor*fval/options_mom_.mom.weighting_matrix_scaling_factor;
oo_.mom.J_test.degrees_freedom = length(oo_.mom.model_moments)-length(xparam);
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);
J_test.j_stat = options_mom_.nobs*variance_correction_factor*fval/options_mom_.mom.weighting_matrix_scaling_factor;
J_test.degrees_freedom = length(model_moments)-length(xparam);
J_test.p_val = 1-chi2cdf(J_test.j_stat, J_test.degrees_freedom);
fprintf('\nValue of J-test statistic: %f\n',J_test.j_stat);
fprintf('p-value of J-test statistic: %f\n',J_test.p_val);
end

View File

@ -0,0 +1,57 @@
function [irf_matching_file_name, irf_matching_file_path] = check_irf_matching_file(irf_matching_file)
% [irf_matching_file_name, irf_matching_file_path] = check_irf_matching_file(irf_matching_file)
% -------------------------------------------------------------------------
% Check if the provided irf_matching_file is a valid MATLAB function with
% .m extension and return name, path and extension of the file.
% -------------------------------------------------------------------------
% INPUTS
% - irf_matching_file: [string] user provided name (with possible path and extension)
% of the MATLAB function that transforms model IRFs
% -------------------------------------------------------------------------
% OUTPUTS
% - irf_matching_file_name: [string] name of the MATLAB function (without extension)
% - irf_matching_file_path: [string] path to irf_matching_file_name
% -------------------------------------------------------------------------
% This function is called by
% - mom.run
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% 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
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
if isempty(irf_matching_file)
% no irf_matching_file provided, so no transformations will be done
irf_matching_file_name = '';
irf_matching_file_path = '';
else
[irf_matching_file_path, irf_matching_file_name, irf_matching_file_ext] = fileparts(irf_matching_file);
% make sure file is a MATLAB function with .m extension
if ~strcmp(irf_matching_file_ext,'.m')
if strcmp(irf_matching_file_ext,'')
irf_matching_file_ext = '.m';
else
error('method_of_moments: ''irf_matching_file'' needs to point towards a MATLAB function with extension ''.m''!');
end
end
if isempty(irf_matching_file_path)
irf_matching_file_path = '.';
end
if exist([irf_matching_file_path filesep irf_matching_file_name irf_matching_file_ext],'file') ~= 2
error('method_of_moments: Could not find a ''irf_matching_file'' called ''%s''!',[irf_matching_file_path filesep irf_matching_file_name irf_matching_file_ext]);
end
end

View File

@ -1,33 +1,33 @@
function options_mom_ = default_option_mom_values(options_mom_, options_, dname, doBayesianEstimation)
% function options_mom_ = default_option_mom_values(options_mom_, options_, dname, doBayesianEstimation)
% Returns structure containing the options for method_of_moments command
% 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.
% =========================================================================
function options_mom_ = default_option_mom_values(options_mom_, options_, dname, do_bayesian_estimation)
% options_mom_ = default_option_mom_values(options_mom_, options_, dname, do_bayesian_estimation)
% -------------------------------------------------------------------------
% Returns structure containing the options for method_of_moments command.
% Note 1: 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.
% Note 2: we call a "mode" the minimum of the objective function, i.e.
% the parameter vector that minimizes the distance between the moments/IRFs
% computed from the model and the moments/IRFs computed from the data.
% -------------------------------------------------------------------------
% INPUTS
% o options_mom_: [structure] information about all (user-specified and updated) settings used in estimation (options_mom_)
% o options_: [structure] information on global options
% o dname: [string] name of directory to store results
% o doBayesianEstimation [boolean] indicator whether we do Bayesian estimation
% o options_mom_: [structure] all user-specified settings (from the method_of_moments command)
% o options_: [structure] global options
% o dname: [string] default name of directory to store results
% o do_bayesian_estimation [boolean] indicator whether we do Bayesian estimation
% -------------------------------------------------------------------------
% OUTPUTS
% o oo_: [structure] storage for results (oo_)
% o options_mom_: [structure] information about all (user-specified and updated) settings used in estimation (options_mom_)
% o options_mom_: [structure] all user-specified and updated settings required for method_of_moments estimation
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% -------------------------------------------------------------------------
% This function calls
% o set_default_option
% o user_has_matlab_license
% o user_has_octave_forge_package
% o set_default_option
% o user_has_matlab_license
% o user_has_octave_forge_package
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
@ -46,34 +46,43 @@ function options_mom_ = default_option_mom_values(options_mom_, options_, dname,
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
mom_method = options_mom_.mom.mom_method; % this is a required option
% -------------------------------------------------------------------------
% LIMITATIONS
% -------------------------------------------------------------------------
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.')
error('method_of_moments: The loglinear option is not supported. Please append the required logged variables as auxiliary equations.');
else
options_mom_.logged_steady_state = 0;
options_mom_.loglinear = false;
end
options_mom_.hessian.use_penalized_objective = false; % penalized objective not yet
% options related to variable declarations
if isfield(options_,'trend_coeffs')
error('method_of_moments: %s does not allow for trend in data',mom_method)
if isfield(options_mom_,'hessian') && options_mom_.hessian.use_penalized_objective
warning('method_of_moments: The ''use_penalized_objective_for_hessian'' option is not supported yet and will be skipped.');
end
options_mom_.hessian.use_penalized_objective = false; % penalized objective not yet supported
if isfield(options_,'trend_coeffs')
error('method_of_moments: %s does not allow for trend in data',mom_method);
end
% options related to endogenous prior restrictions are not supported
if ~isempty(options_.endogenous_prior_restrictions.irf) && ~isempty(options_.endogenous_prior_restrictions.moment)
fprintf('method_of_moments: Endogenous prior restrictions are not supported yet and will be skipped.\n')
warning('method_of_moments: Endogenous prior restrictions are not supported yet and will be skipped.');
end
options_mom_.endogenous_prior_restrictions.irf = {};
options_mom_.endogenous_prior_restrictions.moment = {};
options_mom_.mom.analytic_jacobian_optimizers = [1, 3, 4, 13, 101]; % these are currently supported optimizers that are able to use the analytical_jacobian option
if isfield(options_mom_,'bayesian_irf') && options_mom_.bayesian_irf % do we need this at all??
warning('method_of_moments: The ''bayesian_irf'' option is not supported yet and will be skipped.');
end
options_mom_.bayesian_irf = false;
if strcmp(mom_method,'IRF_MATCHING')
if isfield(options_mom_.mom,'penalized_estimator') && options_mom_.mom.penalized_estimator
warning('method_of_moments: The ''penalized_estimator'' option is not supported yet for IRF_MATCHING and will be ignored.');
end
options_mom_.mom.penalized_estimator = false;
end
% -------------------------------------------------------------------------
% OPTIONS POSSIBLY SET BY THE USER
@ -87,8 +96,7 @@ options_mom_ = set_default_option(options_mom_,'nograph',false); % do no
options_mom_ = set_default_option(options_mom_,'noprint',false); % do not print output to console
options_mom_ = set_default_option(options_mom_,'TeX',false); % print TeX tables and graphics
options_mom_.mom = set_default_option(options_mom_.mom,'verbose',false); % display and store intermediate estimation results
%options_mom_ = set_default_option(options_mom_,'verbosity',false); %
if doBayesianEstimation
if do_bayesian_estimation
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
end
@ -111,6 +119,16 @@ end
if strcmp(mom_method,'GMM')
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.
end
if strcmp(mom_method,'IRF_MATCHING')
if ~isfield(options_mom_.mom,'irf_matching_file')
options_mom_.mom.irf_matching_file = []; % irf_matching file enables to transform model IRFs before matching them to data IRFs
end
options_mom_.mom.irf_matching_file = set_default_option(options_mom_.mom.irf_matching_file,'name','');
options_mom_.mom = set_default_option(options_mom_.mom,'simulation_method','STOCH_SIMUL'); % simulation method used to compute IRFs
options_mom_ = set_default_option(options_mom_,'add_tiny_number_to_cholesky',1e-14); % add tiny number to Cholesky factor to avoid numerical problems when computing IRFs
options_mom_ = set_default_option(options_mom_,'drop',100); % truncation / burnin for order>1 irf simulations
options_mom_ = set_default_option(options_mom_,'relative_irf',false); % requests the computation of normalized IRFs
end
% data related options
if strcmp(mom_method,'GMM') || strcmp(mom_method,'SMM')
@ -123,12 +141,14 @@ if strcmp(mom_method,'GMM') || strcmp(mom_method,'SMM')
end
% optimization related
if (isoctave && user_has_octave_forge_package('optim')) || (~isoctave && user_has_matlab_license('optimization_toolbox'))
if strcmp(mom_method,'GMM') || strcmp(mom_method,'SMM')
if strcmp(mom_method,'GMM') || strcmp(mom_method,'SMM')
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
else
options_mom_ = set_default_option(options_mom_,'mode_compute',5); % specifies newrat as fallback default option for minimization
end
else
options_mom_ = set_default_option(options_mom_,'mode_compute',4); % specifies csminwel as fallback default option for minimization
elseif strcmp(mom_method,'IRF_MATCHING')
options_mom_ = set_default_option(options_mom_,'mode_compute',5); % specifies newrat as fallback default option for minimization
end
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
@ -136,9 +156,20 @@ options_mom_ = set_default_option(options_mom_,'silent_optimizer',false);
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
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
options_mom_.optimizer_vec = [options_mom_.mode_compute;num2cell(options_mom_.additional_optimizer_steps)];
options_mom_.mom.analytic_jacobian_optimizers = [1, 3, 4, 13, 101]; % these are currently supported optimizers that are able to use the analytic_jacobian option
options_mom_.analytic_derivation = 0; % force to 0 as we check this seperately in dynare_minimize_objective.m
options_mom_ = set_default_option(options_mom_,'mode_file',''); % name of the file containing initial values for the mode
options_mom_ = set_default_option(options_mom_,'cova_compute',true); % 1: computed covariance via Hessian after the computation of the mode, 0: turn off computation of covariance matrix
% perturbation related
options_mom_ = set_default_option(options_mom_,'order',1); % order of Taylor approximation in perturbation
if strcmp(mom_method,'IRF_MATCHING') % number of simulated series used to compute IRFs
if options_mom_.order == 1
options_mom_ = set_default_option(options_mom_,'replic',1);
else
options_mom_ = set_default_option(options_mom_,'replic',50);
end
end
options_mom_ = set_default_option(options_mom_,'pruning',false); % use pruned state space system at order>1
options_mom_ = set_default_option(options_mom_,'aim_solver',false); % use AIM algorithm to compute perturbation approximation instead of mjdgges
options_mom_ = set_default_option(options_mom_,'k_order_solver',false); % use k_order_perturbation instead of mjdgges
@ -161,12 +192,121 @@ options_mom_ = set_default_option(options_mom_,'lyapunov_complex_threshold',1e-1
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
% mode check plot
% Bayesian MCMC related
if do_bayesian_estimation
options_mom_ = set_default_option(options_mom_,'mh_replic',0); % number of draws in Metropolis-Hastings and slice samplers
options_mom_ = set_default_option(options_mom_,'mh_posterior_mode_estimation',false); % skip optimizer-based mode-finding and instead compute the mode based on a run of a MCMC
options_mom_ = set_default_option(options_mom_,'load_mh_file',false); % add to previous Metropolis-Hastings or slice simulations instead of starting from scratch
options_mom_ = set_default_option(options_mom_,'load_results_after_load_mh',false); % load the previously computed convergence diagnostics, marginal data density, and posterior statistics from an existing mom_results file instead of recomputing them
if options_mom_.mh_replic > 0 || options_mom_.load_mh_file
options_mom_ = set_default_option(options_mom_,'sub_draws',[]);
options_mom_ = set_default_option(options_mom_,'posterior_max_subsample_draws',1200);
options_mom_ = set_default_option(options_mom_,'mh_nblck',2); % number of parallel chains for Metropolis-Hastings or slice algorithm
options_mom_ = set_default_option(options_mom_,'mh_drop',0.5); % fraction of initially generated parameter vectors to be dropped as a burn-in before using posterior simulations
options_mom_ = set_default_option(options_mom_,'mh_conf_sig',0.9); % confidence/HPD interval used for the computation of prior and posterior statistics
options_mom_ = set_default_option(options_mom_,'mh_recover',false); % attempts to recover a Metropolis-Hastings simulation that crashed prematurely
options_mom_ = set_default_option(options_mom_,'MCMC_jumping_covariance','hessian'); % which covariance to use for the proposal density of the MCMC sampler
if ~isfield(options_mom_,'mh_initialize_from_previous_mcmc')
options_mom_.mh_initialize_from_previous_mcmc.status = false; % pick initial values for new MCMC from a previous one
end
options_mom_.mh_initialize_from_previous_mcmc = set_default_option(options_mom_.mh_initialize_from_previous_mcmc,'directory',''); % pick initial values for new MCMC from a previous one: directory
options_mom_.mh_initialize_from_previous_mcmc = set_default_option(options_mom_.mh_initialize_from_previous_mcmc,'record',''); % pick initial values for new MCMC from a previous one: record file name
options_mom_.mh_initialize_from_previous_mcmc = set_default_option(options_mom_.mh_initialize_from_previous_mcmc,'prior',''); % pick initial values for new MCMC from a previous one: prior file name
if ~isfield(options_mom_,'posterior_sampler_options')
options_mom_.posterior_sampler_options = [];
end
options_mom_.posterior_sampler_options = set_default_option(options_mom_.posterior_sampler_options,'posterior_sampling_method','random_walk_metropolis_hastings'); % selects the sampler used to sample from the posterior distribution during Bayesian estimation
options_mom_.posterior_sampler_options = set_default_option(options_mom_.posterior_sampler_options,'sampling_opt',[]); % used to set options for the posterior sampling methods
switch options_mom_.posterior_sampler_options.posterior_sampling_method
case 'random_walk_metropolis_hastings'
if ~isfield(options_mom_.posterior_sampler_options,'rwmh')
options_mom_.posterior_sampler_options.rwmh = [];
end
options_mom_.posterior_sampler_options.rwmh = set_default_option(options_mom_.posterior_sampler_options.rwmh,'proposal_distribution','rand_multivariate_normal');
options_mom_.posterior_sampler_options.rwmh = set_default_option(options_mom_.posterior_sampler_options.rwmh,'student_degrees_of_freedom',3);
options_mom_.posterior_sampler_options.rwmh = set_default_option(options_mom_.posterior_sampler_options.rwmh,'use_mh_covariance_matrix',false);
options_mom_.posterior_sampler_options.rwmh = set_default_option(options_mom_.posterior_sampler_options.rwmh,'save_tmp_file',false);
case 'tailored_random_block_metropolis_hastings'
if ~isfield(options_mom_.posterior_sampler_options,'tarb')
options_mom_.posterior_sampler_options.tarb = [];
end
options_mom_.posterior_sampler_options.tarb = set_default_option(options_mom_.posterior_sampler_options.tarb,'proposal_distribution','rand_multivariate_normal');
options_mom_.posterior_sampler_options.tarb = set_default_option(options_mom_.posterior_sampler_options.tarb,'student_degrees_of_freedom',3);
options_mom_.posterior_sampler_options.tarb = set_default_option(options_mom_.posterior_sampler_options.tarb,'mode_compute',4);
options_mom_.posterior_sampler_options.tarb = set_default_option(options_mom_.posterior_sampler_options.tarb,'new_block_probability',0.25);
options_mom_.posterior_sampler_options.tarb = set_default_option(options_mom_.posterior_sampler_options.tarb,'optim_opt','');
options_mom_.posterior_sampler_options.tarb = set_default_option(options_mom_.posterior_sampler_options.tarb,'save_tmp_file',true);
case 'slice'
if ~isfield(options_mom_.posterior_sampler_options,'slice')
options_mom_.posterior_sampler_options.slice = [];
end
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'proposal_distribution','');
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'rotated',0);
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'slice_initialize_with_mode',false); % must be used with rotated
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'use_mh_covariance_matrix',false); % must be used with rotated
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'WR',[]);
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'mode_files',[]);
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'mode',[]);
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'initial_step_size',0.8);
options_mom_.posterior_sampler_options.slice = set_default_option(options_mom_.posterior_sampler_options.slice,'save_tmp_file',true);
case 'independent_metropolis_hastings'
if ~isfield(options_mom_.posterior_sampler_options,'imh')
options_mom_.posterior_sampler_options.imh = [];
end
options_mom_.posterior_sampler_options.imh = set_default_option(options_mom_.posterior_sampler_options.imh,'proposal_distribution','rand_multivariate_normal');
options_mom_.posterior_sampler_options.imh = set_default_option(options_mom_.posterior_sampler_options.imh,'use_mh_covariance_matrix',false);
options_mom_.posterior_sampler_options.imh = set_default_option(options_mom_.posterior_sampler_options.imh,'save_tmp_file',false);
end
if ~strcmp(options_mom_.posterior_sampler_options.posterior_sampling_method,'slice')
options_mom_ = set_default_option(options_mom_,'mh_init_scale_factor',2);
options_mom_ = set_default_option(options_mom_,'mh_jscale',[]);
end
% mh_tune_jscale options
if strcmp(options_mom_.posterior_sampler_options.posterior_sampling_method,'random_walk_metropolis_hastings')
if ~isfield(options_mom_,'mh_tune_jscale')
options_mom_.mh_tune_jscale = [];
end
options_mom_.mh_tune_jscale = set_default_option(options_mom_.mh_tune_jscale,'status',false);
options_mom_.mh_tune_jscale = set_default_option(options_mom_.mh_tune_jscale,'target',0.33);
options_mom_.mh_tune_jscale = set_default_option(options_mom_.mh_tune_jscale,'guess',[]);
options_mom_.mh_tune_jscale.maxiter = options_.mh_tune_jscale.maxiter;
options_mom_.mh_tune_jscale.rho = options_.mh_tune_jscale.rho;
options_mom_.mh_tune_jscale.stepsize = options_.mh_tune_jscale.stepsize;
options_mom_.mh_tune_jscale.c1 = options_.mh_tune_jscale.c1;
options_mom_.mh_tune_jscale.c2 = options_.mh_tune_jscale.c2;
options_mom_.mh_tune_jscale.c3 = options_.mh_tune_jscale.c3;
end
% convergence diagnostics
options_mom_ = set_default_option(options_mom_,'nodiagnostic',false);
if ~isfield(options_mom_,'convergence')
options_mom_.convergence = [];
end
if ~isfield(options_mom_.convergence,'geweke')
options_mom_.convergence.geweke = [];
end
if ~isfield(options_mom_.convergence,'rafterylewis')
options_mom_.convergence.rafterylewis = [];
end
if ~isfield(options_mom_.convergence,'brooksgelman')
options_mom_.convergence.brooksgelman = [];
end
options_mom_.convergence.geweke = set_default_option(options_mom_.convergence.geweke,'taper_steps', [4 8 15]);
options_mom_.convergence.geweke = set_default_option(options_mom_.convergence.geweke,'geweke_interval', [0.2 0.5]);
options_mom_.convergence.rafterylewis = set_default_option(options_mom_.convergence.rafterylewis,'indicator', false);
options_mom_.convergence.rafterylewis = set_default_option(options_mom_.convergence.rafterylewis,'qrs', [0.025 0.005 0.95]);
options_mom_.convergence.brooksgelman = set_default_option(options_mom_.convergence.brooksgelman,'plotrows',3);
end
end
% mode check plot options
options_mom_.mode_check.nolik = false; % we don't do likelihood (also this initializes mode_check substructure)
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.
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)
options_mom_.mode_check = set_default_option(options_mom_.mode_check,'status',false); % plot the target function for values around the computed mode for each estimated parameter in turn. This is helpful to diagnose problems with the optimizer.
options_mom_.mode_check = set_default_option(options_mom_.mode_check,'neighbourhood_size',.5); % width of the window around the computed mode 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 mode. A value of 0 allows to have asymmetric plots, which can be useful if the mode 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 mode where the target function is evaluated (for each parameter)
% -------------------------------------------------------------------------
@ -180,8 +320,12 @@ options_mom_.obs_nbr = length(options_mom_.varobs); % number of observed variabl
% related to call of dynare
options_mom_.console_mode = options_.console_mode;
if options_mom_.console_mode
options_mom_.nodisplay = true;
end
options_mom_.parallel = options_.parallel;
options_mom_.parallel_info = options_.parallel_info;
options_mom_.debug = options_.debug; % debug option is needed by some functions, e.g. check_plot
% related to estimated_params and estimated_params_init blocks
options_mom_.use_calibration_initialization = options_.use_calibration_initialization;
@ -250,19 +394,82 @@ end
options_mom_.gstep = options_.gstep; % needed by hessian.m
options_mom_.trust_region_initial_step_bound_factor = options_.trust_region_initial_step_bound_factor; % used in dynare_solve for trust_region
% other
% miscellaneous
options_mom_.threads = options_.threads;
options_mom_.MaxNumberOfBytes = options_.MaxNumberOfBytes;
%options_mom_.MaximumNumberOfMegaBytes = options_.MaximumNumberOfMegaBytes;
options_mom_.marginal_data_density = options_.marginal_data_density;
% -------------------------------------------------------------------------
% DEFAULT VALUES
% -------------------------------------------------------------------------
options_mom_.analytic_derivation = 0;
options_mom_.mom.compute_derivs = false; % flag to compute derivs in objective function (might change for GMM with either analytic_standard_errors or analytic_jacobian (dependent on optimizer))
options_mom_.mom.vector_output = false; % specifies whether the objective function returns a vector
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)
options_mom_.initialize_estimated_parameters_with_the_prior_mode = 0; % needed by set_prior.m
options_mom_.figures = options_.figures; % needed by plot_priors.m
options_mom_.ramsey_policy = false; % needed by evaluate_steady_state
options_mom_.risky_steadystate = false; % needed by resol
options_mom_.jacobian_flag = true; % needed by dynare_solve
options_mom_.figures = options_.figures; % needed by plot_priors.m
options_mom_.ramsey_policy = false; % needed by evaluate_steady_state
options_mom_.risky_steadystate = false; % needed by resol
options_mom_.jacobian_flag = true; % needed by dynare_solve
options_mom_.use_mh_covariance_matrix = false; % needed by posterior_sampler, get's overwritten by same option in options_mom_.posterior_sampler_options
% -------------------------------------------------------------------------
% CHECKS ON SETTINGS
% -------------------------------------------------------------------------
if strcmp(mom_method,'GMM') || strcmp(mom_method,'SMM')
if numel(options_mom_.nobs) > 1
error('method_of_moments: Recursive estimation is not supported. Please set an integer as ''nobs''!');
end
if numel(options_mom_.first_obs) > 1
error('method_of_moments: Recursive estimation is not supported. Please set an integer as ''first_obs''!');
end
end
if options_mom_.order < 1
error('method_of_moments: The order of the Taylor approximation cannot be 0!')
end
if options_mom_.order > 2
fprintf('Dynare will use ''k_order_solver'' as the order>2\n');
options_mom_.k_order_solver = true;
end
if strcmp(mom_method,'SMM')
if options_mom_.mom.simulation_multiple < 1
fprintf('The simulation horizon is shorter than the data. Dynare resets the simulation_multiple to 7.\n')
options_mom_.mom.simulation_multiple = 7;
end
end
if strcmp(mom_method,'GMM')
% require 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
if options_mom_.order > 3
error('method_of_moments: Perturbation orders higher than 3 are not implemented for GMM estimation, try using SMM!');
end
end
if strcmp(mom_method,'IRF_MATCHING') && do_bayesian_estimation
if isfield(options_mom_,'mh_tune_jscale') && options_mom_.mh_tune_jscale.status && (options_mom_.mh_tune_jscale.maxiter<options_mom_.mh_tune_jscale.stepsize)
warning('method_of_moments: You specified mh_tune_jscale, but the maximum number of iterations is smaller than the step size. No update will take place.')
end
if options_mom_.load_results_after_load_mh
if ~exist([options_mom_.dirname filesep 'method_of_moments' filesep M_.fname '_mom_results.mat'],'file')
fprintf('\nYou specified the ''load_results_after_load_mh'' option, but no ''%s_mom_results.mat'' file\n',M_.fname);
fprintf('was found in the folder %s%smethod_of_moments.\n',options_mom_.dirname,filesep);
fprintf('Results will be recomputed and option ''load_results_after_load_mh'' is reset to false.\n');
options_mom_.load_results_after_load_mh = false;
end
end
if options_mom_.mh_replic>0 && options_mom_.mh_nblck<1
error('method_of_moments: Bayesian MCMC estimation cannot be conducted with ''mh_nblocks''=0!')
end
end
if options_mom_.mom.analytic_jacobian && ~strcmp(mom_method,'GMM')
options_mom_.mom.analytic_jacobian = false;
fprintf('\n''analytic_jacobian'' option will be dismissed as it only works with GMM.\n');
end
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
if any(cellfun(@(x) isnumeric(x) && any(x == 13), options_mom_.optimizer_vec))
error('method_of_moments: lsqnonlin (mode_compute=13) is not yet supported for IRF matching!');
end
end

View File

@ -1,74 +0,0 @@
function display_comparison_moments(M_, options_mom_, data_moments, model_moments)
% function display_comparison_moments(M_, options_mom_, data_moments, model_moments)
% -------------------------------------------------------------------------
% Displays and saves to disk the comparison of the data moments and the model moments
% =========================================================================
% INPUTS
% M_: [structure] model information
% options_mom_: [structure] method of moments options
% data_moments: [vector] data moments
% model_moments: [vector] model moments
% -------------------------------------------------------------------------
% OUTPUT
% No output, just displays and saves to disk the comparison of the data moments and the model moments
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% -------------------------------------------------------------------------
% This function calls
% o dyn_latex_table
% o dyntable
% o cellofchararraymaxlength
% =========================================================================
% Copyright © 2023 Dynare Team
%
% 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
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
titl = ['Comparison of matched 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 = [data_moments model_moments];
dyntable(options_mom_, titl, headers, labels, data_mat, cellofchararraymaxlength(labels)+2, 10, 7);
if options_mom_.TeX
dyn_latex_table(M_, options_mom_, titl, ['comparison_moments_', options_mom_.mom.mom_method], headers, labels_TeX, data_mat, cellofchararraymaxlength(labels)+2, 10, 7);
end

View File

@ -0,0 +1,96 @@
function display_comparison_moments_irfs(M_, options_mom_, data_moments, model_moments)
% display_comparison_moments_irfs(M_, options_mom_, data_moments, model_moments)
% -------------------------------------------------------------------------
% Displays and saves to disk the comparison of the data moments/IRFs and the model moments/IRFs
% -------------------------------------------------------------------------
% INPUTS
% M_: [structure] model information
% options_mom_: [structure] method of moments options
% data_moments: [vector] data moments
% model_moments: [vector] model moments
% -------------------------------------------------------------------------
% OUTPUT
% No output, just displays and saves to disk the comparison of the data moments and the model moments
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% -------------------------------------------------------------------------
% This function calls
% o dyn_latex_table
% o dyntable
% o cellofchararraymaxlength
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% 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
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
titl = upper('Comparison of matched data IRFs and model IRFs');
headers = {'IRF','Data','Model'};
idx = 1;
for jj = 1:size(M_.matched_irfs,1)
irf_varname = M_.matched_irfs{jj,1};
irf_shockname = M_.matched_irfs{jj,2};
% note that periods can span over multiple rows
IRF_PERIODS = [];
for kk = 1:size(M_.matched_irfs{jj,3},1)
irf_periods = M_.matched_irfs{jj,3}{kk,1};
IRF_PERIODS = [IRF_PERIODS; irf_periods(:)];
end
for hh = 1:length(IRF_PERIODS)
labels{idx,1} = sprintf('%s %s (%u)',irf_varname,irf_shockname,IRF_PERIODS(hh));
labels_TeX{idx,1} = sprintf('%s %s (%u)',M_.endo_names_tex{ismember(M_.endo_names,irf_varname)},M_.exo_names_tex{ismember(M_.exo_names,irf_shockname)},IRF_PERIODS(hh));
idx = idx+1;
end
end
else
titl = ['Comparison of matched 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
end
data_mat = [data_moments model_moments];
dyntable(options_mom_, titl, headers, labels, data_mat, cellofchararraymaxlength(labels)+2, 10, 7);
if options_mom_.TeX
dyn_latex_table(M_, options_mom_, titl, ['comparison_moments_', options_mom_.mom.mom_method], headers, labels_TeX, data_mat, cellofchararraymaxlength(labels)+2, 10, 7);
end

View File

@ -1,7 +1,8 @@
function [dataMoments, m_data] = get_data_moments(data, obs_var, inv_order_var, matched_moments_, options_mom_)
% [dataMoments, m_data] = get_data_moments(data, obs_var, inv_order_var, matched_moments_, options_mom_)
% This function computes the user-selected empirical moments from data
% =========================================================================
function [data_moments, m_data] = get_data_moments(data, obs_var, inv_order_var, matched_moments_, options_mom_)
% [data_moments, m_data] = get_data_moments(data, obs_var, inv_order_var, matched_moments_, options_mom_)
% -------------------------------------------------------------------------
% Computes the user-selected empirical moments from data
% -------------------------------------------------------------------------
% INPUTS
% o data [T x varobs_nbr] data set
% o obs_var: [integer] index of observables
@ -10,13 +11,14 @@ function [dataMoments, m_data] = get_data_moments(data, obs_var, inv_order_var,
% o options_mom_: [structure] information about all settings (specified by the user, preprocessor, and taken from global options_)
% -------------------------------------------------------------------------
% OUTPUTS
% o dataMoments [numMom x 1] mean of selected empirical moments
% o data_moments [numMom x 1] mean of selected empirical moments
% o m_data [T x numMom] selected empirical moments at each point in time
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% o mom.objective_function
% =========================================================================
% -------------------------------------------------------------------------
% Copyright © 2020-2023 Dynare Team
%
% This file is part of Dynare.
@ -33,15 +35,11 @@ function [dataMoments, m_data] = get_data_moments(data, obs_var, inv_order_var,
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------
% Author(s):
% o Willi Mutschler (willi@mutschler.eu)
% o Johannes Pfeifer (johannes.pfeifer@unibw.de)
% =========================================================================
% Initialization
T = size(data,1); % Number of observations (T)
dataMoments = NaN(options_mom_.mom.mom_nbr,1);
data_moments = NaN(options_mom_.mom.mom_nbr,1);
m_data = NaN(T,options_mom_.mom.mom_nbr);
% Product moment for each time period, i.e. each row t contains y_t1(l1)^p1*y_t2(l2)^p2*...
% note that here we already are able to treat leads and lags and any power product moments
@ -61,10 +59,10 @@ for jm = 1:options_mom_.mom.mom_nbr
end
% We replace NaN (due to leads and lags and missing values) with the corresponding mean
if isoctave && octave_ver_less_than('8')
dataMoments(jm,1) = nanmean(m_data_tmp);
data_moments(jm,1) = nanmean(m_data_tmp);
else
dataMoments(jm,1) = mean(m_data_tmp,'omitnan');
data_moments(jm,1) = mean(m_data_tmp,'omitnan');
end
m_data_tmp(isnan(m_data_tmp)) = dataMoments(jm,1);
m_data_tmp(isnan(m_data_tmp)) = data_moments(jm,1);
m_data(:,jm) = m_data_tmp;
end

View File

@ -0,0 +1,130 @@
function graph_comparison_irfs(matched_irfs,irf_model_varobs,varobs_id,irf_horizon,relative_irf,endo_names,endo_names_tex,exo_names,exo_names_tex,dname,fname,graph_format,TeX,nodisplay,figures_textwidth)
% graph_comparison_irfs(matched_irfs,irf_model_varobs,varobs_id,irf_horizon,relative_irf,endo_names,endo_names_tex,exo_names,exo_names_tex,dname,fname,graph_format,TeX,nodisplay,figures_textwidth)
% -------------------------------------------------------------------------
% Plots and saves to disk the comparison of the selected data IRFs and corresponding model IRfs
% -------------------------------------------------------------------------
% INPUTS
% matched_irfs: [matrix] information on matched data IRFs
% irf_model_varobs: [matrix] model IRFs for observable variables
% varobs_id: [vector] index for observable variables in endo_names
% irf_horizon: [scalar] maximum horizon of IRFs
% relative_irf: [boolean] if true, plots normalized IRFs
% endo_names: [cell] names of endogenous variables
% endo_names_tex: [cell] names of endogenous variables in latex
% exo_names: [cell] names of exogenous variables
% exo_names_tex: [cell] names of exogenous variables in latex
% dname: [string] name of the directory where to save the graphs
% fname: [string] name of the mod file
% graph_format: [cell] format of the graphs
% TeX: [boolean] if true, uses latex for plots
% nodisplay: [boolean] if true, does not display the graphs
% figures_textwidth: [scalar] textwidth used in plots
% -------------------------------------------------------------------------
% OUTPUT
% No output, just displays and saves to disk the graphs
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% -------------------------------------------------------------------------
% This function calls
% o dyn_figure
% o dyn_saveas
% o remove_fractional_xticks
% o CheckPath
% o pltorg
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% 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
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
graph_directory_name = CheckPath('graphs',dname);
latex_directory_name = CheckPath('latex',dname);
if TeX && any(strcmp('eps',cellstr(graph_format)))
fid_TeX = fopen([latex_directory_name '/' fname '_irf_matching_plot.tex'],'w');
fprintf(fid_TeX,'%% TeX eps-loader file generated by mom.run.m (Dynare).\n');
fprintf(fid_TeX,['%% ' datestr(now,0) '\n']);
fprintf(fid_TeX,' \n');
end
unique_shock_entries = unique(matched_irfs(:, 2));
colDarkGrey = [0.3, 0.3, 0.3]; % dark grey
for jexo = unique_shock_entries' % loop over cell with shock names
unique_variables = unique(matched_irfs(ismember(matched_irfs(:, 2),jexo), 1));
[nbplt,nr,nc,lr,lc,nstar] = pltorg(length(unique_variables));
fig = 0;
for jvar = 1:length(unique_variables)
% get data points, note that periods and values can span over multiple rows
jj = ismember(matched_irfs(:,1), unique_variables(jvar)) & ismember(matched_irfs(:,2), jexo);
IRF_PERIODS = []; IRF_VALUES = [];
for kk = 1:size(matched_irfs{jj,3},1)
irf_periods = matched_irfs{jj,3}{kk,1};
irf_values = matched_irfs{jj,3}{kk,2};
if length(irf_values)==1
irf_values = repmat(irf_values,length(irf_periods),1);
end
IRF_PERIODS = [IRF_PERIODS; irf_periods(:)];
IRF_VALUES = [IRF_VALUES; irf_values(:)];
end
if jvar==1 || ~( (fig-1)*nstar<jvar && jvar<=fig*nstar )
fig = fig+1;
fig_irf = dyn_figure(nodisplay,'Name',['IRF matching shock to ' jexo{:} ' figure ' int2str(fig)]);
end
plt = jvar-(fig-1)*nstar;
if nbplt>1 && fig==nbplt
subplot(lr,lc,plt);
else
subplot(nr,nc,plt);
end
plt_data = plot(IRF_PERIODS,IRF_VALUES,'h', 'MarkerEdgeColor',colDarkGrey,'MarkerFaceColor',colDarkGrey,'MarkerSize',8);
hold on
plt_model = plot(1:irf_horizon, irf_model_varobs(:,varobs_id==find(ismember(endo_names,unique_variables(jvar))) , ismember(exo_names,jexo)),'-k','linewidth',2);
hold on
plot([1 irf_horizon],[0 0],'-r','linewidth',1);
hold off
xlim([1 irf_horizon]);
remove_fractional_xticks
if TeX
title(['$' endo_names_tex{ismember(endo_names,unique_variables(jvar))} '$'],'Interpreter','latex');
else
title(unique_variables{jvar},'Interpreter','none');
end
set(gca,'FontSize',12);
if (plt==nstar) || jvar==length(unique_variables)
% Adding a legend at the bottom
axes('Position',[0, 0, 1, 1],'Visible','off');
lgd = legend([plt_data,plt_model],{'Data', 'Model'}, 'Location', 'southeast','NumColumns',2,'FontSize',14);
if ~isoctave
lgd.Position = [0.37 0.01 lgd.Position(3) lgd.Position(4)];
end
dyn_saveas(fig_irf,[graph_directory_name filesep fname '_matched_irf_' jexo{:} int2str(fig)],nodisplay,graph_format);
if TeX && any(strcmp('eps',cellstr(graph_format)))
fprintf(fid_TeX,'\\begin{figure}[H]\n');
fprintf(fid_TeX,'\\centering \n');
fprintf(fid_TeX,'\\includegraphics[width=%2.2f\\textwidth]{%s_matched_irf_%s%s}\n',figures_textwidth*min(plt/nc,1),[graph_directory_name '/' fname],jexo{:},int2str(fig));
if relative_irf
fprintf(fid_TeX,'\\caption{Relative impulse response functions (orthogonalized shock to $%s$).}', jexo{:});
else
fprintf(fid_TeX,'\\caption{Impulse response functions (orthogonalized shock to $%s$).}', jexo{:});
end
fprintf(fid_TeX,'\\label{Fig:MatchedIRF:%s:%s}\n', jexo{:},int2str(fig));
fprintf(fid_TeX,'\\end{figure}\n');
fprintf(fid_TeX,' \n');
end
end
end
end

View File

@ -0,0 +1,151 @@
function [data_irfs, weight_mat, irf_index, max_irf_horizon] = matched_irfs_blocks(matched_irfs, matched_irfs_weight, varobs_id, obs_nbr, exo_nbr, endo_names, exo_names)
% [data_irfs, weight_mat, irf_index, max_irf_horizon] = matched_irfs_blocks(matched_irfs, matched_irfs_weight, varobs_id, obs_nbr, exo_nbr, endo_names, exo_names)
% -------------------------------------------------------------------------
% Checks and transforms matched_irfs and matched_irfs_weight blocks
% for further use in the estimation.
% -------------------------------------------------------------------------
% INPUTS
% matched_irfs: [cell array] original matched_irfs block
% matched_irfs_weight: [cell array] original matched_irfs_weight block
% varobs_id: [vector] index for observable variables in endo_names
% obs_nbr: [scalar] number of observable variables
% exo_nbr: [scalar] number of exogenous variables
% endo_names: [cell array] names of endogenous variables
% exo_names: [cell array] names of exogenous variables
% -------------------------------------------------------------------------
% OUTPUT
% data_irfs: [matrix] IRFs for VAROBS as declared in matched_irfs block
% weight_mat: [matrix] weighting matrix for IRFs as declared in matched_irfs_weight block
% irf_index: [vector] index for selecting specific IRFs from full IRF matrix of observables
% max_irf_horizon: [scalar] maximum IRF horizon as declared in matched_irfs block
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% 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
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% note matched_irfs block:
% - each row in the cell contains a unique combination of var and varexo,
% however the third column in each row is a nested cell with information
% on periods, values and weights
% - periods, values and weights can span several rows with different lengths of entries
% - in some cases we need to duplicate values and/or weights
% - at the end we want to have everything vectorized and the same length
% get maximum IRF horizons
max_irf_horizon = [];
for jj = 1:size(matched_irfs,1)
max_irf_horizon = [max_irf_horizon; cell2mat(cellfun(@(c) c(:), matched_irfs{jj,3}(:,1), 'UniformOutput', false))];
end
max_irf_horizon = max(max_irf_horizon);
% create full matrix where 1st dimension are IRF periods, 2nd dimension are variables as declared in VAROBS, 3rd dimension are shocks
% idea: overwrite NaN values if they are declared in matched_irfs block; at the end the remaining NaN values will be removed
data_irfs = NaN(max_irf_horizon,obs_nbr,exo_nbr);
% create full empirical weighting matrix, identity matrix by default, i.e. all IRFs are equally important
% idea: first specify full matrix and then reduce it using only entries that are declared in matched_irfs block
weight_mat = speye(max_irf_horizon*obs_nbr*exo_nbr);
for jj = 1:size(matched_irfs,1)
id_var = find(ismember(endo_names,matched_irfs{jj,1}));
id_varobs = find(varobs_id==id_var,1);
id_shock = find(ismember(exo_names,matched_irfs{jj,2}));
if isempty(id_varobs)
skipline;
error('method_of_moments: You specified an IRF matching involving variable %s, but it is not declared as a varobs!',endo_names{id_var})
end
IRF_PERIODS = []; IRF_VALUES = []; IRF_WEIGHTS = [];
for kk = 1:size(matched_irfs{jj,3},1)
irf_periods = matched_irfs{jj,3}{kk,1};
if length(unique(irf_periods)) < length(irf_periods) % row-specific check for unique periods
error('method_of_moments: You specified an IRF matching involving variable %s and shock %s, but there were duplicate ''periods'' in the specification!',endo_names{id_var},exo_names{id_shock});
end
irf_values = matched_irfs{jj,3}{kk,2};
if length(irf_values)==1
irf_values = repmat(irf_values,length(irf_periods),1);
end
if length(irf_periods) ~= length(irf_values) % row-specific check for enough values
error('method_of_moments: You specified an IRF matching involving variable %s and shock %s, but the length of ''periods'' does not match the length of ''values''!',endo_names{id_var},exo_names{id_shock});
end
irf_weights = matched_irfs{jj,3}{kk,3};
if length(irf_weights)==1
irf_weights = repmat(irf_weights,length(irf_periods),1);
end
if length(irf_periods) ~= length(irf_weights) % row-specific check for enough weights
error('method_of_moments: You specified an IRF matching involving variable %s and shock %s, but the length of ''periods'' does not match the length of ''weights''!',endo_names{id_var},exo_names{id_shock});
end
IRF_PERIODS = [IRF_PERIODS; irf_periods(:)];
IRF_VALUES = [IRF_VALUES; irf_values(:)];
IRF_WEIGHTS = [IRF_WEIGHTS; irf_weights(:)];
end
if length(unique(irf_periods)) < length(irf_periods) % overall check for unique periods
error('method_of_moments: You specified an IRF matching involving variable %s and shock %s, but there were duplicate ''periods'' in the specification!',endo_names{id_var},exo_names{id_shock});
end
for hh = 1:length(IRF_PERIODS)
data_irfs(IRF_PERIODS(hh),id_varobs,id_shock) = IRF_VALUES(hh);
if IRF_WEIGHTS(hh) ~= 1
idweight_mat = sub2ind(size(data_irfs),IRF_PERIODS(hh),id_varobs,id_shock);
weight_mat(idweight_mat,idweight_mat) = IRF_WEIGHTS(hh);
end
end
end
% fine-tune weighting matrix using matched_irfs_weights
for jj = 1:size(matched_irfs_weight,1)
id_var1 = find(ismember(endo_names,matched_irfs_weight{jj,1}));
id_var2 = find(ismember(endo_names,matched_irfs_weight{jj,4}));
id_varobs1 = find(varobs_id==id_var1,1);
id_varobs2 = find(varobs_id==id_var2,1);
if isempty(id_varobs1)
skipline;
error('method_of_moments: You specified a weight for an IRF matching involving variable %s, but it is not a varobs!',endo_names{id_var1})
end
if isempty(id_varobs2)
skipline;
error('method_of_moments: You specified a weight for an IRF matching involving variable %s, but it is not a varobs!',endo_names{id_var2})
end
id_shock1 = find(ismember(exo_names,matched_irfs_weight{jj,3}));
id_shock2 = find(ismember(exo_names,matched_irfs_weight{jj,6}));
irf_periods1 = matched_irfs_weight{jj,2};
irf_periods2 = matched_irfs_weight{jj,5};
if length(irf_periods1) ~= length(irf_periods2)
error('method_of_moments: You specified a ''matched_irfs_weights'' entry for an IRF matching involving %s/%s and %s/%s,\n but the horizons do not have the same length!',endo_names{id_var1},exo_names{id_shock1},endo_names{id_var2},exo_names{id_shock2});
end
if max([irf_periods1(:);irf_periods2(:)]) > max_irf_horizon
error('method_of_moments: You specified a ''matched_irfs_weights'' entry for an IRF matching involving %s/%s and %s/%s,\n but the horizon is larger than the maximum one declared in the ''matched_irfs'' block!',endo_names{id_var1},exo_names{id_shock1},endo_names{id_var2},exo_names{id_shock2});
end
weight_mat_values = matched_irfs_weight{jj,7};
if length(weight_mat_values)==1 && length(irf_periods1)>1
weight_mat_values = repmat(weight_mat_values,length(irf_periods1),1);
end
if length(weight_mat_values) ~= length(irf_periods1)
error('method_of_moments: You specified a ''matched_irfs_weights'' entry for an IRF matching involving %s/%s and %s/%s,\n but the horizons do not match the length of ''weights''!',endo_names{id_var1},exo_names{id_shock1},endo_names{id_var2},exo_names{id_shock2});
end
for hh = 1:length(irf_periods1)
idweight_mat1 = sub2ind(size(data_irfs),irf_periods1(hh),id_varobs1,id_shock1);
idweight_mat2 = sub2ind(size(data_irfs),irf_periods2(hh),id_varobs2,id_shock2);
weight_mat(idweight_mat1,idweight_mat2) = weight_mat_values(hh);
weight_mat(idweight_mat2,idweight_mat1) = weight_mat_values(hh); % symmetry
end
end
% remove non-specified IRFs
irf_index = find(~isnan(data_irfs));
data_irfs = data_irfs(irf_index);
weight_mat = weight_mat(irf_index,irf_index);

View File

@ -1,8 +1,8 @@
function matched_moments = matched_moments_block(matched_moments, mom_method)
% function matched_moments = matched_moments_block(matched_moments, mom_method)
% matched_moments = matched_moments_block(matched_moments, mom_method)
% -------------------------------------------------------------------------
% Checks and transforms matched_moments block for further use in the estimation
% -------------------------------------------------------------------------
% Checks and transforms matched_moments bock for further use in the estimation
% =========================================================================
% INPUTS
% matched_moments: [cell array] original matched_moments block
% mom_method: [string] method of moments method (GMM or SMM)
@ -12,7 +12,8 @@ function matched_moments = matched_moments_block(matched_moments, mom_method)
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% =========================================================================
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
@ -29,7 +30,7 @@ function matched_moments = matched_moments_block(matched_moments, mom_method)
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
matched_moments_orig = matched_moments;
% higher-order product moments not supported yet for GMM
@ -59,22 +60,22 @@ for jm = 1:size(matched_moments,1)
end
% 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,matched_moments(:,3))';
UniqueMomIdx = [];
unique_mom_idx = [];
for jpow = unique(powers)
idx1 = find(powers==jpow);
[~,idx2] = unique(cell2mat(matched_moments(idx1,:)),'rows');
UniqueMomIdx = [UniqueMomIdx idx1(idx2)];
unique_mom_idx = [unique_mom_idx idx1(idx2)];
end
% remove duplicate elements
DuplicateMoms = setdiff(1:size(matched_moments_orig,1),UniqueMomIdx);
if ~isempty(DuplicateMoms)
fprintf('Duplicate declared moments found and removed in ''matched_moments'' block in rows:\n %s.\n',num2str(DuplicateMoms))
duplicate_moms = setdiff(1:size(matched_moments_orig,1),unique_mom_idx);
if ~isempty(duplicate_moms)
fprintf('Duplicate declared moments found and removed in ''matched_moments'' block in rows:\n %s.\n',num2str(duplicate_moms));
fprintf('Dynare will continue with remaining moment conditions\n');
end
if strcmp(mom_method, 'SMM')
% for SMM: keep the original structure, but get rid of duplicate moments
matched_moments = matched_moments_orig(sort(UniqueMomIdx),:);
matched_moments = matched_moments_orig(sort(unique_mom_idx),:);
elseif strcmp(mom_method, 'GMM')
% for GMM we use the transformed matched_moments structure
matched_moments = matched_moments(sort(UniqueMomIdx),:);
matched_moments = matched_moments(sort(unique_mom_idx),:);
end

View File

@ -1,25 +1,30 @@
function [xparam1, oo_, Woptflag] = mode_compute_gmm_smm(xparam0, objective_function, oo_, M_, options_mom_, estim_params_, bayestopt_, Bounds)
% function [xparam1, oo_, Woptflag] = mode_compute_gmm_smm(xparam0, objective_function, oo_, M_, options_mom_, estim_params_, bayestopt_, Bounds)
function [xparam1, weighting_info, mom_verbose] = mode_compute_gmm_smm(xparam0, objective_function, m_data, data_moments, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% [xparam1, weighting_info, mom_verbose] = mode_compute_gmm_smm(xparam0, objective_function, m_data, data_moments, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% -------------------------------------------------------------------------
% Iterated method of moments for GMM and SMM, computes the minimum of the
% objective function (distance between data moments and model moments)
% for a sequence of optimizers and GMM/SMM iterations with different
% weighting matrices.
% =========================================================================
% -------------------------------------------------------------------------
% INPUTS
% xparam0: [vector] vector of initialized parameters
% objective_function: [func handle] name of the objective function
% oo_: [structure] results
% M_: [structure] model information
% options_mom_: [structure] options
% estim_params_: [structure] information on estimated parameters
% bayestopt_: [structure] information on priors
% Bounds: [structure] bounds for optimization
% xparam0: [vector] vector of initialized parameters
% objective_function: [func handle] name of the objective function
% m_data: [matrix] selected data moments at each point in time
% data_moments: [vector] vector of data moments
% options_mom_: [structure] options
% M_: [structure] model information
% estim_params_: [structure] information on estimated parameters
% bayestopt_: [structure] information on priors
% BoundsInfo: [structure] bounds for optimization
% dr: [structure] reduced form model
% endo_steady_state: [vector] steady state for endogenous variables (initval)
% exo_steady_state: [vector] steady state for exogenous variables (initval)
% exo_det_steady_state: [vector] steady state for exogenous deterministic variables (initval)
% -------------------------------------------------------------------------
% OUTPUT
% xparam1: [vector] mode of objective function
% oo_: [structure] updated results
% Woptflag: [logical] true if optimal weighting matrix was computed
% xparam1: [vector] mode of objective function
% weighting_info: [structure] information on weighting matrix
% mom_verbose: [structure] information on intermediate estimation results
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
@ -29,7 +34,9 @@ function [xparam1, oo_, Woptflag] = mode_compute_gmm_smm(xparam0, objective_func
% o mom.display_estimation_results_table
% o dynare_minimize_objective
% o mom.objective_function
% =========================================================================
% o prior_dist_names
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
@ -46,15 +53,16 @@ function [xparam1, oo_, Woptflag] = mode_compute_gmm_smm(xparam0, objective_func
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
mom_verbose = [];
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)))
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')
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');
end
for stage_iter = 1:size(options_mom_.mom.weighting_matrix,1)
fprintf('Estimation stage %u\n',stage_iter);
Woptflag = false;
weighting_info.Woptflag = false;
switch lower(options_mom_.mom.weighting_matrix{stage_iter})
case 'identity_matrix'
fprintf(' - identity weighting matrix\n');
@ -63,44 +71,44 @@ for stage_iter = 1:size(options_mom_.mom.weighting_matrix,1)
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');
weighting_matrix = diag(diag( mom.optimal_weighting_matrix(oo_.mom.m_data, oo_.mom.data_moments, options_mom_.mom.bartlett_kernel_lag) ));
weighting_matrix = diag(diag( mom.optimal_weighting_matrix(m_data, data_moments, options_mom_.mom.bartlett_kernel_lag) ));
else
fprintf(' and using previous stage estimate of model-moments\n');
weighting_matrix = diag(diag( mom.optimal_weighting_matrix(oo_.mom.m_data, oo_.mom.model_moments, options_mom_.mom.bartlett_kernel_lag) ));
weighting_matrix = diag(diag( mom.optimal_weighting_matrix(m_data, model_moments, options_mom_.mom.bartlett_kernel_lag) ));
end
case 'optimal'
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');
weighting_matrix = mom.optimal_weighting_matrix(oo_.mom.m_data, oo_.mom.data_moments, options_mom_.mom.bartlett_kernel_lag);
weighting_matrix = mom.optimal_weighting_matrix(m_data, data_moments, options_mom_.mom.bartlett_kernel_lag);
else
fprintf(' and using previous stage estimate of model-moments\n');
weighting_matrix = mom.optimal_weighting_matrix(oo_.mom.m_data, oo_.mom.model_moments, options_mom_.mom.bartlett_kernel_lag);
Woptflag = true;
weighting_matrix = mom.optimal_weighting_matrix(m_data, model_moments, options_mom_.mom.bartlett_kernel_lag);
weighting_info.Woptflag = true;
end
otherwise % user specified matrix in file
fprintf(' - user-specified weighting matrix\n');
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 !'])
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);
if ~isequal(nrow,ncol) || ~isequal(nrow,length(oo_.mom.data_moments)) %check if square and right size
error(['method_of_moments: ''weighting_matrix'' must be square and have ',num2str(length(oo_.mom.data_moments)),' rows and columns!'])
if ~isequal(nrow,ncol) || ~isequal(nrow,length(data_moments)) %check if square and right size
error(['method_of_moments: ''weighting_matrix'' must be square and have ',num2str(length(data_moments)),' rows and columns!']);
end
end
try % check for positive definiteness of weighting_matrix
oo_.mom.Sw = chol(weighting_matrix);
weighting_info.Sw = chol(weighting_matrix);
catch
error('method_of_moments: Specified ''weighting_matrix'' is not positive definite. Check whether your model implies stochastic singularity!')
error('method_of_moments: Specified ''weighting_matrix'' is not positive definite. Check whether your model implies stochastic singularity!');
end
for optim_iter = 1:length(options_mom_.optimizer_vec)
options_mom_.current_optimizer = options_mom_.optimizer_vec{optim_iter};
if options_mom_.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_);
xparam1 = xparam0; % no minimization, evaluate objective at current values
fval = feval(objective_function, xparam1, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
else
if options_mom_.optimizer_vec{optim_iter} == 13
options_mom_.mom.vector_output = true;
@ -112,18 +120,22 @@ for stage_iter = 1:size(options_mom_.mom.weighting_matrix,1)
else
options_mom_.mom.compute_derivs = false;
end
[xparam1, fval, exitflag] = dynare_minimize_objective(objective_function, xparam0, options_mom_.optimizer_vec{optim_iter}, options_mom_, [Bounds.lb Bounds.ub], bayestopt_.name, bayestopt_, [],...
Bounds, oo_, estim_params_, M_, options_mom_);
[xparam1, fval] = dynare_minimize_objective(objective_function, xparam0, options_mom_.optimizer_vec{optim_iter}, options_mom_, [BoundsInfo.lb BoundsInfo.ub], bayestopt_.name, bayestopt_, [],...
data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
if options_mom_.mom.vector_output
fval = fval'*fval;
end
end
fprintf('\nStage %d Iteration %d: Value of minimized moment distance objective function: %12.10f.\n',stage_iter,optim_iter,fval)
fprintf('\nStage %d Iteration %d: Value of minimized moment distance objective function: %12.10f.\n',stage_iter,optim_iter,fval);
if options_mom_.mom.verbose
oo_.mom = display_estimation_results_table(xparam1,NaN(size(xparam1)),M_,options_mom_,estim_params_,bayestopt_,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));
fprintf('\n''verbose'' option: ');
std_via_invhessian_xparam1_iter = NaN(size(xparam1));
tbl_title_iter = sprintf('FREQUENTIST %s (STAGE %d ITERATION %d) VERBOSE',options_mom_.mom.mom_method,stage_iter,optim_iter);
field_name_iter = sprintf('%s_stage_%d_iter_%d',lower(options_mom_.mom.mom_method),stage_iter,optim_iter);
mom_verbose.(field_name_iter) = display_estimation_results_table(xparam1,std_via_invhessian_xparam1_iter,M_,options_mom_,estim_params_,bayestopt_,[],prior_dist_names,tbl_title_iter,field_name_iter);
end
xparam0 = xparam1;
end
options_mom_.vector_output = false;
[~, ~, ~,~,~, oo_] = feval(objective_function, xparam1, Bounds, oo_, estim_params_, M_, options_mom_); % get oo_.mom.model_moments for iterated GMM/SMM to compute optimal weighting matrix
end
[~, ~, ~, ~, ~, ~, model_moments] = feval(objective_function, xparam1, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state); % get model_moments for iterated GMM/SMM to compute optimal weighting matrix
end

View File

@ -0,0 +1,122 @@
function [xparam1, hessian_xparam1, fval, mom_verbose] = mode_compute_irf_matching(xparam0, hessian_xparam0, objective_function, doBayesianEstimation, weighting_info, data_moments, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% [xparam1, hessian_xparam1, fval, mom_verbose] = mode_compute_irf_matching(xparam0, hessian_xparam0, objective_function, doBayesianEstimation, weighting_info, data_moments, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% -------------------------------------------------------------------------
% Computes the minimum of the objective function (distance between data IRFs
% and model IRFs) for a sequence of optimizers.
% Note that we call a "mode" the minimum of the objective function, i.e.
% the parameter vector that minimizes the distance between the IRFs
% computed from the model and the IRFs computed from the data.
% -------------------------------------------------------------------------
% INPUTS
% xparam0: [vector] initialized parameters
% hessian_xparam0: [matrix] initialized hessian at xparam0
% objective_function: [func handle] name of the objective function
% doBayesianEstimation: [logical] true if Bayesian estimation
% weighting_info: [structure] information on weighting matrix
% data_moments: [vector] data moments
% options_mom_: [structure] options
% M_: [structure] model information
% estim_params_: [structure] information on estimated parameters
% bayestopt_: [structure] information on priors
% BoundsInfo: [structure] bounds for optimization
% dr: [structure] information reduced-form model
% endo_steady_state: [vector] steady state of endogenous variables (initval)
% exo_steady_state: [vector] steady state of exogenous variables (initval)
% exo_det_steady_state: [vector] steady state of deterministic exogenous variables (initval)
% -------------------------------------------------------------------------
% OUTPUT
% xparam1: [vector] mode of objective function
% hessian_xparam1: [matrix] hessian at xparam1
% fval: [double] function value at mode
% mom_verbose: [structure] information on intermediate estimation results
% Also saves the computed mode and hessian to a file.
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% -------------------------------------------------------------------------
% This function calls
% o display_estimation_results_table
% o dynare_minimize_objective
% o hessian
% o mom.objective_function
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% 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
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
mom_verbose = [];
for optim_iter = 1:length(options_mom_.optimizer_vec)
options_mom_.current_optimizer = options_mom_.optimizer_vec{optim_iter};
if options_mom_.optimizer_vec{optim_iter}==0
% no minimization, evaluate objective at current values
xparam1 = xparam0;
hessian_xparam1 = hessian_xparam0;
fval = feval(objective_function, xparam1, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
else
[xparam1, fval, exitflag, hessian_xparam1, options_mom_, Scale, new_rat_hess_info] = dynare_minimize_objective(objective_function, xparam0, options_mom_.optimizer_vec{optim_iter}, options_mom_, [BoundsInfo.lb BoundsInfo.ub], bayestopt_.name, bayestopt_, hessian_xparam0,...
data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
end
fprintf('\nMode Compute Iteration %d: Value of minimized moment distance objective function: %12.10f.\n',optim_iter,fval);
if options_mom_.mom.verbose
fprintf('\n''verbose'' option: ');
if options_mom_.cova_compute
if options_mom_.optimizer_vec{optim_iter}==0
hessian_xparam1_iter = hessian_xparam1;
else
fprintf('computing Hessian');
hessian_xparam1_iter = hessian(objective_function, xparam1, options_mom_.gstep,...
data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
hessian_xparam1_iter = reshape(hessian_xparam1_iter, length(xparam1), length(xparam1));
end
hsd_iter = sqrt(diag(hessian_xparam1_iter));
invhessian_xparam1_iter = inv(hessian_xparam1_iter./(hsd_iter*hsd_iter'))./(hsd_iter*hsd_iter');
std_via_invhessian_xparam1_iter = sqrt(diag(invhessian_xparam1_iter));
else
std_via_invhessian_xparam1_iter = NaN(size(xparam1));
end
fprintf(' and displaying intermediate results.');
if doBayesianEstimation
tbl_title_iter = sprintf('BAYESIAN %s (OPTIM ITERATION %d) VERBOSE',strrep(options_mom_.mom.mom_method,'_',' '),optim_iter);
field_name_iter = sprintf('posterior_iter_%d',optim_iter);
else
tbl_title_iter = sprintf('FREQUENTIST %s (OPTIM ITERATION %d) VERBOSE',strrep(options_mom_.mom.mom_method,'_',' '),optim_iter);
field_name_iter = sprintf('iter_%d',optim_iter);
end
mom_verbose.(field_name_iter) = display_estimation_results_table(xparam1,std_via_invhessian_xparam1_iter,M_,options_mom_,estim_params_,bayestopt_,[],prior_dist_names,tbl_title_iter,field_name_iter);
end
xparam0 = xparam1;
hessian_xparam0 = hessian_xparam1;
end
if options_mom_.cova_compute
if options_mom_.mom.verbose
hessian_xparam1 = hessian_xparam1_iter;
else
fprintf('\nComputing Hessian at the mode.\n');
hessian_xparam1 = hessian(objective_function, xparam1, options_mom_.gstep,...
data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
hessian_xparam1 = reshape(hessian_xparam1, length(xparam1), length(xparam1));
end
end
parameter_names = bayestopt_.name;
if options_mom_.cova_compute || options_mom_.mode_compute==5 || options_mom_.mode_compute==6
hh = hessian_xparam1;
save([M_.dname filesep 'method_of_moments' filesep M_.fname '_mode.mat'],'xparam1','hh','parameter_names','fval');
else
save([M_.dname filesep 'method_of_moments' filesep M_.fname '_mode.mat'],'xparam1','parameter_names','fval');
end

View File

@ -1,27 +1,33 @@
function [fval, info, exit_flag, df, junkHessian, oo_, M_] = objective_function(xparam, Bounds, oo_, estim_params_, M_, options_mom_)
% [fval, info, exit_flag, df, junk1, oo_, M_] = objective_function(xparam, Bounds, oo_, estim_params_, M_, options_mom_)
function [fval, info, exit_flag, df, junk_hessian, Q, model_moments, model_moments_params_derivs, irf_model_varobs] = objective_function(xparam, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% [fval, info, exit_flag, df, junk_hessian, Q, model_moments, model_moments_params_derivs, irf_model_varobs] = objective_function(xparam, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% -------------------------------------------------------------------------
% This function evaluates the objective function for method of moments estimation
% =========================================================================
% INPUTS
% o xparam: [vector] current value of estimated parameters as returned by set_prior()
% o Bounds: [structure] containing parameter bounds
% o oo_: [structure] for results
% o estim_params_: [structure] describing the estimated_parameters
% o M_ [structure] describing the model
% o options_mom_: [structure] information about all settings (specified by the user, preprocessor, and taken from global options_)
% This function evaluates the objective function for method of moments estimation,
% i.e. distance between model and data moments/IRFs, possibly augmented with priors.
% -------------------------------------------------------------------------
% INPUTS (same ones as in dsge_likelihood.m and dsge_var_likelihood.m)
% - xparam: [vector] current value of estimated parameters as returned by set_prior()
% - data_moments: [vector] data with moments/IRFs to match (corresponds to dataset_ in likelihood-based estimation)
% - weighting_info: [structure] storing information on weighting matrices (corresponds to dataset_info in likelihood-based estimation)
% - options_mom_: [structure] information about all settings (specified by the user, preprocessor, and taken from global options_)
% - M_ [structure] model information
% - estim_params_: [structure] information from estimated_params block
% - bayestopt_: [structure] information on the prior distributions
% - BoundsInfo: [structure] parameter bounds
% - dr: [structure] reduced form model
% - endo_steady_state: [vector] steady state value for endogenous variables (initval)
% - exo_steady_state: [vector] steady state value for exogenous variables (initval)
% - exo_det_steady_state: [vector] steady state value for exogenous deterministic variables (initval)
% -------------------------------------------------------------------------
% OUTPUTS
% o fval: [double] value of the quadratic form of the moment difference (except for lsqnonlin, where this is done implicitly)
% o info: [vector] information on error codes and penalties
% o exit_flag: [double] flag for exit status (0 if error, 1 if no error)
% o df: [matrix] analytical jacobian of the moment difference (wrt paramters), currently for GMM only
% o junkHessian: [matrix] empty matrix required for optimizer interface (Hessian would typically go here)
% o oo_: [structure] results with the following updated fields:
% - oo_.mom.model_moments: [vector] model moments
% - oo_.mom.Q: [double] value of the quadratic form of the moment difference
% - oo_.mom.model_moments_params_derivs: [matrix] analytical jacobian of the model moments wrt estimated parameters (currently for GMM only)
% o M_: [structure] updated model structure
% - fval: [double] value of the quadratic form of the moment difference (except for lsqnonlin, where this is done implicitly)
% - info: [vector] information on error codes and penalties
% - exit_flag: [double] flag for exit status (0 if error, 1 if no error)
% - df: [matrix] analytical jacobian of the moment difference (wrt paramters), currently for GMM only
% - junk_hessian: [matrix] empty matrix required for optimizer interface (Hessian would typically go here)
% - Q: [double] value of the quadratic form of the moment difference
% - model_moments: [vector] model moments
% - model_moments_params_derivs: [matrix] analytical jacobian of the model moments wrt estimated parameters (currently for GMM only)
% - irf_model_varobs: [matrix] model IRFs for observable variables (used for plotting matched IRfs in mom.run)
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
@ -29,13 +35,18 @@ function [fval, info, exit_flag, df, junkHessian, oo_, M_] = objective_function(
% -------------------------------------------------------------------------
% This function calls
% o check_bounds_and_definiteness_estimation
% o get_lower_cholesky_covariance
% o get_perturbation_params_derivs
% o getIrfShocksIndx
% o irf
% o mom.get_data_moments
% o priordens
% o pruned_state_space_system
% o resol
% o set_all_parameters
% o simult_
% =========================================================================
% -------------------------------------------------------------------------
% Copyright © 2020-2023 Dynare Team
%
% This file is part of Dynare.
@ -52,28 +63,27 @@ function [fval, info, exit_flag, df, junkHessian, oo_, M_] = objective_function(
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
%% TO DO
% check the info values and make use of meaningful penalties
% how do we do the penalty for the prior??
%------------------------------------------------------------------------------
% Initialization of the returned variables and others...
%------------------------------------------------------------------------------
junkHessian = [];
irf_model_varobs = [];
model_moments_params_derivs = [];
model_moments = [];
Q = [];
junk_hessian = [];
df = []; % required to be empty by e.g. newrat
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
if options_mom_.mom.compute_derivs && options_mom_.mom.analytic_jacobian
if options_mom_.mom.vector_output == 1
if options_mom_.mom.penalized_estimator
df = nan(size(oo_.mom.data_moments,1)+length(xparam),length(xparam));
df = NaN(options_mom_.mom.mom_nbr+length(xparam),length(xparam));
else
df = nan(size(oo_.mom.data_moments,1),length(xparam));
df = NaN(options_mom_.mom.mom_nbr,length(xparam));
end
else
df = nan(length(xparam),1);
df = NaN(length(xparam),1);
end
end
end
@ -82,14 +92,13 @@ end
%--------------------------------------------------------------------------
% Get the structural parameters and define penalties
%--------------------------------------------------------------------------
% Ensure that xparam1 is a column vector; particleswarm.m requires this.
xparam = xparam(:);
M_ = set_all_parameters(xparam, estim_params_, M_);
[fval,info,exit_flag] = check_bounds_and_definiteness_estimation(xparam, M_, estim_params_, Bounds);
[fval,info,exit_flag] = check_bounds_and_definiteness_estimation(xparam, M_, estim_params_, BoundsInfo);
if info(1)
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = ones(size(oo_.mom.data_moments,1),1)*options_mom_.huge_number;
fval = ones(options_mom_.mom.mom_nbr,1)*options_mom_.huge_number;
end
return
end
@ -98,9 +107,8 @@ end
%--------------------------------------------------------------------------
% Call resol to compute steady state and model solution
%--------------------------------------------------------------------------
% Compute linear approximation around the deterministic steady state
[oo_.dr, info, M_.params] = resol(0, M_, options_mom_, oo_.dr ,oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
[dr, info, M_.params] = resol(0, M_, options_mom_, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
% Return, with endogenous penalty when possible, if resol issues an error code
if info(1)
if info(1) == 3 || info(1) == 4 || info(1) == 5 || info(1)==6 ||info(1) == 19 ||...
@ -111,7 +119,7 @@ if info(1)
info(4) = info(2);
exit_flag = 0;
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = ones(size(oo_.mom.data_moments,1),1)*options_mom_.huge_number;
fval = ones(options_mom_.mom.mom_nbr,1)*options_mom_.huge_number;
end
return
else
@ -119,7 +127,7 @@ if info(1)
info(4) = 0.1;
exit_flag = 0;
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = ones(size(oo_.mom.data_moments,1),1)*options_mom_.huge_number;
fval = ones(options_mom_.mom.mom_nbr,1)*options_mom_.huge_number;
end
return
end
@ -144,44 +152,44 @@ if strcmp(options_mom_.mom.mom_method,'GMM')
indpcorr = estim_params_.corrx(:,1:2); % values correspond to varexo declaration order, row number corresponds to order in estimated_params
end
if estim_params_.nvn || estim_params_.ncn % nvn is number of stderr parameters and ncn is number of corr parameters of measurement innovations as declared in estimated_params
error('Analytic computation of standard errrors does not (yet) support measurement errors.\nInstead, define them explicitly as varexo and provide measurement equations in the model definition.\nAlternatively, use numerical standard errors.')
error('Analytic computation of standard errrors does not (yet) support measurement errors.\nInstead, define them explicitly as varexo and provide measurement equations in the model definition.\nAlternatively, use numerical standard errors.');
end
modparam_nbr = estim_params_.np; % number of model parameters as declared in estimated_params
stderrparam_nbr = estim_params_.nvx; % number of stderr parameters
corrparam_nbr = estim_params_.ncx; % number of corr parameters
totparam_nbr = stderrparam_nbr+corrparam_nbr+modparam_nbr;
oo_.dr.derivs = identification.get_perturbation_params_derivs(M_, options_mom_, estim_params_, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state, indpmodel, indpstderr, indpcorr, 0); %analytic derivatives of perturbation matrices
oo_.mom.model_moments_params_derivs = NaN(options_mom_.mom.mom_nbr,totparam_nbr);
pruned_state_space = pruned_SS.pruned_state_space_system(M_, options_mom_, oo_.dr, oo_.mom.obs_var, options_mom_.ar, 0, 1);
dr.derivs = identification.get_perturbation_params_derivs(M_, options_mom_, estim_params_, dr, endo_steady_state, exo_steady_state, exo_det_steady_state, indpmodel, indpstderr, indpcorr, 0); %analytic derivatives of perturbation matrices
model_moments_params_derivs = NaN(options_mom_.mom.mom_nbr,totparam_nbr);
pruned_state_space = pruned_SS.pruned_state_space_system(M_, options_mom_, dr, options_mom_.mom.obs_var, options_mom_.ar, 0, 1);
else
pruned_state_space = pruned_SS.pruned_state_space_system(M_, options_mom_, oo_.dr, oo_.mom.obs_var, options_mom_.ar, 0, 0);
pruned_state_space = pruned_SS.pruned_state_space_system(M_, options_mom_, dr, options_mom_.mom.obs_var, options_mom_.ar, 0, 0);
end
oo_.mom.model_moments = NaN(options_mom_.mom.mom_nbr,1);
model_moments = NaN(options_mom_.mom.mom_nbr,1);
for jm = 1:size(M_.matched_moments,1)
% First moments
if ~options_mom_.prefilter && (sum(M_.matched_moments{jm,3}) == 1)
idx1 = (oo_.mom.obs_var == find(oo_.dr.order_var==M_.matched_moments{jm,1}) );
oo_.mom.model_moments(jm,1) = pruned_state_space.E_y(idx1);
idx1 = (options_mom_.mom.obs_var == find(dr.order_var==M_.matched_moments{jm,1}) );
model_moments(jm,1) = pruned_state_space.E_y(idx1);
if options_mom_.mom.compute_derivs && ( options_mom_.mom.analytic_standard_errors || options_mom_.mom.analytic_jacobian )
oo_.mom.model_moments_params_derivs(jm,:) = pruned_state_space.dE_y(idx1,:);
model_moments_params_derivs(jm,:) = pruned_state_space.dE_y(idx1,:);
end
end
% second moments
if (sum(M_.matched_moments{jm,3}) == 2)
idx1 = (oo_.mom.obs_var == find(oo_.dr.order_var==M_.matched_moments{jm,1}(1)) );
idx2 = (oo_.mom.obs_var == find(oo_.dr.order_var==M_.matched_moments{jm,1}(2)) );
idx1 = (options_mom_.mom.obs_var == find(dr.order_var==M_.matched_moments{jm,1}(1)) );
idx2 = (options_mom_.mom.obs_var == find(dr.order_var==M_.matched_moments{jm,1}(2)) );
if nnz(M_.matched_moments{jm,2}) == 0
% covariance
if options_mom_.prefilter
oo_.mom.model_moments(jm,1) = pruned_state_space.Var_y(idx1,idx2);
model_moments(jm,1) = pruned_state_space.Var_y(idx1,idx2);
if options_mom_.mom.compute_derivs && ( options_mom_.mom.analytic_standard_errors || options_mom_.mom.analytic_jacobian )
oo_.mom.model_moments_params_derivs(jm,:) = pruned_state_space.dVar_y(idx1,idx2,:);
model_moments_params_derivs(jm,:) = pruned_state_space.dVar_y(idx1,idx2,:);
end
else
oo_.mom.model_moments(jm,1) = pruned_state_space.Var_y(idx1,idx2) + pruned_state_space.E_y(idx1)*pruned_state_space.E_y(idx2)';
model_moments(jm,1) = pruned_state_space.Var_y(idx1,idx2) + pruned_state_space.E_y(idx1)*pruned_state_space.E_y(idx2)';
if options_mom_.mom.compute_derivs && ( options_mom_.mom.analytic_standard_errors || options_mom_.mom.analytic_jacobian )
for jp=1:totparam_nbr
oo_.mom.model_moments_params_derivs(jm,jp) = pruned_state_space.dVar_y(idx1,idx2,jp) + pruned_state_space.dE_y(idx1,jp)*pruned_state_space.E_y(idx2)' + pruned_state_space.E_y(idx1)*pruned_state_space.dE_y(idx2,jp)';
model_moments_params_derivs(jm,jp) = pruned_state_space.dVar_y(idx1,idx2,jp) + pruned_state_space.dE_y(idx1,jp)*pruned_state_space.E_y(idx2)' + pruned_state_space.E_y(idx1)*pruned_state_space.dE_y(idx2,jp)';
end
end
end
@ -189,15 +197,15 @@ if strcmp(options_mom_.mom.mom_method,'GMM')
% autocovariance
lag = -M_.matched_moments{jm,2}(2); %note that leads/lags in M_.matched_moments are transformed such that first entry is always 0 and the second is a lag
if options_mom_.prefilter
oo_.mom.model_moments(jm,1) = pruned_state_space.Var_yi(idx1,idx2,lag);
model_moments(jm,1) = pruned_state_space.Var_yi(idx1,idx2,lag);
if options_mom_.mom.compute_derivs && ( options_mom_.mom.analytic_standard_errors || options_mom_.mom.analytic_jacobian )
oo_.mom.model_moments_params_derivs(jm,:) = pruned_state_space.dVar_yi(idx1,idx2,lag,:);
model_moments_params_derivs(jm,:) = pruned_state_space.dVar_yi(idx1,idx2,lag,:);
end
else
oo_.mom.model_moments(jm,1) = pruned_state_space.Var_yi(idx1,idx2,lag) + pruned_state_space.E_y(idx1)*pruned_state_space.E_y(idx2)';
model_moments(jm,1) = pruned_state_space.Var_yi(idx1,idx2,lag) + pruned_state_space.E_y(idx1)*pruned_state_space.E_y(idx2)';
if options_mom_.mom.compute_derivs && ( options_mom_.mom.analytic_standard_errors || options_mom_.mom.analytic_jacobian )
for jp=1:totparam_nbr
oo_.mom.model_moments_params_derivs(jm,jp) = vec( pruned_state_space.dVar_yi(idx1,idx2,lag,jp) + pruned_state_space.dE_y(idx1,jp)*pruned_state_space.E_y(idx2)' + pruned_state_space.E_y(idx1)*pruned_state_space.dE_y(idx2,jp)');
model_moments_params_derivs(jm,jp) = vec( pruned_state_space.dVar_yi(idx1,idx2,lag,jp) + pruned_state_space.dE_y(idx1,jp)*pruned_state_space.E_y(idx2)' + pruned_state_space.E_y(idx1)*pruned_state_space.dE_y(idx2,jp)');
end
end
end
@ -217,26 +225,22 @@ if strcmp(options_mom_.mom.mom_method,'SMM')
scaled_shock_series = zeros(size(options_mom_.mom.shock_series)); % initialize
scaled_shock_series(:,i_exo_var) = options_mom_.mom.shock_series(:,i_exo_var)*chol_S; % set non-zero entries
% simulate series
y_sim = simult_(M_, options_mom_, oo_.dr.ys, oo_.dr, scaled_shock_series, options_mom_.order);
% provide meaningful penalty if data is nan or inf
y_sim = simult_(M_, options_mom_, dr.ys, dr, scaled_shock_series, options_mom_.order);
% provide meaningful penalty if data is NaN or Inf
if any(any(isnan(y_sim))) || any(any(isinf(y_sim)))
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = Inf(size(oo_.mom.Sw,1),1);
else
fval = Inf;
end
info(1)=180;
info(4) = 0.1;
exit_flag = 0;
fval = Inf;
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = ones(size(oo_.mom.data_moments,1),1)*options_mom_.huge_number;
fval = ones(options_mom_.mom.mom_nbr,1)*options_mom_.huge_number;
end
return
end
% remove burn-in and focus on observables (note that y_sim is in declaration order)
y_sim = y_sim(oo_.dr.order_var(oo_.mom.obs_var) , end-options_mom_.mom.long+1:end)';
y_sim = y_sim(dr.order_var(options_mom_.mom.obs_var) , end-options_mom_.mom.long+1:end)';
if ~all(diag(M_.H)==0)
i_ME = setdiff([1:size(M_.H,1)],find(diag(M_.H) == 0)); % find ME with 0 variance
i_ME = setdiff(1:size(M_.H,1),find(diag(M_.H) == 0)); % find ME with 0 variance
chol_S = chol(M_.H(i_ME,i_ME)); % decompose rest
shock_mat=zeros(size(options_mom_.mom.ME_shock_series)); % initialize
shock_mat(:,i_ME)=options_mom_.mom.ME_shock_series(:,i_ME)*chol_S;
@ -246,46 +250,119 @@ if strcmp(options_mom_.mom.mom_method,'SMM')
if options_mom_.prefilter
y_sim = bsxfun(@minus, y_sim, mean(y_sim,1));
end
oo_.mom.model_moments = mom.get_data_moments(y_sim, oo_.mom.obs_var, oo_.dr.inv_order_var, M_.matched_moments, options_mom_);
model_moments = mom.get_data_moments(y_sim, options_mom_.mom.obs_var, dr.inv_order_var, M_.matched_moments, options_mom_);
end
%------------------------------------------------------------------------------
% IRF_MATCHING using STOCH_SIMUL: Compute IRFs given model solution and Cholesky
% decomposition on shock covariance matrix; this resembles the core codes in
% stoch_simul
%------------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING') && strcmp(options_mom_.mom.simulation_method,'STOCH_SIMUL')
cs = get_lower_cholesky_covariance(M_.Sigma_e,options_mom_.add_tiny_number_to_cholesky);
irf_shocks_indx = getIrfShocksIndx(M_, options_mom_);
model_irf = NaN(options_mom_.irf,M_.endo_nbr,M_.exo_nbr);
for i = irf_shocks_indx
if options_mom_.order>1 && options_mom_.relative_irf % normalize shock to 0.01 before IRF generation for GIRFs; multiply with 100 later
y_irf = irf(M_, options_mom_, dr, cs(:,i)./cs(i,i)/100, options_mom_.irf, options_mom_.drop, options_mom_.replic, options_mom_.order);
else % for linear model, rescaling is done later
y_irf = irf(M_, options_mom_, dr, cs(:,i), options_mom_.irf, options_mom_.drop, options_mom_.replic, options_mom_.order);
end
if any(any(isnan(y_irf))) && ~options_mom_.pruning && ~(options_mom_.order==1)
info(1) = 181;
info(4) = 0.1;
fval = Inf;
exit_flag = 0;
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = ones(options_mom_.mom.mom_nbr,1)*options_mom_.huge_number;
end
message = get_error_message(info,options_mom_);
fprintf('\n%s\n info = %d for shock %s.\n', message, info(1), M_.exo_names{i});
return
end
if options_mom_.relative_irf
if options_mom_.order==1 % multiply with 100 for backward compatibility
y_irf = 100*y_irf/cs(i,i);
end
end
model_irf(:,:,i) = transpose(y_irf);
end
% do transformations on model IRFs if irf_matching_file is provided
if ~isempty(options_mom_.mom.irf_matching_file.name)
[model_irf, check] = feval(str2func(options_mom_.mom.irf_matching_file.name), model_irf, M_, options_mom_, dr.ys);
if check
fval = Inf;
info(1) = 180;
info(4) = 0.1;
exit_flag = 0;
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = ones(options_mom_.mom.mom_nbr,1)*options_mom_.huge_number;
end
return
end
end
irf_model_varobs = model_irf(:,options_mom_.varobs_id,:); % focus only on observables (this will be used later for plotting)
model_moments = irf_model_varobs(options_mom_.mom.irfIndex); % focus only on selected IRF periods
end
%--------------------------------------------------------------------------
% Compute quadratic target function
%--------------------------------------------------------------------------
moments_difference = oo_.mom.data_moments - oo_.mom.model_moments;
moments_difference = data_moments - model_moments;
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
residuals = sqrt(options_mom_.mom.weighting_matrix_scaling_factor)*oo_.mom.Sw*moments_difference;
oo_.mom.Q = residuals'*residuals;
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
Q = transpose(moments_difference)*weighting_info.W*moments_difference;
% log-likelihood
lnlik = options_mom_.mom.mom_nbr/2*log(1/2/pi) - 1/2*weighting_info.Winv_logdet - 1/2*Q;
if isinf(lnlik)
fval = Inf; info(1) = 50; info(4) = 0.1; exit_flag = 0;
return
end
if isnan(lnlik)
fval = Inf; info(1) = 45; info(4) = 0.1; exit_flag = 0;
return
end
if imag(lnlik)~=0
fval = Inf; info(1) = 46; info(4) = 0.1; exit_flag = 0;
return
end
% add log prior if necessary
lnprior = priordens(xparam,bayestopt_.pshape,bayestopt_.p6,bayestopt_.p7,bayestopt_.p3,bayestopt_.p4);
fval = - (lnlik + lnprior);
elseif strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
residuals = sqrt(options_mom_.mom.weighting_matrix_scaling_factor)*weighting_info.Sw*moments_difference;
Q = residuals'*residuals;
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
fval = residuals;
if options_mom_.mom.penalized_estimator
fval=[fval;(xparam-oo_.mom.prior.mean)./sqrt(diag(oo_.mom.prior.variance))];
fval=[fval;(xparam-bayestopt_.p1)./bayestopt_.p2];
end
else
fval = oo_.mom.Q;
fval = Q;
if options_mom_.mom.penalized_estimator
fval=fval+(xparam-oo_.mom.prior.mean)'/oo_.mom.prior.variance*(xparam-oo_.mom.prior.mean);
fval=fval+(xparam-bayestopt_.p1)'/(diag(bayestopt_.p2.^2))*(xparam-bayestopt_.p1);
end
end
if options_mom_.mom.compute_derivs && options_mom_.mom.analytic_jacobian
if options_mom_.mom.penalized_estimator
dxparam1 = eye(length(xparam));
dxparam = eye(length(xparam));
end
for jp=1:length(xparam)
dmoments_difference = - oo_.mom.model_moments_params_derivs(:,jp);
dresiduals = sqrt(options_mom_.mom.weighting_matrix_scaling_factor)*oo_.mom.Sw*dmoments_difference;
dmoments_difference = - model_moments_params_derivs(:,jp);
dresiduals = sqrt(options_mom_.mom.weighting_matrix_scaling_factor)*weighting_info.Sw*dmoments_difference;
if options_mom_.mom.vector_output == 1 % lsqnonlin requires vector output
if options_mom_.mom.penalized_estimator
df(:,jp)=[dresiduals;dxparam1(:,jp)./sqrt(diag(oo_.mom.prior.variance))];
df(:,jp)=[dresiduals;dxparam(:,jp)./bayestopt_.p2];
else
df(:,jp) = dresiduals;
end
else
df(jp,1) = dresiduals'*residuals + residuals'*dresiduals;
if options_mom_.mom.penalized_estimator
df(jp,1)=df(jp,1)+(dxparam1(:,jp))'/oo_.mom.prior.variance*(xparam-oo_.mom.prior.mean)+(xparam-oo_.mom.prior.mean)'/oo_.mom.prior.variance*(dxparam1(:,jp));
df(jp,1)=df(jp,1)+(dxparam(:,jp))'/(diag(bayestopt_.p2.^2))*(xparam-bayestopt_.p1)+(xparam-bayestopt_.p1)'/(diag(bayestopt_.p2.^2))*(dxparam(:,jp));
end
end
end
@ -293,5 +370,4 @@ if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_meth
end
end % main function end
end % main function end

View File

@ -2,9 +2,10 @@ function W_opt = optimal_weighting_matrix(m_data, moments, q_lag)
% W_opt = optimal_weighting_matrix(m_data, moments, q_lag)
% -------------------------------------------------------------------------
% This function computes the optimal weigthing matrix by a Bartlett kernel with maximum lag q_lag
% Adapted from replication codes of
% 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.
% =========================================================================
% Adapted from replication codes of 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.
% -------------------------------------------------------------------------
% INPUTS
% o m_data [T x numMom] selected data moments at each point in time
% o moments [numMom x 1] selected estimated moments (either data_moments or estimated model_moments)
@ -17,9 +18,10 @@ function W_opt = optimal_weighting_matrix(m_data, moments, q_lag)
% o mom.run.m
% -------------------------------------------------------------------------
% This function calls:
% o CorrMatrix (embedded)
% =========================================================================
% Copyright © 2020-2021 Dynare Team
% o corr_matrix (embedded)
% -------------------------------------------------------------------------
% Copyright © 2020-2023 Dynare Team
%
% This file is part of Dynare.
%
@ -35,46 +37,42 @@ function W_opt = optimal_weighting_matrix(m_data, moments, q_lag)
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------
% Author(s):
% o Willi Mutschler (willi@mutschler.eu)
% o Johannes Pfeifer (johannes.pfeifer@unibw.de)
% =========================================================================
% Initialize
[T,num_Mom] = size(m_data); %note that in m_data NaN values (due to leads or lags in matched_moments and missing data) were replaced by the mean
% initialize
[T,num_Mom] = size(m_data); % note that in m_data NaN values (due to leads or lags in matched_moments and missing data) were replaced by the mean
% center around moments (could be either data_moments or model_moments)
h_Func = m_data - repmat(moments',T,1);
h_func = m_data - repmat(moments',T,1);
% The required correlation matrices
GAMA_array = zeros(num_Mom,num_Mom,q_lag);
GAMA0 = Corr_Matrix(h_Func,T,num_Mom,0);
% the required correlation matrices
gamma_array = zeros(num_Mom,num_Mom,q_lag);
gamma0 = corr_matrix(h_func,T,num_Mom,0);
if q_lag > 0
for ii=1:q_lag
GAMA_array(:,:,ii) = Corr_Matrix(h_Func,T,num_Mom,ii);
gamma_array(:,:,ii) = corr_matrix(h_func,T,num_Mom,ii);
end
end
% The estimate of S
S = GAMA0;
% the estimate of S
S = gamma0;
if q_lag > 0
for ii=1:q_lag
S = S + (1-ii/(q_lag+1))*(GAMA_array(:,:,ii) + GAMA_array(:,:,ii)');
S = S + (1-ii/(q_lag+1))*(gamma_array(:,:,ii) + gamma_array(:,:,ii)');
end
end
% The estimate of W
% the estimate of W
W_opt = S\eye(size(S,1));
W_opt=(W_opt+W_opt')/2; %assure symmetry
end
W_opt = (W_opt+W_opt')/2; % ensure symmetry
end % main function end
% The correlation matrix
function GAMA_corr = Corr_Matrix(h_Func,T,num_Mom,v)
GAMA_corr = zeros(num_Mom,num_Mom);
function gamma_corr = corr_matrix(h_func,T,num_Mom,v)
gamma_corr = zeros(num_Mom,num_Mom);
for t = 1+v:T
GAMA_corr = GAMA_corr + h_Func(t-v,:)'*h_Func(t,:);
gamma_corr = gamma_corr + h_func(t-v,:)'*h_func(t,:);
end
GAMA_corr = GAMA_corr/T;
end
gamma_corr = gamma_corr/T;
end % corr_matrix end

View File

@ -1,11 +1,12 @@
function print_info_on_estimation_settings(options_mom_, number_of_estimated_parameters)
% function print_info_on_estimation_settings(options_mom_, number_of_estimated_parameters)
function print_info_on_estimation_settings(options_mom_, number_of_estimated_parameters, do_bayesian_estimation)
% print_info_on_estimation_settings(options_mom_, number_of_estimated_parameters, do_bayesian_estimation)
% -------------------------------------------------------------------------
% Print information on the method of moments estimation settings to the console
% =========================================================================
% -------------------------------------------------------------------------
% INPUTS
% options_mom_ [struct] Options for the method of moments estimation
% number_of_estimated_parameters [integer] Number of estimated parameters
% options_mom_ [struct] options for the method of moments estimation
% number_of_estimated_parameters [integer] number of estimated parameters
% do_bayesian_estimation [boolean] true if the estimation is Bayesian
% -------------------------------------------------------------------------
% OUTPUT
% No output, just displays the chosen settings
@ -15,7 +16,8 @@ function print_info_on_estimation_settings(options_mom_, number_of_estimated_par
% -------------------------------------------------------------------------
% This function calls
% o skipline
% =========================================================================
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
@ -32,7 +34,8 @@ function print_info_on_estimation_settings(options_mom_, number_of_estimated_par
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
fprintf('\n---------------------------------------------------\n')
if strcmp(options_mom_.mom.mom_method,'SMM')
fprintf('Simulated method of moments with');
@ -49,7 +52,16 @@ if strcmp(options_mom_.mom.mom_method,'SMM') || strcmp(options_mom_.mom.mom_meth
fprintf('\n - penalized estimation using deviation from prior mean and weighted with prior precision');
end
end
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
if do_bayesian_estimation
fprintf('Bayesian Impulse Response Function Matching with');
else
fprintf('Frequentist Impulse Response Function Matching with');
end
if ~isempty(options_mom_.mom.irf_matching_file.name)
fprintf('\n - irf_matching_file: %s',[options_mom_.mom.irf_matching_file.path filesep options_mom_.mom.irf_matching_file.name '.m']);
end
end
for i = 1:length(options_mom_.optimizer_vec)
if i == 1
str = '- optimizer (mode_compute';
@ -118,6 +130,8 @@ if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_meth
fprintf('\n - standard errors: numerical derivatives');
end
fprintf('\n - number of matched moments: %d', options_mom_.mom.mom_nbr);
elseif strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
fprintf('\n - number of matched IRFs: %d', options_mom_.mom.mom_nbr);
end
fprintf('\n - number of parameters: %d', number_of_estimated_parameters);
fprintf('\n\n');

View File

@ -6,31 +6,47 @@ function [oo_, options_mom_, M_] = run(bayestopt_, options_, oo_, estim_params_,
% o Preparing local options_mom_ structure
% o Checking the options and the compatibility of the settings
% o Initializations of variables, orderings and state space representation
% o Checks and transformations for matched moments structure
% o Checks and transformations for matched_moments structure
% o Checks and transformations for matched_irfs and matched_irfs_weights structure
% o Checks and transformations for estimated parameters, priors, and bounds
% o Checks and transformations for data
% o Checks for objective function at initial parameters
% o GMM/SMM: iterated method of moments estimation
% o GMM/SMM: J-Test and fit of moments%
% o Mode computation: optimization
% - GMM/SMM: iterated optimization
% - IRF_MATCHING: optimization
% o Bayesian MCMC estimation
% o Display of results
% - GMM/SMM: J-Test and fit of moments
% - IRF_MATCHING: fit of IRFs
% o Clean up
% -------------------------------------------------------------------------
% Note that we call a "mode" the minimum of the objective function, i.e.
% the parameter vector that minimizes the distance between the moments/IRFs
% computed from the model and the moments/IRFs computed from the data.
% -------------------------------------------------------------------------
% This function is inspired by replication codes accompanied to the following papers:
% GMM/SMM:
% 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.
% =========================================================================
% o Ruge-Murcia (2007): "Methods to Estimate Dynamic Stochastic General Equilibrium Models", Journal of Economic Dynamics and Control, 31(8):2599-2636.
% IRF MATCHING:
% o Christiano, Trabandt, Walentin (2010): "DSGE Models for Monetary Policy Analysis." In Handbook of Monetary Economics, 3:285367.
% o Christiano, Eichenbaum, Trabandt (2016): "Unemployment and Business Cycles." Econometrica, 84: 1523-1569.
% o Ruge-Murcia (2020): "Estimating Nonlinear Dynamic Equilibrium Models by Matching Impulse Responses", Economics Letters, 197.
% -------------------------------------------------------------------------
% INPUTS
% o bayestopt_: [structure] information about priors
% o options_: [structure] information about global options
% o oo_: [structure] storage for results
% o oo_: [structure] results
% o estim_params_: [structure] information about estimated parameters
% o M_: [structure] information about model with
% o matched_moments: [cell] information about selected moments to match in GMM/SMM estimation
% vars: matched_moments{:,1});
% lead/lags: matched_moments{:,2};
% powers: matched_moments{:,3};
% o matched_irfs: [cell] information about selected IRFs to match in IRF_MATCHING estimation
% o matched_irfs_weights: [cell] information about entries in weight matrix for an IRF_MATCHING estimation
% o options_mom_: [structure] information about settings specified by the user
% -------------------------------------------------------------------------
% OUTPUTS
@ -42,25 +58,26 @@ function [oo_, options_mom_, M_] = run(bayestopt_, options_, oo_, estim_params_,
% o driver.m
% -------------------------------------------------------------------------
% This function calls
% o cellofchararraymaxlength
% o check_for_calibrated_covariances
% o check_mode_file
% o check_posterior_sampler_options
% o check_prior_bounds
% o check_prior_stderr_corr
% o check_steady_state_changes_parameters
% o check_varobs_are_endo_and_declared_once
% o check_hessian_at_the_mode
% o display_estimation_results_table
% o do_parameter_initialization
% o dyn_latex_table
% o dynare_minimize_objective
% o dyntable
% o get_all_parameters
% o get_dynare_random_generator_state
% o get_matrix_entries_for_psd_check
% o M_.fname '_prior_restrictions'
% o makedataset
% o mom.check_plot
% o mode_check
% o mom.check_irf_matching_file
% o mom.default_option_mom_values
% o mom.get_data_moments
% o mom.matched_irfs_blocks
% o mom.matched_moments_block
% o mom.objective_function
% o mom.optimal_weighting_matrix
@ -77,8 +94,9 @@ function [oo_, options_mom_, M_] = run(bayestopt_, options_, oo_, estim_params_,
% o set_state_space
% o skipline
% o test_for_deep_parameters_calibration
% o transform_prior_to_laplace_prior
% o warning_config
% =========================================================================
% Copyright © 2020-2023 Dynare Team
%
% This file is part of Dynare.
@ -95,34 +113,8 @@ function [oo_, options_mom_, M_] = run(bayestopt_, options_, oo_, estim_params_,
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------
% Maintaining Author(s):
% o Willi Mutschler (willi@mutschler.eu)
% o Johannes Pfeifer (johannes.pfeifer@unibw.de)
% =========================================================================
% -------------------------------------------------------------------------
% TO DO LISTS
% -------------------------------------------------------------------------
% GENERAL
% - document all options in manual
% - document analytic_jacobian better
% - make endogenous_prior_restrictions work
% - dirname option to save output to different directory not yet implemented
% - create test for prior restrictions file
% - add mode_file option
% - implement penalty objective
% - test optimizers
% GMM/SMM
% - 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)
% - display scaled moments
% - enable first moments despite prefilter
% - do "true" Bayesian GMM and SMM not only penalized
fprintf('\n==== Method of Moments Estimation (%s) ====\n\n',options_mom_.mom.mom_method)
fprintf('\n==== Method of Moments Estimation (%s) ====\n\n',options_mom_.mom.mom_method);
% -------------------------------------------------------------------------
@ -130,29 +122,33 @@ fprintf('\n==== Method of Moments Estimation (%s) ====\n\n',options_mom_.mom.mom
% -------------------------------------------------------------------------
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!')
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!')
error('method_of_moments: The ''estimated_params'' block must not be empty!');
end
end
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
if ~isfield(M_,'matched_moments') || isempty(M_.matched_moments) % structure storing the moments used for GMM and SMM estimation
error('method_of_moments: You need to provide a ''matched_moments'' block for ''mom_method=%s''!',options_mom_.mom.mom_method)
error('method_of_moments: You need to provide a ''matched_moments'' block for ''mom_method=%s''!',options_mom_.mom.mom_method);
end
elseif strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
if ~isfield(M_,'matched_irfs') || isempty(M_.matched_irfs) % structure storing the irfs used for matching
error('method_of_moments: You need to provide a ''matched_irfs'' block for ''mom_method=%s''!',options_mom_.mom.mom_method);
end
end
if (~isempty(estim_params_.var_endo) || ~isempty(estim_params_.corrn)) && strcmp(options_mom_.mom.mom_method, 'GMM')
error('method_of_moments: GMM estimation does not support measurement error(s) yet. Please specify them as a structural shock!')
error('method_of_moments: GMM estimation does not support measurement error(s) yet. Please specify them as a structural shock!');
end
doBayesianEstimation = [estim_params_.var_exo(:,5); estim_params_.var_endo(:,5); estim_params_.corrx(:,6); estim_params_.corrn(:,6); estim_params_.param_vals(:,5)];
if all(doBayesianEstimation~=0)
doBayesianEstimation = true;
elseif all(doBayesianEstimation==0)
doBayesianEstimation = false;
do_bayesian_estimation = [estim_params_.var_exo(:,5); estim_params_.var_endo(:,5); estim_params_.corrx(:,6); estim_params_.corrn(:,6); estim_params_.param_vals(:,5)];
if all(do_bayesian_estimation~=0)
do_bayesian_estimation = true;
elseif all(do_bayesian_estimation==0)
do_bayesian_estimation = false;
else
error('method_of_moments: Estimation must be either fully Frequentist or fully Bayesian. Maybe you forgot to specify a prior distribution!')
error('method_of_moments: Estimation must be either fully Frequentist or fully Bayesian. Maybe you forgot to specify a prior distribution!');
end
if ~isfield(options_,'varobs')
error('method_of_moments: VAROBS statement is missing!')
error('method_of_moments: VAROBS statement is missing!');
end
check_varobs_are_endo_and_declared_once(options_.varobs,M_.endo_names);
@ -166,7 +162,7 @@ check_varobs_are_endo_and_declared_once(options_.varobs,M_.endo_names);
% 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.
options_mom_ = mom.default_option_mom_values(options_mom_, options_, M_.dname, doBayesianEstimation);
options_mom_ = mom.default_option_mom_values(options_mom_, options_, M_.dname, do_bayesian_estimation);
% -------------------------------------------------------------------------
@ -183,60 +179,27 @@ if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_meth
end
% -------------------------------------------------------------------------
% checks on settings
% -------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
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
end
if options_mom_.order < 1
error('method_of_moments: The order of the Taylor approximation cannot be 0!')
end
if options_mom_.order > 2
fprintf('Dynare will use ''k_order_solver'' as the order>2\n');
options_mom_.k_order_solver = true;
end
if strcmp(options_mom_.mom.mom_method,'SMM')
if options_mom_.mom.simulation_multiple < 1
fprintf('The simulation horizon is shorter than the data. Dynare resets the simulation_multiple to 7.\n')
options_mom_.mom.simulation_multiple = 7;
end
end
if strcmp(options_mom_.mom.mom_method,'GMM')
% require 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
if options_mom_.order > 3
error('method_of_moments: Perturbation orders higher than 3 are not implemented for GMM estimation, try using SMM!');
end
end
if options_mom_.mom.analytic_jacobian && ~strcmp(options_mom_.mom.mom_method,'GMM')
options_mom_.mom.analytic_jacobian = false;
fprintf('\n''analytic_jacobian'' option will be dismissed as it only works with GMM.\n');
end
% -------------------------------------------------------------------------
% initializations
% -------------------------------------------------------------------------
% create output directories to store results
M_.dname = options_mom_.dirname;
CheckPath(M_.dname,'.');
CheckPath('method_of_moments',M_.dname);
CheckPath('graphs',options_mom_.dirname);
% initialize options that might change
options_mom_.mom.compute_derivs = false; % flag to compute derivs in objective function (might change for GMM with either analytic_standard_errors or analytic_jacobian (dependent on optimizer))
options_mom_.mom.vector_output = false; % specifies whether the objective function returns a vector
CheckPath('graphs',M_.dname);
if do_bayesian_estimation
oo_.mom.posterior.optimization.mode = [];
oo_.mom.posterior.optimization.Variance = [];
oo_.mom.posterior.optimization.log_density=[];
end
do_bayesian_estimation_mcmc = do_bayesian_estimation && ( (options_mom_.mh_replic>0) || options_mom_.load_mh_file );
invhess = [];
% decision rule
oo_.dr = set_state_space(oo_.dr,M_); % get state-space representation
oo_.mom.obs_var = []; % create index of observed variables in DR order
options_mom_.mom.obs_var = []; % create index of observed variables in DR order
for i = 1:options_mom_.obs_nbr
oo_.mom.obs_var = [oo_.mom.obs_var; find(strcmp(options_mom_.varobs{i}, M_.endo_names(oo_.dr.order_var)))];
options_mom_.mom.obs_var = [options_mom_.mom.obs_var; find(strcmp(options_mom_.varobs{i}, M_.endo_names(oo_.dr.order_var)))];
end
@ -255,37 +218,76 @@ if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_meth
% Get maximum lag number for autocovariances/autocorrelations
options_mom_.ar = max(cellfun(@max,M_.matched_moments(:,2))) - min(cellfun(@min,M_.matched_moments(:,2)));
% Check that only observed variables are involved in moments
not_observed_variables=setdiff(oo_.dr.inv_order_var([M_.matched_moments{:,1}]),oo_.mom.obs_var);
not_observed_variables=setdiff(oo_.dr.inv_order_var([M_.matched_moments{:,1}]),options_mom_.mom.obs_var);
if ~isempty(not_observed_variables)
skipline;
error('method_of_moments: You specified moments involving %s, but it is not a varobs!',M_.endo_names{oo_.dr.order_var(not_observed_variables)})
error('method_of_moments: You specified moments involving %s, but it is not a varobs!',M_.endo_names{oo_.dr.order_var(not_observed_variables)});
end
end
% -------------------------------------------------------------------------
% estimated parameters: checks and transformations on values, priors, bounds
% matched_irfs: checks and transformations
% -------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
[oo_.mom.data_moments, oo_.mom.weighting_info.W, options_mom_.mom.irfIndex, options_mom_.irf] = mom.matched_irfs_blocks(M_.matched_irfs, M_.matched_irfs_weights, options_mom_.varobs_id, options_mom_.obs_nbr, M_.exo_nbr, M_.endo_names, M_.exo_names);
% compute inverse of weighting matrix
try
oo_.mom.weighting_info.Winv = inv(oo_.mom.weighting_info.W);
catch
error('method_of_moments: Something wrong while computing inv(W), check your weighting matrix!');
end
if any(isnan(oo_.mom.weighting_info.Winv(:))) || any(isinf(oo_.mom.weighting_info.Winv(:)))
error('method_of_moments: There are NaN or Inf values in inv(W), check your weighting matrix!');
end
% compute log determinant of inverse of weighting matrix in a robust way to avoid Inf or NaN
try
oo_.mom.weighting_info.Winv_logdet = 2*sum(log(diag(chol(oo_.mom.weighting_info.Winv))));
catch
error('method_of_moments: Something wrong while computing log(det(inv(W))), check your weighting matrix!');
end
if any(isnan(oo_.mom.weighting_info.Winv_logdet(:))) || any(isinf(oo_.mom.weighting_info.Winv_logdet(:)))
error('method_of_moments: There are NaN or Inf values in log(det(inv(W))), check your weighting matrix!');
end
options_mom_.mom.mom_nbr = length(options_mom_.mom.irfIndex);
end
% -------------------------------------------------------------------------
% irf_matching_file: checks and transformations
% -------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
[options_mom_.mom.irf_matching_file.name, options_mom_.mom.irf_matching_file.path] = mom.check_irf_matching_file(options_mom_.mom.irf_matching_file.name);
% check for irf_matching_file
if ~( isempty(options_mom_.mom.irf_matching_file.path) || strcmp(options_mom_.mom.irf_matching_file.path,'.') )
fprintf('\nAdding %s to MATLAB''s path.\n',options_mom_.mom.irf_matching_file.path);
addpath(options_mom_.mom.irf_matching_file.path);
end
end
% -------------------------------------------------------------------------
% estimated parameters: checks and transformations on values, priors, bounds, posterior options
% -------------------------------------------------------------------------
% set priors and bounds over the estimated parameters
[xparam0, estim_params_, bayestopt_, lb, ub, M_] = set_prior(estim_params_, M_, options_mom_);
number_of_estimated_parameters = length(xparam0);
hessian_xparam0 = []; % initialize hessian
% check if enough moments for estimation
if strcmp(options_mom_.mom.mom_method, 'GMM') || strcmp(options_mom_.mom.mom_method, 'SMM')
if options_mom_.mom.mom_nbr < length(xparam0)
skipline;
error('method_of_moments: There must be at least as many moments as parameters for a %s estimation!',options_mom_.mom.mom_method);
end
skipline(2);
if options_mom_.mom.mom_nbr < length(xparam0)
skipline;
error('method_of_moments: There must be at least as many moments as parameters for a %s estimation!',options_mom_.mom.mom_method);
end
skipline(2);
% 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
% check that the provided mode_file is compatible with the current estimation settings
if ~isempty(options_mom_.mode_file) && ( ~do_bayesian_estimation || (do_bayesian_estimation && ~options_mom_.mh_posterior_mode_estimation) )
[xparam0, hessian_xparam0] = check_mode_file(xparam0, hessian_xparam0, options_mom_, bayestopt_);
end
% check on specified priors and penalized estimation (which uses Laplace approximated priors)
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
bayestopt_orig = bayestopt_;
@ -298,7 +300,6 @@ if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_meth
bayestopt_ = mom.transform_prior_to_laplace_prior(bayestopt_);
end
end
% check for calibrated covariances before updating parameters
estim_params_ = check_for_calibrated_covariances(estim_params_,M_);
@ -310,89 +311,104 @@ else
estim_params_.full_calibration_detected = false;
end
if options_mom_.use_calibration_initialization % set calibration as starting values
if ~isempty(bayestopt_) && ~doBayesianEstimation && any(all(isnan([xparam_calib xparam0]),2))
if ~isempty(bayestopt_) && ~do_bayesian_estimation && any(all(isnan([xparam_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_,xparam_calib,xparam0); % get explicitly initialized parameters that have precedence over calibrated values
end
end
% check initialization
if ~isempty(bayestopt_) && ~doBayesianEstimation && any(isnan(xparam0))
if ~isempty(bayestopt_) && ~do_bayesian_estimation && any(isnan(xparam0))
error('method_of_moments: Frequentist %s 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_) && doBayesianEstimation
if ~isempty(bayestopt_) && do_bayesian_estimation
% plot prior densities
if ~options_mom_.nograph && options_mom_.plot_priors
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
plot_priors(bayestopt_orig,M_,estim_params_,options_mom_,'Original priors'); % only for visual inspection (not saved to disk, because overwritten in next call to plot_priors)
plot_priors(bayestopt_,M_,estim_params_,options_mom_,'Laplace approximated priors');
clear('bayestopt_orig'); % make sure stale structure cannot be used
else
plot_priors(bayestopt_,M_,estim_params_,options_mom_,'Priors');
end
end
% set prior bounds
Bounds = prior_bounds(bayestopt_, options_mom_.prior_trunc);
Bounds.lb = max(Bounds.lb,lb);
Bounds.ub = min(Bounds.ub,ub);
BoundsInfo = prior_bounds(bayestopt_, options_mom_.prior_trunc);
BoundsInfo.lb = max(BoundsInfo.lb,lb);
BoundsInfo.ub = min(BoundsInfo.ub,ub);
else
% no priors are declared so Dynare will estimate the parameters with
% Frequentist methods using inequality constraints for the parameters
Bounds.lb = lb;
Bounds.ub = ub;
if options_mom_.mom.penalized_estimator
fprintf('Penalized estimation turned off as you did not declare priors\n')
% no priors are declared so Dynare will estimate the parameters with Frequentist methods using inequality constraints for the parameters
BoundsInfo.lb = lb;
BoundsInfo.ub = ub;
if (strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')) && options_mom_.mom.penalized_estimator
fprintf('Penalized estimation turned off as you did not declare priors\n');
options_mom_.mom.penalized_estimator = 0;
else
if isfield(options_mom_,'mh_replic') && options_mom_.mh_replic > 0
fprintf('Setting ''mh_replic=0'' as you did not declare priors.\n');
options_mom_.mh_replic = 0;
end
end
end
% set correct bounds for standard deviations and correlations
Bounds = mom.set_correct_bounds_for_stderr_corr(estim_params_,Bounds);
BoundsInfo = mom.set_correct_bounds_for_stderr_corr(estim_params_,BoundsInfo);
% 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_);
check_prior_bounds(xparam0,BoundsInfo,M_,estim_params_,options_mom_,bayestopt_);
catch last_error
fprintf('Cannot use parameter values from calibration as they violate the prior bounds.')
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_);
check_prior_bounds(xparam0,BoundsInfo,M_,estim_params_,options_mom_,bayestopt_);
end
% check for positive definiteness
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 results
oo_.mom.prior.mean = bayestopt_.p1;
oo_.mom.prior.mode = bayestopt_.p5;
oo_.mom.prior.variance = diag(bayestopt_.p2.^2);
oo_.mom.prior.hyperparameters.first = bayestopt_.p6;
oo_.mom.prior.hyperparameters.second = bayestopt_.p7;
% storing prior parameters in results structure
if do_bayesian_estimation || ( (strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')) && options_mom_.mom.penalized_estimator)
oo_.mom.prior.mean = bayestopt_.p1;
oo_.mom.prior.mode = bayestopt_.p5;
oo_.mom.prior.variance = diag(bayestopt_.p2.^2);
oo_.mom.prior.hyperparameters.first = bayestopt_.p6;
oo_.mom.prior.hyperparameters.second = bayestopt_.p7;
end
% 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_);
if doBayesianEstimation
% warning if prior allows that stderr parameters are negative or corr parameters are outside the unit circle
% set jscale
if do_bayesian_estimation_mcmc
if ~strcmp(options_mom_.posterior_sampler_options.posterior_sampling_method,'slice')
if isempty(options_mom_.mh_jscale)
options_mom_.mh_jscale = 2.38/sqrt(number_of_estimated_parameters); % use optimal value for univariate normal distribution (check_posterior_sampler_options and mode_compute=6 may overwrite this setting)
end
bayestopt_.jscale(find(isnan(bayestopt_.jscale))) = options_mom_.mh_jscale;
end
end
% initialization of posterior sampler options
if do_bayesian_estimation_mcmc
[current_options, options_mom_, bayestopt_] = check_posterior_sampler_options([], M_.fname, M_.dname, options_mom_, BoundsInfo, bayestopt_);
options_mom_.posterior_sampler_options.current_options = current_options;
if strcmp(current_options.posterior_sampling_method,'slice') && current_options.use_mh_covariance_matrix && ~current_options.rotated
error('method_of_moments: Using the slice sampler with the ''use_mh_covariance_matrix'' option requires also setting the ''rotated'' option!');
end
end
% warning if prior allows that stderr parameters are negative or corr parameters are outside the unit circle
if do_bayesian_estimation
check_prior_stderr_corr(estim_params_,bayestopt_);
% check value of prior density
[~,~,~,info]= priordens(xparam0,bayestopt_.pshape,bayestopt_.p6,bayestopt_.p7,bayestopt_.p3,bayestopt_.p4);
[~,~,~,info] = priordens(xparam0,bayestopt_.pshape,bayestopt_.p6,bayestopt_.p7,bayestopt_.p3,bayestopt_.p4);
if any(info)
fprintf('The prior density evaluated at the initial values is Inf for the following parameters: %s\n',bayestopt_.name{info,1})
error('The initial value of the prior is -Inf!')
fprintf('The prior density evaluated at the initial values is Inf for the following parameters: %s\n',bayestopt_.name{info,1});
error('The initial value of the prior is -Inf!');
end
end
@ -400,34 +416,34 @@ end
% -------------------------------------------------------------------------
% datafile: checks and transformations
% -------------------------------------------------------------------------
% Build dataset
% build dataset
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
% Check if datafile has same name as mod file
[~,name,~] = fileparts(options_mom_.datafile);
% check if datafile has same name as mod file
[~,name] = fileparts(options_mom_.datafile);
if strcmp(name,M_.fname)
error('method_of_moments: ''datafile'' and mod file are not allowed to have the same name; change the name of the ''datafile''!')
error('method_of_moments: ''datafile'' and mod file are not allowed to have the same name; change the name of the ''datafile''!');
end
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
% check length of data for estimation of second moments
if options_mom_.ar > options_mom_.nobs+1
error('method_of_moments: Dataset is too short to compute higher than first moments!');
end
% Provide info on data moments handling
% provide info on data moments handling
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');
% Get data moments for the method of moments
[oo_.mom.data_moments, oo_.mom.m_data] = mom.get_data_moments(dataset_.data, oo_.mom.obs_var, oo_.dr.inv_order_var, M_.matched_moments, options_mom_);
% get data moments for the method of moments
[oo_.mom.data_moments, oo_.mom.m_data] = mom.get_data_moments(dataset_.data, options_mom_.mom.obs_var, oo_.dr.inv_order_var, M_.matched_moments, options_mom_);
if ~isreal(dataset_.data)
error('method_of_moments: The data moments contain complex values!')
error('method_of_moments: The data moments contain complex values!');
end
end
% -------------------------------------------------------------------------
% SMM: Get shock series fand set variance correction factor
% SMM: Get shock series and set variance correction factor
% -------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'SMM')
options_mom_.mom.long = round(options_mom_.mom.simulation_multiple*options_mom_.nobs);
@ -461,7 +477,6 @@ end
% -------------------------------------------------------------------------
% checks for steady state at initial parameters
% -------------------------------------------------------------------------
% check if steady state solves static model and if steady-state changes estimated parameters
if options_mom_.steadystate.nocheck
steadystate_check_flag_vec = [0 1];
@ -470,7 +485,7 @@ else
end
[oo_.steady_state, info, steady_state_changes_parameters] = check_steady_state_changes_parameters(M_, estim_params_, oo_, options_mom_, steadystate_check_flag_vec);
if info(1)
fprintf('\nThe steady state at the initial parameters cannot be computed.\n')
fprintf('\nThe steady state at the initial parameters cannot be computed.\n');
print_info(info, 0, options_mom_);
end
if steady_state_changes_parameters && strcmp(options_mom_.mom.mom_method,'GMM') && options_mom_.mom.analytic_standard_errors
@ -478,7 +493,6 @@ if steady_state_changes_parameters && strcmp(options_mom_.mom.mom_method,'GMM')
fprintf('because the steady-state changes estimated parameters. Option ''analytic_derivation_mode'' reset to -2.');
options_mom_.analytic_derivation_mode = -2;
end
% display warning if some parameters are still NaN
test_for_deep_parameters_calibration(M_);
@ -488,17 +502,25 @@ test_for_deep_parameters_calibration(M_);
% -------------------------------------------------------------------------
objective_function = str2func('mom.objective_function');
try
% Check for NaN or complex values of moment-distance-funtion evaluated at initial parameters
% check for NaN or complex values of moment-distance-funtion evaluated at initial parameters
if strcmp(options_mom_.mom.mom_method,'SMM') || strcmp(options_mom_.mom.mom_method,'GMM')
oo_.mom.Sw = eye(options_mom_.mom.mom_nbr); % initialize with identity weighting matrix
oo_.mom.weighting_info.Sw = eye(options_mom_.mom.mom_nbr); % initialize with identity weighting matrix
end
tic_id = tic;
[fval, info, ~, ~, ~, oo_, M_] = feval(objective_function, xparam0, Bounds, oo_, estim_params_, M_, options_mom_);
[fval, info] = feval(objective_function, xparam0, oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
elapsed_time = toc(tic_id);
if isnan(fval)
error('method_of_moments: The initial value of the objective function with identity weighting matrix is NaN!')
if strcmp(options_mom_.mom.mom_method,'SMM') || strcmp(options_mom_.mom.mom_method,'GMM')
error('method_of_moments: The initial value of the objective function with identity weighting matrix is NaN!');
else
error('method_of_moments: The initial value of the objective function is NaN!');
end
elseif imag(fval)
error('method_of_moments: The initial value of the objective function with identity weighting matrix is complex!')
if strcmp(options_mom_.mom.mom_method,'SMM') || strcmp(options_mom_.mom.mom_method,'GMM')
error('method_of_moments: The initial value of the objective function with identity weighting matrix is complex!');
else
error('method_of_moments: The initial value of the objective function is complex!');
end
end
if info(1) > 0
disp('method_of_moments: Error in computing the objective function for initial parameter values')
@ -513,10 +535,10 @@ try
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('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
@ -527,60 +549,281 @@ end
% -------------------------------------------------------------------------
% print some info to console
% -------------------------------------------------------------------------
mom.print_info_on_estimation_settings(options_mom_, number_of_estimated_parameters);
mom.print_info_on_estimation_settings(options_mom_, number_of_estimated_parameters, do_bayesian_estimation);
% -------------------------------------------------------------------------
% GMM/SMM: iterated estimation
% compute mode for GMM/SMM
% -------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
[xparam1, oo_.mom.weighting_info, oo_.mom.verbose] = mom.mode_compute_gmm_smm(xparam0, objective_function, oo_.mom.m_data, oo_.mom.data_moments, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
end
% -------------------------------------------------------------------------
% compute mode for IRF matching
% -------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
if ~do_bayesian_estimation || (do_bayesian_estimation && ~options_mom_.mh_posterior_mode_estimation)
[xparam1, hessian_xparam1, fval, oo_.mom.verbose] = mom.mode_compute_irf_matching(xparam0, hessian_xparam0, objective_function, do_bayesian_estimation, oo_.mom.weighting_info, oo_.mom.data_moments, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
else
xparam1 = xparam0;
hessian_xparam1 = hessian_xparam0;
end
end
% -------------------------------------------------------------------------
% compute standard errors and initialize covariance of the proposal distribution
% -------------------------------------------------------------------------
if strcmp(options_mom_.mom.mom_method,'GMM') || strcmp(options_mom_.mom.mom_method,'SMM')
% compute mode
[xparam1, oo_, Woptflag] = mom.mode_compute_gmm_smm(xparam0, objective_function, oo_, M_, options_mom_, estim_params_, bayestopt_, Bounds);
% compute standard errors at mode
options_mom_.mom.vector_output = false; % make sure flag is reset
M_ = set_all_parameters(xparam1,estim_params_,M_); % update M_ and oo_ (in particular to get oo_.mom.model_moments)
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
[~, ~, ~,~,~, oo_] = feval(objective_function, xparam1, Bounds, oo_, estim_params_, M_, options_mom_); % compute model moments and oo_.mom.model_moments_params_derivs
[~, ~, ~, ~, ~, oo_.mom.Q, oo_.mom.model_moments, oo_.mom.model_moments_params_derivs] = feval(objective_function, xparam1, oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
options_mom_.mom.compute_derivs = false; % reset to not compute derivatives in objective function during optimization
[stdh,hessian_xparam1] = mom.standard_errors(xparam1, objective_function, Bounds, oo_, estim_params_, M_, options_mom_, Woptflag);
[stdh, invhess] = mom.standard_errors(xparam1, objective_function, oo_.mom.model_moments, oo_.mom.model_moments_params_derivs, oo_.mom.m_data, oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
if options_mom_.cova_compute
hessian_xparam1 = inv(invhess);
end
else
if ~do_bayesian_estimation || ~options_mom_.mh_posterior_mode_estimation
if do_bayesian_estimation
oo_.mom.posterior.optimization.mode = xparam1;
if exist('fval','var')
oo_.mom.posterior.optimization.log_density = -fval;
end
end
if options_mom_.cova_compute
hsd = sqrt(diag(hessian_xparam1)); % represent the curvature (or second derivatives) of the likelihood with respect to each parameter being estimated.
invhess = inv(hessian_xparam1./(hsd*hsd'))./(hsd*hsd'); % before taking the inverse scale the Hessian matrix by dividing each of its elements by the outer product of hsd such that the diagonal of the resulting matrix is approximately 1. This kind of scaling can help in regularizing the matrix and potentially improves its condition number, which in turn can make the matrix inversion more stable.
stdh = sqrt(diag(invhess));
if do_bayesian_estimation
oo_.mom.posterior.optimization.Variance = invhess;
end
end
else
variances = bayestopt_.p2.*bayestopt_.p2;
id_Inf = isinf(variances);
variances(id_Inf) = 1;
invhess = options_mom_.mh_posterior_mode_estimation*diag(variances);
xparam1 = bayestopt_.p5;
id_NaN = isnan(xparam1);
xparam1(id_NaN) = bayestopt_.p1(id_NaN);
outside_bound_pars=find(xparam1 < BoundsInfo.lb | xparam1 > BoundsInfo.ub);
xparam1(outside_bound_pars) = bayestopt_.p1(outside_bound_pars);
end
if ~options_mom_.cova_compute
stdh = NaN(length(xparam1),1);
end
end
% -------------------------------------------------------------------------
% display estimation results at mode
% -------------------------------------------------------------------------
if do_bayesian_estimation && ~options_mom_.mom.penalized_estimator && ~options_mom_.mh_posterior_mode_estimation
% display table with Bayesian mode estimation results and store parameter estimates and standard errors in oo_
oo_.mom = display_estimation_results_table(xparam1, stdh, M_, options_mom_, estim_params_, bayestopt_, oo_.mom, prior_dist_names, 'Posterior', 'posterior');
% Laplace approximation to the marginal log density
if options_mom_.cova_compute
estim_params_nbr = size(xparam1,1);
if ispd(invhess)
log_det_invhess = log(det(invhess./(stdh*stdh')))+2*sum(log(stdh));
likelihood = feval(objective_function, xparam1, oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
oo_.mom.MarginalDensity.LaplaceApproximation = .5*estim_params_nbr*log(2*pi) + .5*log_det_invhess - likelihood;
else
oo_.mom.MarginalDensity.LaplaceApproximation = NaN;
end
fprintf('\nLog data density [Laplace approximation] is %f.\n',oo_.mom.MarginalDensity.LaplaceApproximation);
end
elseif ~do_bayesian_estimation || (do_bayesian_estimation && options_mom_.mom.penalized_estimator)
% display table with Frequentist estimation results and store parameter estimates and standard errors in oo_
oo_.mom = display_estimation_results_table(xparam1, stdh, M_, options_mom_, estim_params_, bayestopt_, oo_.mom, prior_dist_names, options_mom_.mom.mom_method, lower(options_mom_.mom.mom_method));
end
% -------------------------------------------------------------------------
% checks for mode and hessian at the mode
% -------------------------------------------------------------------------
if (~do_bayesian_estimation && options_mom_.cova_compute) || (do_bayesian_estimation && ~options_mom_.mh_posterior_mode_estimation && options_mom_.cova_compute)
check_hessian_at_the_mode(hessian_xparam1, xparam1, M_, estim_params_, options_, BoundsInfo);
end
if options_mom_.mode_check.status
mode_check(objective_function, xparam1, hessian_xparam1, options_mom_, M_, estim_params_, bayestopt_, Bounds, true,...
Bounds, oo_, estim_params_, M_, options_mom_);
if ~do_bayesian_estimation || (do_bayesian_estimation && ~options_mom_.mh_posterior_mode_estimation)
mode_check(objective_function, xparam1, diag(stdh), options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, true,... % use diag(stdh) instead of hessian_xparam1 as mode_check uses diagonal elements
oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
end
end
% -------------------------------------------------------------------------
% Bayesian MCMC estimation
% -------------------------------------------------------------------------
if do_bayesian_estimation_mcmc
invhess = set_mcmc_jumping_covariance(invhess, length(xparam1), options_mom_.MCMC_jumping_covariance, bayestopt_, 'method_of_moments');
% reset bounds as lb and ub must only be operational during mode-finding
BoundsInfo = set_mcmc_prior_bounds(xparam1, bayestopt_, options_mom_, 'method_of_moments');
% tunes the jumping distribution's scale parameter
if isfield(options_mom_,'mh_tune_jscale') && options_mom_.mh_tune_jscale.status
if strcmp(options_mom_.posterior_sampler_options.posterior_sampling_method, 'random_walk_metropolis_hastings')
options_mom_.mh_jscale = tune_mcmc_mh_jscale_wrapper(invhess, options_mom_, M_, objective_function, xparam1, BoundsInfo,...
oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
bayestopt_.jscale(:) = options_mom_.mh_jscale;
fprintf('mh_tune_jscale: mh_jscale has been set equal to %s.\n', num2str(options_mom_.mh_jscale));
else
warning('mh_tune_jscale is only available with ''random_walk_metropolis_hastings''!')
end
end
% run MCMC sampling
posterior_sampler_options = options_mom_.posterior_sampler_options.current_options;
posterior_sampler_options.invhess = invhess;
[posterior_sampler_options, options_mom_, bayestopt_] = check_posterior_sampler_options(posterior_sampler_options, M_.fname, M_.dname, options_mom_, BoundsInfo, bayestopt_,'method_of_moments');
options_mom_.posterior_sampler_options.current_options = posterior_sampler_options; % store current options
if options_mom_.mh_replic>0
posterior_sampler(objective_function,posterior_sampler_options.proposal_distribution,xparam1,posterior_sampler_options,BoundsInfo,oo_.mom.data_moments,oo_.mom.weighting_info,options_mom_,M_,estim_params_,bayestopt_,oo_,'method_of_moments::mcmc');
end
CutSample(M_, options_mom_, 'method_of_moments::mcmc'); % discard first mh_drop percent of the draws
if options_mom_.mh_posterior_mode_estimation
% skip optimizer-based mode-finding and instead compute the mode based on a run of a MCMC
[~,~,posterior_mode,~] = compute_mh_covariance_matrix(bayestopt_,M_.fname,M_.dname,'method_of_moments');
oo_.mom = fill_mh_mode(posterior_mode',NaN(length(posterior_mode),1),M_,options_mom_,estim_params_,bayestopt_,oo_.mom,'posterior');
return
else
% get stored results if required
if options_mom_.load_mh_file && options_mom_.load_results_after_load_mh
oo_load_mh = load([M_.dname filesep 'method_of_moments' filesep M_.fname '_mom_results'],'oo_');
end
% convergence diagnostics
if ~options_mom_.nodiagnostic
if (options_mom_.mh_replic>0 || (options_mom_.load_mh_file && ~options_mom_.load_results_after_load_mh))
oo_.mom = mcmc_diagnostics(options_mom_, estim_params_, M_, oo_.mom);
elseif options_mom_.load_mh_file && options_mom_.load_results_after_load_mh
if isfield(oo_load_mh.oo_.mom,'convergence')
oo_.mom.convergence = oo_load_mh.oo_.mom.convergence;
end
end
end
% statistics and plots for posterior draws
if options_mom_.mh_replic || (options_mom_.load_mh_file && ~options_mom_.load_results_after_load_mh)
[~,oo_.mom] = marginal_density(M_, options_mom_, estim_params_, oo_.mom, bayestopt_, 'method_of_moments');
oo_.mom = GetPosteriorParametersStatistics(estim_params_, M_, options_mom_, bayestopt_, oo_.mom, prior_dist_names);
if ~options_mom_.nograph
oo_.mom = PlotPosteriorDistributions(estim_params_, M_, options_mom_, bayestopt_, oo_.mom);
end
[oo_.mom.posterior.metropolis.mean,oo_.mom.posterior.metropolis.Variance] = GetPosteriorMeanVariance(options_mom_,M_);
elseif options_mom_.load_mh_file && options_mom_.load_results_after_load_mh
% load fields from previous MCMC run stored in results-file
field_names={'posterior_mode','posterior_std_at_mode',...% fields set by marginal_density
'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
};
for field_iter=1:size(field_names,2)
if isfield(oo_load_mh.oo_.mom,field_names{1,field_iter})
oo_.mom.(field_names{1,field_iter}) = oo_load_mh.oo_.mom.(field_names{1,field_iter});
end
end
if isfield(oo_load_mh.oo_.mom,'MarginalDensity') && isfield(oo_load_mh.oo_.mom.MarginalDensity,'ModifiedHarmonicMean') % field set by marginal_density
oo_.mom.MarginalDensity.ModifiedHarmonicMean = oo_load_mh.oo_.mom.MarginalDensity.ModifiedHarmonicMean;
end
if isfield(oo_load_mh.oo_.mom,'posterior') && isfield(oo_load_mh.oo_.mom.posterior,'metropolis') % field set by GetPosteriorMeanVariance
oo_.mom.posterior.metropolis = oo_load_mh.oo_.mom.posterior.metropolis;
end
end
[error_flag,~,options_mom_]= metropolis_draw(1,options_mom_,estim_params_,M_);
if ~(~isempty(options_mom_.sub_draws) && options_mom_.sub_draws==0)
% THIS IS PROBABLY NOT USEFUL HERE AND CAN BE REMOVED (PREPROCESSOR: REMOVE bayesian_irf, moments_varendo)
%if options_mom_.bayesian_irf
% if error_flag
% error('method_of_moments: Cannot compute the posterior IRFs!');
% end
% PosteriorIRF('posterior','method_of_moments::mcmc');
%end
% if options_mom_.moments_varendo
% if error_flag
% error('method_of_moments: Cannot compute the posterior moments for the endogenous variables!');
% end
% if options_mom_.load_mh_file && options_mom_.mh_replic==0 %user wants to recompute results
% [MetropolisFolder, info] = CheckPath('metropolis',options_mom_.dirname);
% 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
% end
% oo_ = compute_moments_varendo('posterior',options_,M_,oo_,var_list_);
% end
else
fprintf('''sub_draws'' was set to 0. Skipping posterior computations.');
end
xparam1 = get_posterior_parameters('mean',M_,estim_params_,oo_.mom,options_);
end
% MAYBE USEFUL????
% % Posterior correlations
% extreme_corr_bound = 0.7;
% if ~isnan(extreme_corr_bound)
% tril_para_correlation_matrix=tril(para_correlation_matrix,-1);
% [row_index,col_index]=find(abs(tril_para_correlation_matrix)>extreme_corr_bound);
% extreme_corr_params=cell(length(row_index),3);
% for i=1:length(row_index)
% extreme_corr_params{i,1}=char(parameter_names(row_index(i),:));
% extreme_corr_params{i,2}=char(parameter_names(col_index(i),:));
% extreme_corr_params{i,3}=tril_para_correlation_matrix(row_index(i),col_index(i));
% end
% end
% disp(' ');
% disp(['Correlations of Parameters (at Posterior Mode) > ',num2str(extreme_corr_bound)]);
% disp(extreme_corr_params)
end
% -------------------------------------------------------------------------
% display final estimation results
% -------------------------------------------------------------------------
M_ = set_all_parameters(xparam1,estim_params_,M_); % update parameters
[~, ~, ~, ~, ~, oo_.mom.Q, oo_.mom.model_moments, oo_.mom.model_moments_params_derivs, oo_.mom.irf_model_varobs] = objective_function(xparam1, oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state); % store final results in oo_.mom
if strcmp(options_mom_.mom.mom_method,'SMM') || strcmp(options_mom_.mom.mom_method,'GMM')
% Store results in output structure
oo_.mom = display_estimation_results_table(xparam1,stdh,M_,options_mom_,estim_params_,bayestopt_,oo_.mom,prior_dist_names,options_mom_.mom.mom_method,lower(options_mom_.mom.mom_method));
% J test
oo_ = mom.Jtest(xparam1, objective_function, Woptflag, oo_, options_mom_, bayestopt_, Bounds, estim_params_, M_, dataset_.nobs);
% display comparison of model moments and data moments
mom.display_comparison_moments(M_, options_mom_, oo_.mom.data_moments, oo_.mom.model_moments);
oo_.mom.J_test = mom.Jtest(xparam1, objective_function, oo_.mom.Q, oo_.mom.model_moments, oo_.mom.m_data, oo_.mom.data_moments, oo_.mom.weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
elseif strcmp(options_mom_.mom.mom_method,'IRF_MATCHING')
if ~options_mom_.nograph
mom.graph_comparison_irfs(M_.matched_irfs,oo_.mom.irf_model_varobs,options_mom_.varobs_id,options_mom_.irf,options_mom_.relative_irf,M_.endo_names,M_.endo_names_tex,M_.exo_names,M_.exo_names_tex,M_.dname,M_.fname,options_mom_.graph_format,options_mom_.TeX,options_mom_.nodisplay,options_mom_.figures.textwidth)
end
end
% display comparison of model moments/IRFs and data moments/IRFs
mom.display_comparison_moments_irfs(M_, options_mom_, oo_.mom.data_moments, oo_.mom.model_moments);
% save results to _mom_results.mat
save([M_.dname filesep 'method_of_moments' filesep M_.fname '_mom_results.mat'], 'oo_', 'options_mom_', 'M_', 'estim_params_', 'bayestopt_');
fprintf('\n==== Method of Moments Estimation (%s) Completed ====\n\n',options_mom_.mom.mom_method);
% -------------------------------------------------------------------------
% clean up
% -------------------------------------------------------------------------
fprintf('\n==== Method of Moments Estimation (%s) Completed ====\n\n',options_mom_.mom.mom_method)
%reset warning state
warning_config;
warning_config; %reset warning state
if isoctave && isfield(options_mom_, 'prior_restrictions') && ...
isfield(options_mom_.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_mom_.prior_restrictions.routine = [];
end
if strcmp(options_mom_.mom.mom_method,'SMM') || strcmp(options_mom_.mom.mom_method,'GMM')
if isfield(oo_.mom,'irf_model_varobs') && isempty(oo_.mom.irf_model_varobs)
oo_.mom = rmfield(oo_.mom,'irf_model_varobs'); % remove empty field
end
end
if strcmp(options_mom_.mom.mom_method,'IRF_MATCHING') && ~isempty(options_mom_.mom.irf_matching_file.path) && ~strcmp(options_mom_.mom.irf_matching_file.path,'.')
rmpath(options_mom_.irf_matching_file.path); % remove path to irf_matching_file
end

View File

@ -1,18 +1,19 @@
function Bounds = set_correct_bounds_for_stderr_corr(estim_params_,Bounds)
% function Bounds = set_correct_bounds_for_stderr_corr(estim_params_,Bounds)
function BoundsInfo = set_correct_bounds_for_stderr_corr(estim_params_,BoundsInfo)
% BoundsInfo = set_correct_bounds_for_stderr_corr(estim_params_,BoundsInfo)
% -------------------------------------------------------------------------
% Set correct bounds for standard deviation and corrrelation parameters
% =========================================================================
% -------------------------------------------------------------------------
% INPUTS
% o estim_params_ [struct] information on estimated parameters
% o Bounds [struct] information on bounds
% o BoundsInfo [struct] information on bounds
% -------------------------------------------------------------------------
% OUTPUT
% o Bounds [struct] updated bounds
% o BoundsInfo [struct] updated bounds
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% =========================================================================
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
@ -29,15 +30,15 @@ function Bounds = set_correct_bounds_for_stderr_corr(estim_params_,Bounds)
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
number_of_estimated_parameters = estim_params_.nvx+estim_params_.nvn+estim_params_.ncx+estim_params_.ncn+estim_params_.np;
% set correct bounds for standard deviations and corrrelations
param_of_interest = (1:number_of_estimated_parameters)'<=estim_params_.nvx+estim_params_.nvn;
LB_below_0 = (Bounds.lb<0 & param_of_interest);
Bounds.lb(LB_below_0) = 0;
LB_below_0 = (BoundsInfo.lb<0 & param_of_interest);
BoundsInfo.lb(LB_below_0) = 0;
param_of_interest = (1:number_of_estimated_parameters)'> estim_params_.nvx+estim_params_.nvn & (1:number_of_estimated_parameters)'<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;
LB_below_minus_1 = (BoundsInfo.lb<-1 & param_of_interest);
UB_above_1 = (BoundsInfo.ub>1 & param_of_interest);
BoundsInfo.lb(LB_below_minus_1) = -1;
BoundsInfo.ub(UB_above_1) = 1;

View File

@ -1,23 +1,32 @@
function [SE_values, Asympt_Var] = standard_errors(xparam, objective_function, Bounds, oo_, estim_params_, M_, options_mom_, Wopt_flag)
% [SE_values, Asympt_Var] = standard_errors(xparam, objective_function, Bounds, oo_, estim_params_, M_, options_mom_, Wopt_flag)
function [stderr_values, asympt_cov_mat] = standard_errors(xparam, objective_function, model_moments, model_moments_params_derivs, m_data, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% [stderr_values, asympt_cov_mat] = standard_errors(xparam, objective_function, model_moments, model_moments_params_derivs, m_data, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state)
% -------------------------------------------------------------------------
% This function computes standard errors to the method of moments estimates
% Adapted from replication codes of
% 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.
% =========================================================================
% Adapted from replication codes of 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.
% -------------------------------------------------------------------------
% INPUTS
% o xparam: value of estimated parameters as returned by set_prior()
% o objective_function string of objective function
% o Bounds: structure containing parameter bounds
% o oo_: structure for results
% o estim_params_: structure describing the estimated_parameters
% o M_ structure describing the model
% o options_mom_: structure information about all settings (specified by the user, preprocessor, and taken from global options_)
% o Wopt_flag: indicator whether the optimal weighting is actually used
% - xparam: [vector] value of estimated parameters as returned by set_prior()
% - objective_function [func] function handle with string of objective function
% - model_moments: [vector] model moments
% - model_moments_params_derivs: [matrix] analytical jacobian of the model moments wrt estimated parameters (currently for GMM only)
% - m_data [matrix] selected empirical moments at each point in time
% - data_moments: [vector] data with moments/IRFs to match
% - weighting_info: [structure] storing information on weighting matrices
% - options_mom_: [structure] information about all settings (specified by the user, preprocessor, and taken from global options_)
% - M_ [structure] model information
% - estim_params_: [structure] information from estimated_params block
% - bayestopt_: [structure] information on the prior distributions
% - BoundsInfo: [structure] parameter bounds
% - dr: [structure] reduced form model
% - endo_steady_state: [vector] steady state value for endogenous variables (initval)
% - exo_steady_state: [vector] steady state value for exogenous variables (initval)
% - exo_det_steady_state: [vector] steady state value for exogenous deterministic variables (initval)
% -------------------------------------------------------------------------
% OUTPUTS
% o SE_values [nparam x 1] vector of standard errors
% o Asympt_Var [nparam x nparam] asymptotic covariance matrix
% o stderr_values [nparam x 1] vector of standard errors
% o asympt_cov_mat [nparam x nparam] asymptotic covariance matrix
% -------------------------------------------------------------------------
% This function is called by
% o mom.run.m
@ -26,9 +35,10 @@ function [SE_values, Asympt_Var] = standard_errors(xparam, objective_function, B
% o get_the_name
% o get_error_message
% o mom.objective_function
% o mom.optimal_weighting_matrix
% =========================================================================
% Copyright © 2020-2021 Dynare Team
% o mom.optimal_weighting_matrix
% -------------------------------------------------------------------------
% Copyright © 2020-2023 Dynare Team
%
% This file is part of Dynare.
%
@ -44,84 +54,74 @@ function [SE_values, Asympt_Var] = standard_errors(xparam, objective_function, B
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------
% Author(s):
% o Willi Mutschler (willi@mutschler.eu)
% o Johannes Pfeifer (johannes.pfeifer@unibw.de)
% =========================================================================
% Some dimensions
num_mom = size(oo_.mom.model_moments,1);
num_mom = size(model_moments,1);
dim_params = size(xparam,1);
D = zeros(num_mom,dim_params);
eps_value = options_mom_.mom.se_tolx;
if strcmp(options_mom_.mom.mom_method,'GMM') && options_mom_.mom.analytic_standard_errors
fprintf('\nComputing standard errors using analytical derivatives of moments\n');
D = oo_.mom.model_moments_params_derivs; %already computed in objective function via get_perturbation_params.m
D = model_moments_params_derivs; % already computed in objective function via get_perturbation_params.m
idx_nan = find(any(isnan(D)));
if any(idx_nan)
for i = idx_nan
fprintf('No standard errors available for parameter %s\n',get_the_name(i,options_mom_.TeX, M_, estim_params_, options_mom_.varobs))
end
warning('There are NaN in the analytical Jacobian of Moments. Check your bounds and/or priors, or use a different optimizer.')
Asympt_Var = NaN(length(xparam),length(xparam));
SE_values = NaN(length(xparam),1);
asympt_cov_mat = NaN(length(xparam),length(xparam));
stderr_values = NaN(length(xparam),1);
return
end
else
fprintf('\nComputing standard errors using numerical derivatives of moments\n');
for i=1:dim_params
%Positive step
% positive step
xparam_eps_p = xparam;
xparam_eps_p(i,1) = xparam_eps_p(i) + eps_value;
[~, info_p, ~, ~,~, oo__p] = feval(objective_function, xparam_eps_p, Bounds, oo_, estim_params_, M_, options_mom_);
% Negative step
xparam_eps_p(i,1) = xparam_eps_p(i) + eps_value;
[~, info_p, ~, ~, ~, ~, model_moments_p] = feval(objective_function, xparam_eps_p, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
% negative step
xparam_eps_m = xparam;
xparam_eps_m(i,1) = xparam_eps_m(i) - eps_value;
[~, info_m, ~, ~,~, oo__m] = feval(objective_function, xparam_eps_m, Bounds, oo_, estim_params_, M_, options_mom_);
% The Jacobian:
xparam_eps_m(i,1) = xparam_eps_m(i) - eps_value;
[~, info_m, ~, ~, ~, ~, model_moments_m] = feval(objective_function, xparam_eps_m, data_moments, weighting_info, options_mom_, M_, estim_params_, bayestopt_, BoundsInfo, dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
% the Jacobian
if nnz(info_p)==0 && nnz(info_m)==0
D(:,i) = (oo__p.mom.model_moments - oo__m.mom.model_moments)/(2*eps_value);
D(:,i) = (model_moments_p - model_moments_m)/(2*eps_value);
else
problpar = get_the_name(i,options_mom_.TeX, M_, estim_params_, options_mom_.varobs);
problematic_parameter = get_the_name(i,options_mom_.TeX, M_, estim_params_, options_mom_.varobs);
if info_p(1)==42
warning('method_of_moments:info','Cannot compute the Jacobian using finite differences for parameter %s due to hitting the upper bound - no standard errors available.\n',problpar)
warning('method_of_moments:info','Cannot compute the Jacobian using finite differences for parameter %s due to hitting the upper bound - no standard errors available.\n',problematic_parameter)
else
message_p = get_error_message(info_p, options_mom_);
end
if info_m(1)==41
warning('method_of_moments:info','Cannot compute the Jacobian using finite differences for parameter %s due to hitting the lower bound - no standard errors available.\n',problpar)
warning('method_of_moments:info','Cannot compute the Jacobian using finite differences for parameter %s due to hitting the lower bound - no standard errors available.\n',problematic_parameter)
else
message_m = get_error_message(info_m, options_mom_);
message_m = get_error_message(info_m, options_mom_);
end
if info_m(1)~=41 && info_p(1)~=42
warning('method_of_moments:info','Cannot compute the Jacobian using finite differences for parameter %s - no standard errors available\n %s %s\nCheck your priors or use a different optimizer.\n',problpar, message_p, message_m)
warning('method_of_moments:info','Cannot compute the Jacobian using finite differences for parameter %s - no standard errors available\n %s %s\nCheck your priors or use a different optimizer.\n',problematic_parameter, message_p, message_m)
end
Asympt_Var = NaN(length(xparam),length(xparam));
SE_values = NaN(length(xparam),1);
asympt_cov_mat = NaN(length(xparam),length(xparam));
stderr_values = NaN(length(xparam),1);
return
end
end
end
T = options_mom_.nobs; %Number of observations
T = options_mom_.nobs;
if isfield(options_mom_,'variance_correction_factor')
T = T*options_mom_.variance_correction_factor;
end
WW = oo_.mom.Sw'*oo_.mom.Sw;
if Wopt_flag
% We have the optimal weighting matrix
Asympt_Var = 1/T*((D'*WW*D)\eye(dim_params));
WW = weighting_info.Sw'*weighting_info.Sw;
if weighting_info.Woptflag
% we already have the optimal weighting matrix
asympt_cov_mat = 1/T*((D'*WW*D)\eye(dim_params));
else
% We do not have the optimal weighting matrix yet
WWopt = mom.optimal_weighting_matrix(oo_.mom.m_data, oo_.mom.model_moments, options_mom_.mom.bartlett_kernel_lag);
% we do not have the optimal weighting matrix yet
WWopt = mom.optimal_weighting_matrix(m_data, model_moments, options_mom_.mom.bartlett_kernel_lag);
S = WWopt\eye(size(WWopt,1));
AA = (D'*WW*D)\eye(dim_params);
Asympt_Var = 1/T*AA*D'*WW*S*WW*D*AA;
asympt_cov_mat = 1/T*AA*D'*WW*S*WW*D*AA;
end
SE_values = sqrt(diag(Asympt_Var));
stderr_values = sqrt(diag(asympt_cov_mat));

View File

@ -1,10 +1,10 @@
function bayestopt_ = transform_prior_to_laplace_prior(bayestopt_)
% function bayestopt_ = transform_prior_to_laplace_prior(bayestopt_)
% bayestopt_ = transform_prior_to_laplace_prior(bayestopt_)
% -------------------------------------------------------------------------
% Transforms the prior specification to a Laplace type of approximation:
% only the prior mean and standard deviation are relevant, all other shape
% information, except for the parameter bounds, is ignored.
% =========================================================================
% -------------------------------------------------------------------------
% INPUTS
% bayestopt_ [structure] prior information
% -------------------------------------------------------------------------
@ -13,7 +13,8 @@ function bayestopt_ = transform_prior_to_laplace_prior(bayestopt_)
% -------------------------------------------------------------------------
% This function is called by
% o mom.run
% =========================================================================
% -------------------------------------------------------------------------
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
@ -30,7 +31,7 @@ function bayestopt_ = transform_prior_to_laplace_prior(bayestopt_)
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% =========================================================================
if any(setdiff([0;bayestopt_.pshape],[0,3]))
fprintf('\nNon-normal priors specified. Penalized estimation uses a Laplace type of approximation:');
fprintf('\nOnly the prior mean and standard deviation are relevant, all other shape information, except for the parameter bounds, is ignored.\n\n');

View File

@ -65,8 +65,10 @@ regime_history=[];
if options_.occbin.smoother.linear_smoother && nargin==12
%% linear smoother
options_.occbin.smoother.status=false;
[alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_);
tmp_smoother=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,P,PK,decomp,Trend,state_uncertainty);
[alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,oo_,bayestopt_,alphahat0,state_uncertainty0] = ...
DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_);
tmp_smoother=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,...
aK,P,PK,decomp,Trend,state_uncertainty);
for jf=1:length(smoother_field_list)
oo_.occbin.linear_smoother.(smoother_field_list{jf}) = tmp_smoother.(smoother_field_list{jf});
end
@ -80,7 +82,9 @@ if options_.occbin.smoother.linear_smoother && nargin==12
oo_.occbin.linear_smoother.T0=T0;
oo_.occbin.linear_smoother.R0=R0;
oo_.occbin.linear_smoother.decomp=decomp;
oo_.occbin.linear_smoother.alphahat0=alphahat0;
oo_.occbin.linear_smoother.state_uncertainty0=state_uncertainty0;
fprintf('\nOccbin: linear smoother done.\n')
options_.occbin.smoother.status=true;
end
@ -115,10 +119,43 @@ opts_simul.piecewise_only = options_.occbin.smoother.piecewise_only;
occbin_options = struct();
occbin_options.first_period_occbin_update = options_.occbin.smoother.first_period_occbin_update;
occbin_options.opts_regime = opts_simul; % this builds the opts_simul options field needed by occbin.solver
occbin_options.opts_regime.binding_indicator = options_.occbin.likelihood.init_binding_indicator;
occbin_options.opts_regime.regime_history=options_.occbin.likelihood.init_regime_history;
[alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,oo_,bayestopt_,alphahat0,state_uncertainty0, diffuse_steps] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,occbin_options);% T1=TT;
occbin_options.opts_simul = opts_simul; % this builds the opts_simul options field needed by occbin.solver
occbin_options.opts_regime.binding_indicator = options_.occbin.smoother.init_binding_indicator;
occbin_options.opts_regime.regime_history=options_.occbin.smoother.init_regime_history;
error_indicator=false;
try
%blanket try-catch should be replaced be proper error handling, see https://git.dynare.org/Dynare/dynare/-/merge_requests/2226#note_20318
[alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,oo_,bayestopt_,alphahat0,state_uncertainty0] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,occbin_options);% T1=TT;
catch ME
error_indicator=true;
disp(ME.message)
for iter = 1:numel(ME.stack)
ME.stack(iter)
end
end
if error_indicator || isempty(alphahat0)
etahat= oo_.occbin.linear_smoother.etahat;
alphahat0= oo_.occbin.linear_smoother.alphahat0;
base_regime = struct();
if M_.occbin.constraint_nbr==1
base_regime.regime = 0;
base_regime.regimestart = 1;
else
base_regime.regime1 = 0;
base_regime.regimestart1 = 1;
base_regime.regime2 = 0;
base_regime.regimestart2 = 1;
end
oo_.occbin.smoother.regime_history = [];
for jper=1:size(alphahat,2)+1
if jper == 1
oo_.occbin.smoother.regime_history = base_regime;
else
oo_.occbin.smoother.regime_history(jper) = base_regime;
end
end
end
oo_.occbin.smoother.realtime_regime_history = oo_.occbin.smoother.regime_history;
regime_history = oo_.occbin.smoother.regime_history;
@ -139,6 +176,7 @@ opts_simul.SHOCKS = [etahat(:,1:end)'; zeros(1,M_.exo_nbr)];
opts_simul.exo_pos = 1:M_.exo_nbr;
opts_simul.endo_init = alphahat0(oo_.dr.inv_order_var,1);
opts_simul.init_regime=regime_history; % use realtime regime for guess, to avoid multiple solution issues!
opts_simul.periods = size(opts_simul.SHOCKS,1);
options_.occbin.simul=opts_simul;
options_.noprint = true;
[~, out, ss] = occbin.solver(M_,options_,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
@ -261,13 +299,13 @@ while is_changed && maxiter>iter && ~is_periodic
eee(:,k) = eig(TT(:,:,k));
end
if options_.debug
err_eig(iter-1) = max(max(abs(sort(eee)-sort(sto_eee))));
err_alphahat(iter-1) = max(max(max(abs(alphahat-sto_alphahat))));
err_etahat(iter-1) = max(max(max(abs(etahat-sto_etahat{iter-1}))));
err_CC(iter-1) = max(max(max(abs(CC-sto_CC))));
err_RR(iter-1) = max(max(max(abs(RR-sto_RR))));
err_TT(iter-1) = max(max(max(abs(TT-sto_TT))));
end
err_eig(iter-1) = max(max(abs(sort(eee)-sort(sto_eee))));
err_alphahat(iter-1) = max(max(max(abs(alphahat-sto_alphahat))));
err_etahat(iter-1) = max(max(max(abs(etahat-sto_etahat{iter-1}))));
err_CC(iter-1) = max(max(max(abs(CC-sto_CC))));
err_RR(iter-1) = max(max(max(abs(RR-sto_RR))));
err_TT(iter-1) = max(max(max(abs(TT-sto_TT))));
end
end
if occbin_smoother_debug || is_periodic
@ -391,6 +429,10 @@ if (~is_changed || occbin_smoother_debug) && nargin==12
oo_.occbin.smoother.T0=TT;
oo_.occbin.smoother.R0=RR;
oo_.occbin.smoother.C0=CC;
oo_.occbin.smoother.simul.piecewise = out.piecewise(1:end-1,:);
if ~options_.occbin.simul.piecewise_only
oo_.occbin.smoother.simul.linear = out.linear(1:end-1,:);
end
if options_.occbin.smoother.plot
GraphDirectoryName = CheckPath('graphs',M_.fname);
latexFolder = CheckPath('latex',M_.dname);
@ -404,7 +446,7 @@ if (~is_changed || occbin_smoother_debug) && nargin==12
j1=0;
ifig=0;
for j=1:M_.exo_nbr
if M_.Sigma_e(j,j)
if max(abs(oo_.occbin.smoother.etahat(j,:)))>1.e-8
j1=j1+1;
if mod(j1,9)==1
hh_fig = dyn_figure(options_.nodisplay,'name','Occbin smoothed shocks');
@ -441,15 +483,15 @@ if (~is_changed || occbin_smoother_debug) && nargin==12
fprintf(fidTeX,'\\label{Fig:smoothedshocks_occbin:%s}\n',int2str(ifig));
fprintf(fidTeX,'\\end{figure}\n');
fprintf(fidTeX,' \n');
end
end
end
end
end
if mod(j1,9)~=0 && j==M_.exo_nbr
annotation('textbox', [0.1,0,0.35,0.05],'String', 'Linear','Color','Blue','horizontalalignment','center','interpreter','none');
annotation('textbox', [0.55,0,0.35,0.05],'String', 'Piecewise','Color','Red','horizontalalignment','center','interpreter','none');
dyn_saveas(hh_fig,[GraphDirectoryName filesep M_.fname,'_smoothedshocks_occbin',int2str(ifig)],options_.nodisplay,options_.graph_format);
if mod(j1,9)~=0 && j==M_.exo_nbr
annotation('textbox', [0.1,0,0.35,0.05],'String', 'Linear','Color','Blue','horizontalalignment','center','interpreter','none');
annotation('textbox', [0.55,0,0.35,0.05],'String', 'Piecewise','Color','Red','horizontalalignment','center','interpreter','none');
dyn_saveas(hh_fig,[GraphDirectoryName filesep M_.fname,'_smoothedshocks_occbin',int2str(ifig)],options_.nodisplay,options_.graph_format);
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
% TeX eps loader file
fprintf(fidTeX,'\\begin{figure}[H]\n');
@ -463,6 +505,6 @@ if (~is_changed || occbin_smoother_debug) && nargin==12
end
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
fclose(fidTeX);
end
end
end
end

View File

@ -71,7 +71,7 @@ end
if ~isempty(xparam1)
M_ = set_all_parameters(xparam1,estim_params_,M_);
[fval,info,exit_flag,Q,H]=check_bounds_and_definiteness_estimation(xparam1, M_, estim_params_, BoundsInfo);
[fval,info,exit_flag]=check_bounds_and_definiteness_estimation(xparam1, M_, estim_params_, BoundsInfo);
if info(1)
return
end
@ -81,7 +81,7 @@ err_index=options_.occbin.likelihood.IVF_shock_observable_mapping; % err_index=
COVMAT1 = M_.Sigma_e(err_index,err_index);
% Linearize the model around the deterministic steady state and extract the matrices of the state equation (T and R).
[T,R,SteadyState,info,dr, M_.params] = dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,'restrict');
[~,~,SteadyState,info,dr, M_.params] = dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,'restrict');
% Return, with endogenous penalty when possible, if dynare_resolve issues an error code (defined in resol).
if info(1)
@ -195,4 +195,4 @@ end
% remember that the likelihood has already been multiplied by -1
% hence, posterior is -1 times the log of the prior
fval = like+prior;
fval = like+prior;

View File

@ -0,0 +1,87 @@
function [binding_indicator, A, regime_string] = backward_map_regime(regime, regime_start)
% [binding_indicator, A, regime_string] = backward_map_regime(regime, regime_start)
% Map regime information into regime indicator
%
% Inputs:
% - regime [integer] [1 by n_transitions] vector of regime number indices
% - regime_start [integer] [1 by n_transitions] vectors with period numbers in which regime starts
%
% Outputs:
% - binding_indicator [integer] [nperiods by 1] vector of regime indices
% - A [bin] binary representation of binding indicator
% - error_flag [boolean] 1 if regime never leaves 1 or is still there at the end of nperiods
% 0 otherwise
% Copyright © 2023 Dynare Team
%
% 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
if nargin ==1
% polymorphism
if ~isstruct(regime)
disp('error::backward_map_regime')
disp('input arguments may be 1 structure with regime info')
disp('or two arrays: regime and regimestart ')
error('wrong input')
end
fnam = fieldnames(regime);
if length(fnam) == 2
[binding_indicator, A, regime_string] = occbin.backward_map_regime(regime.regime, regime.regimestart);
else
for k=1:2
nperiods(k) = regime.(['regimestart' int2str(k)])(end);
number_of_binary_tokens(k) = ceil((nperiods(k)-1)/50);
end
binding_indicator = false(max(nperiods),2);
A = int64(zeros(max(number_of_binary_tokens),2));
for k=1:2
[binding_indicator(1:nperiods(k),k), A(1:number_of_binary_tokens(k),k), tmp{k}] = ...
occbin.backward_map_regime(regime.(['regime' int2str(k)]), regime.(['regimestart' int2str(k)]));
end
regime_string = char(tmp{1},tmp{2});
end
return
else
if isstruct(regime)
disp('error::backward_map_regime')
disp('input arguments may be ONE structure with regime info')
disp('or TWO arrays: regime and regimestart ')
error('wrong input')
end
end
regime_string = char(mat2str(double(regime)),mat2str(regime_start));
nperiods_0 = regime_start(end);
number_of_binary_tokens = max(1,ceil((nperiods_0-1)/50));
A = int64(zeros(number_of_binary_tokens,1));
binding_indicator = false(nperiods_0,1);
if length(regime)>1
for ir=1:length(regime)-1
binding_indicator(regime_start(ir):regime_start(ir+1)-1,1) = regime(ir);
for k=regime_start(ir):regime_start(ir+1)-1
this_token = ceil(k/50);
A(this_token) = int64(bitset(A(this_token),k-50*(this_token-1),regime(ir)));
end
end
end
binding_indicator = logical(binding_indicator);
% to convert regime in a readable string array
% a = dec2bin(A);
% bindicator = [a(end:-1:1) '0'];

View File

@ -0,0 +1,50 @@
function [cost, out] = cost_function(err_0, current_obs, weights, opts_simul,...
M_, dr,endo_steady_state,exo_steady_state,exo_det_steady_state, options_)
% [cost, out] = cost_function(err_0, current_obs, opts_simul,...
% M_, dr,endo_steady_state,exo_steady_state,exo_det_steady_state, options_)
% Outputs:
% - cost [double] penalty
% - out [structure] Occbin's results structure
%
% Inputs
% - err_0 [double] value of shocks
% - current_obs [double] [1 by n_obs] current value of observables
% - weights [double] [1 by n_obs] variance of observables,
% - opts_simul [structure] Structure with simulation options
% used in cost function
% - M_ [structure] Matlab's structure describing the model (M_).
% - dr_ [structure] model information structure
% - endo_steady_state [vector] steady state value for endogenous variables
% - exo_steady_state [vector] steady state value for exogenous variables
% - exo_det_steady_state [vector] steady state value for exogenous deterministic variables
% - options_ [structure] Matlab's structure describing the current options (options_).
% Copyright © 2023 Dynare Team
%
% 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
opts_simul.SHOCKS = err_0';
options_.occbin.simul=opts_simul;
options_.occbin.simul.full_output=1;
options_.noprint = 1;
[~, out] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
cost = 0;
if ~out.error_flag
cost = mean((out.piecewise(1,opts_simul.varobs_id)'-current_obs').^2./weights);
else
cost = cost+1.e10;
end

63
matlab/+occbin/findmin.m Normal file
View File

@ -0,0 +1,63 @@
function [y, out, cost] = findmin(d_index, a0, P1, Qt, Y, ZZ, opts_simul,M_, dr,endo_steady_state,exo_steady_state,exo_det_steady_state, options_)
% [y, out, cost] = findmin(d_index, a0, P1, Qt, Y, ZZ, opts_simul,M_, dr,endo_steady_state,exo_steady_state,exo_det_steady_state, options_)
% Outputs:
% - cost [double] penalty
% - out [structure] Occbin's results structure
%
% Inputs
% - opts_simul [structure] Structure with simulation options
% used in cost function
% - M_ [structure] Matlab's structure describing the model (M_).
% - dr_ [structure] model information structure
% - endo_steady_state [vector] steady state value for endogenous variables
% - exo_steady_state [vector] steady state value for exogenous variables
% - exo_det_steady_state [vector] steady state value for exogenous deterministic variables
% - options_ [structure] Matlab's structure describing the current options (options_).
% Copyright © 2023 Dynare Team
%
% 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
current_obs = Y(d_index,2)'+dr.ys(options_.varobs_id(d_index))';
err_index = find(diag(Qt(:,:,2))~=0);
F = ZZ(d_index,:)*P1(:,:,2)*ZZ(d_index,:)' ;
weights=diag(F);
filtered_errs_init = zeros(1,length(err_index));
opts_simul.varobs_id=options_.varobs_id(d_index)';
opts_simul.exo_pos=err_index; %err_index is predefined mapping from observables to shocks
opts_simul.SHOCKS = filtered_errs_init;
if opts_simul.restrict_state_space
tmp=zeros(M_.endo_nbr,1);
tmp(dr.restrict_var_list,1)=a0(:,1); %updated state
opts_simul.endo_init = tmp(dr.inv_order_var,1);
else
opts_simul.endo_init = a0(dr.inv_order_var,1);
end
[y] = fminsearch(@cost_function,filtered_errs_init');
[cost, out] = occbin.cost_function(y, current_obs, weights, opts_simul,...
M_, dr,endo_steady_state,exo_steady_state,exo_det_steady_state, options_);
function cost = cost_function(x)
cost = occbin.cost_function(x, current_obs, weights, opts_simul,...
M_, dr,endo_steady_state,exo_steady_state,exo_det_steady_state, options_);
end
end

View File

@ -28,7 +28,7 @@ if opts.replic
effective_exo_nbr= length(ishock);
effective_exo_names = M_.exo_names(ishock);
effective_Sigma_e = M_.Sigma_e(ishock,ishock);
[U,S,V] = svd(effective_Sigma_e);
[U,S] = svd(effective_Sigma_e);
if opts.qmc
opts.replic =2^(round(log2(opts.replic+1)))-1;
SHOCKS_ant = qmc_sequence(forecast*effective_exo_nbr, int64(1), 1, opts.replic)';
@ -88,7 +88,7 @@ if opts.replic
for i=1:M_.endo_nbr
for j=1:forecast
[post_mean(j,1), post_median(j,1), post_var(j,1), hpd_interval(j,:), post_deciles(j,:)] = posterior_moments(squeeze(zlin0(j,i,:)),1,options_.forecasts.conf_sig);
[post_mean(j,1), post_median(j,1), post_var(j,1), hpd_interval(j,:), post_deciles(j,:)] = posterior_moments(squeeze(zlin0(j,i,:)),options_.forecasts.conf_sig);
end
oo_.occbin.linear_forecast.Mean.(M_.endo_names{i})=post_mean;
oo_.occbin.linear_forecast.Median.(M_.endo_names{i})=post_median;
@ -99,7 +99,7 @@ if opts.replic
oo_.occbin.linear_forecast.Min.(M_.endo_names{i})=zlinmin(:,i);
oo_.occbin.linear_forecast.Max.(M_.endo_names{i})=zlinmax(:,i);
for j=1:forecast
[post_mean(j,1), post_median(j,1), post_var(j,1), hpd_interval(j,:), post_deciles(j,:)] = posterior_moments(squeeze(zpiece0(j,i,:)),1,options_.forecasts.conf_sig);
[post_mean(j,1), post_median(j,1), post_var(j,1), hpd_interval(j,:), post_deciles(j,:)] = posterior_moments(squeeze(zpiece0(j,i,:)),options_.forecasts.conf_sig);
end
oo_.occbin.forecast.Mean.(M_.endo_names{i})=post_mean;
oo_.occbin.forecast.Median.(M_.endo_names{i})=post_median;

View File

@ -109,7 +109,7 @@ for fig = 1:nbplt
if ndim==2
legend([h1,h2],legend_list,'box','off')
else
legend([h1],legend_list,'box','off')
legend(h1,legend_list,'box','off')
end
end
if options_.TeX

View File

@ -1,4 +1,4 @@
function [a, a1, P, P1, v, T, R, C, regimes_, error_flag, M_, lik, etahat] = kalman_update_algo_1(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,options_,occbin_options)
function [a, a1, P, P1, v, T, R, C, regimes_, error_flag, M_, lik, etahat, alphahat, V] = kalman_update_algo_1(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,options_,occbin_options)
% function [a, a1, P, P1, v, T, R, C, regimes_, error_flag, M_, lik, etahat] = kalman_update_algo_1(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,options_,occbin_options)
% INPUTS
% - a [N by 1] t-1's state estimate
@ -86,6 +86,8 @@ else
base_regime.regimestart2 = 1;
end
regimes_ = [base_regime base_regime base_regime];
opts_simul = occbin_options.opts_simul;
options_.occbin.simul=opts_simul;
mm=size(a,1);
%% store info in t=1
@ -103,16 +105,46 @@ PZI = P1(:,:,t)*ZZ'*iF(di,di,t);
% L(:,:,t) = T-K(:,di,t)*ZZ;
L(:,:,t) = eye(mm)-PZI*ZZ;
if ~options_.occbin.filter.use_relaxation
[a, a1, P, P1, v, alphahat, etahat, lik, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
if ~isempty(fieldnames(regimes0))
if options_.occbin.filter.guess_regime
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state, regimes0(1),'reduced_state_space',T0,R0);
if M_.occbin.constraint_nbr==1
bindx = occbin.backward_map_regime(regimes0(1).regime, regimes0(1).regimestart);
bindx = bindx(2:end);
[regimes0(2).regime, regimes0(2).regimestart, error_flag]=occbin.map_regime(bindx);
bindx = bindx(2:end);
[regimes0(3).regime, regimes0(3).regimestart, error_flag]=occbin.map_regime(bindx);
else
bindx1 = occbin.backward_map_regime(regimes0(1).regime1, regimes0(1).regimestart1);
bindx2 = occbin.backward_map_regime(regimes0(1).regime2, regimes0(1).regimestart2);
bindx1 = bindx1(2:end);
bindx2 = bindx2(2:end);
[regimes0(2).regime1, regimes0(2).regimestart1, error_flag]=occbin.map_regime(bindx1);
[regimes0(2).regime2, regimes0(2).regimestart2, error_flag]=occbin.map_regime(bindx2);
bindx1 = bindx1(2:end);
bindx2 = bindx2(2:end);
[regimes0(3).regime1, regimes0(3).regimestart1, error_flag]=occbin.map_regime(bindx1);
[regimes0(3).regime2, regimes0(3).regimestart2, error_flag]=occbin.map_regime(bindx2);
end
% regimes0=[regimes0 base_regime base_regime];
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
end
[a, a1, P, P1, v, alphahat, etahat, lik, V, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance);
else
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state, base_regime,'reduced_state_space',T0,R0);
regimes0(1)=base_regime;
if isempty(fieldnames(regimes0))
regimes0 = regimes_;
else
regimes0(1)=base_regime;
end
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
[a, a1, P, P1, v, alphahat, etahat, lik, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
[a, a1, P, P1, v, alphahat, etahat, lik, V, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance);
end
if error_flag
etahat=NaN(size(QQQ,1),1);
@ -120,7 +152,6 @@ if error_flag
end
%% run here the occbin simul
opts_simul = occbin_options.opts_simul;
opts_simul.SHOCKS = zeros(3,M_.exo_nbr);
opts_simul.exo_pos=1:M_.exo_nbr;
opts_simul.SHOCKS(1,:) = etahat(:,2)';
@ -134,14 +165,24 @@ else
my_order_var = dr.order_var;
end
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
if options_.occbin.filter.guess_regime
options_.occbin.simul.init_regime=regimes0;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
end
else
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
options_.occbin.simul.init_regime=regimes0;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
end
end
if out.error_flag
error_flag = out.error_flag;
etahat=etahat(:,2);
lik=inf;
return;
end
@ -159,53 +200,18 @@ end
lik_hist=lik;
niter=1;
is_periodic=0;
if options_.occbin.filter.use_relaxation || isequal(regimes0(1),base_regime)
nguess=1;
else
nguess=0;
end
newguess=0;
if any(myregime) || ~isequal(regimes_(1),regimes0(1))
while ~isequal(regimes_(1),regimes0(1)) && ~is_periodic && ~out.error_flag && niter<=options_.occbin.likelihood.max_number_of_iterations
niter=niter+1;
oldstart=1;
if M_.occbin.constraint_nbr==1 && length(regimes0(1).regimestart)>1
oldstart = regimes0(1).regimestart(end);
end
newstart=1;
if M_.occbin.constraint_nbr==1 && length(regimes_(1).regimestart)>1
newstart = regimes_(1).regimestart(end);
end
if M_.occbin.constraint_nbr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
regimestart = max(oldstart+2,round(0.5*(newstart+oldstart)));
regimestart = min(regimestart,oldstart+4);
if regimestart<=regimes_(1).regimestart(end-1)
if length(regimes_(1).regimestart)<=3
regimestart = max(regimestart, min(regimes_(1).regimestart(end-1)+2,newstart));
else
regimes_(1).regime = regimes_(1).regime(1:end-2);
regimes_(1).regimestart = regimes_(1).regimestart(1:end-2);
regimestart = max(regimestart, regimes_(1).regimestart(end-1)+1);
end
end
regimes_(1).regimestart(end)=regimestart;
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state, [base_regime regimes_(1)],'reduced_state_space', T0, R0);
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
elseif newguess==0
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
RR(:,:,2)=ss.R(my_order_var,:,1);
CC(:,2)=ss.C(my_order_var,1);
end
newguess=0;
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
RR(:,:,2)=ss.R(my_order_var,:,1);
CC(:,2)=ss.C(my_order_var,1);
regime_hist(niter) = {regimes_(1)};
if M_.occbin.constraint_nbr==1
regime_end(niter) = regimes_(1).regimestart(end);
end
[a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
[a, a1, P, P1, v, alphahat, etahat, lik, V] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance);
etahat_hist(niter) = {etahat};
lik_hist(niter) = lik;
opts_simul.SHOCKS(1,:) = etahat(:,2)';
@ -216,9 +222,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
else
opts_simul.endo_init = alphahat(dr.inv_order_var,1);
end
if not(options_.occbin.filter.use_relaxation)
opts_simul.init_regime=regimes_(1);
end
opts_simul.init_regime=regimes_(1);
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
@ -227,9 +231,14 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
options_.occbin.simul.init_regime=[];
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
end
if out.error_flag
error_flag = out.error_flag;
etahat=etahat(:,2);
lik=inf;
return;
end
regimes0=regimes_;
@ -238,36 +247,14 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
for kiter=1:niter-1
is_periodic(kiter) = isequal(regime_hist{kiter}, regimes_(1));
end
is_periodic_iter = find(is_periodic);
is_periodic = any(is_periodic);
if is_periodic
if nguess<3 && M_.occbin.constraint_nbr==1
newguess=1;
is_periodic=0;
nguess=nguess+1;
if nguess==1
% change starting regime
regimes_(1).regime=0;
regimes_(1).regimestart=1;
elseif nguess==2
% change starting regime
regimes_(1).regime=[0 1 0];
regimes_(1).regimestart=[1 2 3];
else
regimes_(1).regime=[1 0];
regimes_(1).regimestart=[1 2];
end
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state, [base_regime regimes_(1)],'reduced_state_space',T0,R0);
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
regime_hist = regime_hist(1);
niter=1;
else
% re-set to previous regime
regimes_ = regimes0;
% force projection conditional on previous regime
opts_simul.init_regime=regimes0(1);
% re-set to previous regime
if options_.occbin.filter.periodic_solution
% force projection conditional on most likely regime
[m, im]=min(lik_hist(is_periodic_iter:end));
opts_simul.init_regime=regime_hist{is_periodic_iter+im-1};
if M_.occbin.constraint_nbr==1
myregimestart = [regimes0.regimestart];
else
@ -280,8 +267,20 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
if out.error_flag
error_flag = out.error_flag;
etahat=etahat(:,2);
lik=inf;
return;
else
regimes_ = out.regime_history;
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
RR(:,:,2)=ss.R(my_order_var,:,1);
CC(:,2)=ss.C(my_order_var,1);
[a, a1, P, P1, v, alphahat, etahat, lik, V] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood, options_.occbin.filter.state_covariance);
end
else
error_flag = 330;
etahat=etahat(:,2);
lik=inf;
return;
end
end
end
@ -291,62 +290,6 @@ end
error_flag = out.error_flag;
if ~error_flag && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1))
error_flag = 1;
if M_.occbin.constraint_nbr==1 % try some other regime
[ll, il]=sort(lik_hist);
[ll, il]=sort(regime_end);
rr=regime_hist(il(2:3));
newstart=1;
if length(rr{1}.regimestart)>1
newstart = rr{1}.regimestart(end)-rr{1}.regimestart(end-1)+1;
end
oldstart=1;
if length(rr{2}.regimestart)>1
oldstart = rr{2}.regimestart(end)-rr{2}.regimestart(end-1)+1;
end
nstart=sort([newstart oldstart]);
regimes_=rr{1}(1);
for k=(nstart(1)+1):(nstart(2)-1)
niter=niter+1;
regimes_(1).regimestart(end)=k;
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state, [base_regime regimes_(1)],'reduced_state_space',T0,R0);
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
[a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
etahat_hist(niter) = {etahat};
lik_hist(niter) = lik;
regime_hist(niter) = {regimes_(1)};
opts_simul.SHOCKS(1,:) = etahat(:,2)';
if opts_simul.restrict_state_space
tmp=zeros(M_.endo_nbr,1);
tmp(dr.restrict_var_list,1)=alphahat(:,1);
opts_simul.endo_init = tmp(dr.inv_order_var,1);
else
opts_simul.endo_init = alphahat(dr.inv_order_var,1);
end
% opts_simul.init_regime=regimes_(1);
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
end
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
error_flag = out.error_flag;
etahat=etahat(:,2);
return;
end
if isequal(out.regime_history(1),regimes_(1))
error_flag=0;
break
end
end
regimes_ = out.regime_history;
end
end
if ~error_flag
@ -359,17 +302,26 @@ C = ss.C(my_order_var,1:2);
QQ = R(:,:,2)*QQQ(:,:,3)*transpose(R(:,:,2));
P(:,:,1) = P(:,:,2);
P(:,:,2) = T(:,:,2)*P(:,:,1)*transpose(T(:,:,2))+QQ;
etahat=etahat(:,2);
if nargout>=13
etahat=etahat(:,2);
end
warning_config;
end
function [a, a1, P, P1, v, alphahat, etahat, lik, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, rescale_prediction_error_covariance, IF_likelihood)
function [a, a1, P, P1, v, alphahat, etahat, lik, V, error_flag] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, rescale_prediction_error_covariance, IF_likelihood, state_uncertainty_flag)
alphahat=NaN(size(a));
etahat=NaN(size(QQQ,1),2);
lik=Inf;
error_flag=0;
if state_uncertainty_flag
V = zeros(mm,mm,2);
N = zeros(mm,mm,3);
else
V=[];
end
warning off
if nargin<18
IF_likelihood=0;
@ -445,9 +397,15 @@ while t > 1
if isempty(di)
% in this case, L is simply T due to Z=0, so that DK (2012), eq. 4.93 obtains
r(:,t) = L(:,:,t)'*r(:,t+1); %compute r_{t-1}, DK (2012), eq. 4.38 with Z=0
if state_uncertainty_flag
N(:,:,t)=L(:,:,t)'*N(:,:,t+1)*L(:,:,t); %compute N_{t-1}, DK (2012), eq. 4.42 with Z=0
end
else
ZZ = Z(di,:);
r(:,t) = ZZ'*iF(di,di,t)*v(di,t) + L(:,:,t)'*r(:,t+1); %compute r_{t-1}, DK (2012), eq. 4.38
if state_uncertainty_flag
N(:,:,t)=ZZ'*iF(di,di,t)*ZZ+L(:,:,t)'*N(:,:,t+1)*L(:,:,t); %compute N_{t-1}, DK (2012), eq. 4.42
end
end
Q=QQQ(:,:,t);
QRt = Q*transpose(RR(:,:,t));
@ -455,6 +413,10 @@ while t > 1
alphahat(:,t) = a1(:,t) + P1(:,:,t)*r(:,t); %DK (2012), eq. 4.35
etahat(:,t) = QRt*r(:,t); %DK (2012), eq. 4.63
r(:,t) = T'*r(:,t); % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
if state_uncertainty_flag
V(:,:,t) = P1(:,:,t)-P1(:,:,t)*N(:,:,t)*P1(:,:,t); %DK (2012), eq. 4.43
N(:,:,t) = T'*N(:,:,t)*T; %DK (2012), eq. 4.43
end
if IF_likelihood && t==2 && not(isempty(di))
ishocks = any(ZZ*RR(:,:,t));

View File

@ -1,4 +1,4 @@
function [a, a1, P, P1, v, Fi, Ki, T, R, C, regimes_, error_flag, M_, alphahat, etahat, TT, RR, CC] = kalman_update_algo_3(a,a1,P,P1,data_index,Z,v,Fi,Ki,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,options_,occbin_options,kalman_tol,nk)
function [a, a1, P, P1, v, Fi, Ki, T, R, C, regimes_, error_flag, M_, lik, alphahat, etahat, TT, RR, CC] = kalman_update_algo_3(a,a1,P,P1,data_index,Z,v,Fi,Ki,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,options_,occbin_options,kalman_tol,nk)
% function [a, a1, P, P1, v, Fi, Ki, T, R, C, regimes_, error_flag, M_, alphahat, etahat, TT, RR, CC] = kalman_update_algo_3(a,a1,P,P1,data_index,Z,v,Fi,Ki,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,options_,occbin_options,kalman_tol,nk)
%
% INPUTS
@ -85,7 +85,8 @@ if isempty(nk)
end
nk=max(nk,1);
opts_simul = occbin_options.opts_regime;
opts_simul = occbin_options.opts_simul;
options_.occbin.simul=opts_simul;
base_regime = struct();
if M_.occbin.constraint_nbr==1
base_regime.regime = 0;
@ -96,6 +97,7 @@ else
base_regime.regime2 = 0;
base_regime.regimestart2 = 1;
end
regimes_ = [base_regime base_regime base_regime];
myrestrict=[];
if options_.smoother_redux
opts_simul.restrict_state_space =1;
@ -103,15 +105,46 @@ if options_.smoother_redux
end
mm=size(a,1);
if ~options_.occbin.filter.use_relaxation
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
if ~isempty(fieldnames(regimes0))
if options_.occbin.filter.guess_regime
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state, regimes0(1),myrestrict,T0,R0);
if M_.occbin.constraint_nbr==1
bindx = occbin.backward_map_regime(regimes0(1).regime, regimes0(1).regimestart);
bindx = bindx(2:end);
[regimes0(2).regime, regimes0(2).regimestart, error_flag]=occbin.map_regime(bindx);
bindx = bindx(2:end);
[regimes0(3).regime, regimes0(3).regimestart, error_flag]=occbin.map_regime(bindx);
else
bindx1 = occbin.backward_map_regime(regimes0(1).regime1, regimes0(1).regimestart1);
bindx2 = occbin.backward_map_regime(regimes0(1).regime2, regimes0(1).regimestart2);
bindx1 = bindx1(2:end);
bindx2 = bindx2(2:end);
[regimes0(2).regime1, regimes0(2).regimestart1, error_flag]=occbin.map_regime(bindx1);
[regimes0(2).regime2, regimes0(2).regimestart2, error_flag]=occbin.map_regime(bindx2);
bindx1 = bindx1(2:end);
bindx2 = bindx2(2:end);
[regimes0(3).regime1, regimes0(3).regimestart1, error_flag]=occbin.map_regime(bindx1);
[regimes0(3).regime2, regimes0(3).regimestart2, error_flag]=occbin.map_regime(bindx2);
end
% regimes0=[regimes0 base_regime base_regime];
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
end
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat, lik] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
else
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state, base_regime,myrestrict,T0,R0);
if isempty(fieldnames(regimes0))
regimes0 = regimes_;
else
regimes0(1)=base_regime;
end
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat, lik] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
regimes0(1)=base_regime;
end
@ -132,9 +165,23 @@ else
end
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if options_.occbin.filter.guess_regime
options_.occbin.simul.init_regime=regimes0;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
end
else
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
options_.occbin.simul.init_regime=regimes0;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
end
end
if out.error_flag
error_flag = out.error_flag;
etahat=etahat(:,2);
return;
end
@ -148,65 +195,23 @@ regime_hist = {regimes0(1)};
if M_.occbin.constraint_nbr==1
regime_end = regimes0(1).regimestart(end);
end
lik_hist=lik;
niter=1;
is_periodic=0;
if options_.occbin.filter.use_relaxation || isequal(regimes0(1),base_regime)
nguess=1;
else
nguess=0;
end
newguess=0;
if any(myregime) || ~isequal(regimes_(1),regimes0(1))
while ~isequal(regimes_(1),regimes0(1)) && ~is_periodic && ~out.error_flag && niter<=options_.occbin.likelihood.max_number_of_iterations
niter=niter+1;
newstart=1;
if M_.occbin.constraint_nbr==1 && length(regimes_(1).regimestart)>1
newstart = regimes_(1).regimestart(end);
end
oldstart=1;
if M_.occbin.constraint_nbr==1 && length(regimes0(1).regimestart)>1
oldstart = regimes0(1).regimestart(end);
end
if M_.occbin.constraint_nbr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
regimestart = max(oldstart+2,round(0.5*(newstart+oldstart)));
regimestart = min(regimestart,oldstart+4);
if regimestart<=regimes_(1).regimestart(end-1)
if length(regimes_(1).regimestart)<=3
regimestart = max(regimestart, min(regimes_(1).regimestart(end-1)+2,newstart));
else
regimes_(1).regime = regimes_(1).regime(1:end-2);
regimes_(1).regimestart = regimes_(1).regimestart(1:end-2);
regimestart = max(regimestart, regimes_(1).regimestart(end-1)+1);
end
end
% % if (newstart-oldstart)>3
% % regimestart = regimes_(1).regimestart(end-1)+oldstart+2;
% % % regimestart = regimes_(1).regimestart(end-1)+round(0.5*(newstart+oldstart))-1;
regimes_(1).regimestart(end)=regimestart;
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state, [base_regime regimes_(1)],myrestrict,T0,R0);
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
elseif newguess==0
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
RR(:,:,2)=ss.R(my_order_var,:,1);
CC(:,2)=ss.C(my_order_var,1);
end
newguess=0;
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
RR(:,:,2)=ss.R(my_order_var,:,1);
CC(:,2)=ss.C(my_order_var,1);
regime_hist(niter) = {regimes_(1)};
if M_.occbin.constraint_nbr==1
regime_end(niter) = regimes_(1).regimestart(end);
end
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat, lik] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
lik_hist(niter) = lik;
opts_simul.SHOCKS(1,:) = etahat(:,2)';
% if opts_simul.restrict_state_space
% tmp=zeros(M_.endo_nbr,1);
% tmp(dr.restrict_var_list,1)=alphahat(:,1);
% opts_simul.endo_init = tmp(dr.inv_order_var,1);
% else
if opts_simul.restrict_state_space
tmp=zeros(M_.endo_nbr,1);
tmp(dr.restrict_var_list,1)=alphahat(:,1);
@ -214,10 +219,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
else
opts_simul.endo_init = alphahat(dr.inv_order_var,1);
end
% end
if not(options_.occbin.filter.use_relaxation)
opts_simul.init_regime=regimes_(1);
end
opts_simul.init_regime=regimes_(1);
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
@ -228,6 +230,8 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if out.error_flag
error_flag = out.error_flag;
etahat=etahat(:,2);
lik=inf;
return;
end
regimes0=regimes_;
@ -236,36 +240,14 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
for kiter=1:niter-1
is_periodic(kiter) = isequal(regime_hist{kiter}, regimes_(1));
end
is_periodic_iter = find(is_periodic);
is_periodic = any(is_periodic);
if is_periodic
if nguess<3 && M_.occbin.constraint_nbr==1
newguess=1;
is_periodic=0;
nguess=nguess+1;
if nguess==1
% change starting regime
regimes_(1).regime=0;
regimes_(1).regimestart=1;
elseif nguess==2
% change starting regime
regimes_(1).regime=[0 1 0];
regimes_(1).regimestart=[1 2 3];
else
regimes_(1).regime=[1 0];
regimes_(1).regimestart=[1 2];
end
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state, [base_regime regimes_(1)],myrestrict,T0,R0);
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
regime_hist = regime_hist(1);
niter=1;
else
% re-set to previous regime
regimes_ = regimes0;
% force projection conditional on previous regime
opts_simul.init_regime=regimes0(1);
if options_.occbin.filter.periodic_solution
% force projection conditional on most likely regime
[m, im]=min(lik_hist(is_periodic_iter:end));
opts_simul.init_regime=regime_hist{is_periodic_iter+im-1};
if M_.occbin.constraint_nbr==1
myregimestart = [regimes0.regimestart];
else
@ -274,68 +256,39 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
opts_simul.maxit=1;
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
end
[~, out, ss] = occbin.solver(M_,oo_,options_);
if out.error_flag
error_flag = out.error_flag;
etahat=etahat(:,2);
lik=inf;
return;
else
regimes_ = out.regime_history;
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
RR(:,:,2)=ss.R(my_order_var,:,1);
CC(:,2)=ss.C(my_order_var,1);
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat, lik] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
end
else
error_flag = 330;
etahat=etahat(:,2);
lik=inf;
return;
end
end
end
end
end
error_flag = out.error_flag;
if error_flag==0 && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1)) %fixed point algorithm did not converge
if ~error_flag && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1)) %fixed point algorithm did not converge
error_flag = 1;
if M_.occbin.constraint_nbr==1
% try some other regime before giving up
[ll, il]=sort(regime_end);
rr=regime_hist(il(2:3));
newstart=1;
if length(rr{1}(1).regimestart)>1
newstart = rr{1}(1).regimestart(end)-rr{1}(1).regimestart(end-1)+1;
end
oldstart=1;
if length(rr{2}(1).regimestart)>1
oldstart = rr{2}(1).regimestart(end)-rr{2}(1).regimestart(end-1)+1;
end
nstart=sort([newstart oldstart]);
regimes_=rr{1}(1);
for k=(nstart(1)+1):(nstart(2)-1)
niter=niter+1;
regimes_(1).regimestart(end)=k;
[~,~,~,~,~,~, TTx, RRx, CCx] ...
= occbin.dynare_resolve(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state, [base_regime regimes_(1)],myrestrict,T0,R0);
TT(:,:,2) = TTx(:,:,end);
RR(:,:,2) = RRx(:,:,end);
CC(:,2) = CCx(:,end);
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
opts_simul.SHOCKS(1,:) = etahat(:,2)';
if opts_simul.restrict_state_space
tmp=zeros(M_.endo_nbr,1);
tmp(dr.restrict_var_list,1)=alphahat(:,1);
opts_simul.endo_init = tmp(dr.inv_order_var,1);
else
opts_simul.endo_init = alphahat(dr.inv_order_var,1);
end
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
end
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,options_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state);
if isequal(out.regime_history(1),regimes_(1))
error_flag=0;
break
end
end
regimes_ = out.regime_history;
end
end
regimes_=regimes_(1:3);
a = out.piecewise(1:nk+1,my_order_var)' - repmat(out.ys(my_order_var),1,nk+1);
if ~error_flag
a = out.piecewise(1:nk+1,my_order_var)' - repmat(out.ys(my_order_var),1,nk+1);
regimes_=regimes_(1:3);
end
T = ss.T(my_order_var,my_order_var,:);
R = ss.R(my_order_var,:,:);
C = ss.C(my_order_var,:);
@ -352,7 +305,7 @@ end
end
function [a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol)
function [a, a1, P, P1, v, Fi, Ki, alphahat, etahat, lik] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol)
% [a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol)
% - a
% - a1
@ -377,9 +330,18 @@ a(:,t) = a1(:,t);
P1(:,:,t) = T*P(:,:,t-1)*T' + QQ; %transition according to (6.14) in DK (2012)
P(:,:,t) = P1(:,:,t);
di = data_index{t}';
% store info for lik
if not(isempty(di))
vv = Y(di,t) - Z(di,:)*a(:,t);
F = Z(di,:)*P(:,:,t)*Z(di,:)' + diag(H(di));
sig=sqrt(diag(F));
lik=inf;
end
if isempty(di)
Fi(:,t) = 0;
Ki(:,:,t) = 0;
lik =0;
end
for i=di
Zi = Z(i,:);
@ -394,6 +356,11 @@ for i=di
% p. 157, DK (2012)
end
end
if not(isempty(di))
log_dF = log(det(F./(sig*sig')))+2*sum(log(sig));
iF = inv(F./(sig*sig'))./(sig*sig');
lik = log_dF + transpose(vv)*iF*vv + length(di)*log(2*pi);
end
%% do backward pass
ri=zeros(mm,1);
@ -416,4 +383,4 @@ while t > 1
ri = T'*ri; % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
end
end
end

View File

@ -0,0 +1,331 @@
function [ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regx, info, M_, likx, etahat, alphahat, V, Fix, Kix, TTx,RRx,CCx] = ...
kalman_update_engine(a0,a1,P0,P1,t,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,regimes_,base_regime,d_index,M_,...
dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options, Fi,Ki,kalman_tol,nk)
% [ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regx, info, M_, likx, etahat, alphahat, V, Fix, Kix, TTx,RRx,CCx] = kalman_update_engine(
% a0,a1,P0,P1,t,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,regimes_,base_regime,d_index,M_,
% dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options, Fi,Ki,kalman_tol,nk)
% Copyright © 2023 Dynare Team
%
% 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
is_multivariate = true;
Fix=[];
Kix=[];
TTx=[];
RRx=[];
CCx=[];
V=[];
if nargin>26
is_multivariate = false;
end
use_relaxation = false;
if is_multivariate
[ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regx, info, M_, likx, etahat, alphahat, V] = occbin.kalman_update_algo_1(a0,a1,P0,P1,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,struct(),M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options);
else
[ax, a1x, Px, P1x, vx, Fix, Kix, Tx, Rx, Cx, regx, info, M_, likx, alphahat, etahat,TTx,RRx,CCx] = occbin.kalman_update_algo_3(a0,a1,P0,P1,data_index,Z,vv,Fi,Ki,Y,H,Qt,T0,R0,TT,RR,CC,struct(),M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options,kalman_tol,nk);
end
info0=info;
if info
if ~isequal(regimes_(1:2),[base_regime base_regime])
if is_multivariate
[ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regx, info, M_, likx, etahat, alphahat, V] = occbin.kalman_update_algo_1(a0,a1,P0,P1,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,regimes_(1:2),M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options);
else
[ax, a1x, Px, P1x, vx, Fix, Kix, Tx, Rx, Cx, regx, info, M_, likx, alphahat, etahat,TTx,RRx,CCx] = occbin.kalman_update_algo_3(a0,a1,P0,P1,data_index,Z,vv,Fi,Ki,Y,H,Qt,T0,R0,TT,RR,CC,regimes_(1:2),M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options,kalman_tol,nk);
end
end
info1=info;
else
if ~isequal(regimes_(1:2),[base_regime base_regime])
if is_multivariate
[ax1, a1x1, Px1, P1x1, vx1, Tx1, Rx1, Cx1, regx1, info1, M_1, likx1, etahat1, alphahat1, V1] = occbin.kalman_update_algo_1(a0,a1,P0,P1,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,regimes_(1:2),M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options);
else
[ax1, a1x1, Px1, P1x1, vx1, Fix1, Kix1, Tx1, Rx1, Cx1, regx1, info1, M_1, likx1, alphahat1, etahat1,TTx1,RRx1,CCx1] = occbin.kalman_update_algo_3(a0,a1,P0,P1,data_index,Z,vv,Fi,Ki,Y,H,Qt,T0,R0,TT,RR,CC,regimes_(1:2),M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options,kalman_tol,nk);
end
if info1==0 && likx1<likx
ax=ax1;
a1x=a1x1;
Px=Px1;
P1x=P1x1;
vx=vx1;
Tx=Tx1;
Rx=Rx1;
Cx=Cx1;
regx=regx1;
info=info1;
M_= M_1;
likx=likx1;
etahat=etahat1;
alphahat=alphahat1;
if is_multivariate
V=V1;
else
Fix = Fix1;
Kix = Kix1;
TTx = TTx1;
RRx = RRx1;
CCx = CCx1;
end
end
else
if t>options_.occbin.likelihood.number_of_initial_periods_with_extra_regime_guess
info1=0;
else
% may help in first 2 periods to try some other guess regime, due to
% larger state uncertainty
info1=1;
options_.occbin.likelihood.brute_force_regime_guess = true;
options_.occbin.likelihood.loss_function_regime_guess = true;
end
end
end
diffstart=0;
if info==0
if M_.occbin.constraint_nbr==1
oldstart = regimes_(1).regimestart(end);
newstart = regx(1).regimestart(end);
diffstart = newstart-oldstart;
else
newstart1 = regx(1).regimestart1(end);
newstart2 = regx(1).regimestart2(end);
oldstart1 = regimes_(1).regimestart1(end);
oldstart2 = regimes_(1).regimestart2(end);
diffstart = max(newstart1-oldstart1,newstart2-oldstart2);
end
end
if options_.occbin.filter.use_relaxation && diffstart>2
if info0==0
% make sure we match criteria to enter further solution attempts
info1=1;
end
options_.occbin.likelihood.brute_force_regime_guess = true;
options_.occbin.likelihood.loss_function_regime_guess = true;
use_relaxation = true;
end
if options_.occbin.likelihood.brute_force_regime_guess && (info0 || info1) %|| (info==0 && ~isequal(regx(1),base_regime))
guess_regime = [base_regime base_regime];
options_.occbin.filter.guess_regime = true;
use_index = 0;
if M_.occbin.constraint_nbr==1
for k=1:5
guess_regime(1).regimestart=[1 5 5+4*k];
guess_regime(1).regime=[0 1 0];
if is_multivariate
[ax2{1}, a1x2{1}, Px2{1}, P1x2{1}, vx2{1}, Tx2{1}, Rx2{1}, Cx2{1}, regx2{1}, info2, M_2{1}, likx2{1}, etahat2{1}, alphahat2{1}, V2{1}] = occbin.kalman_update_algo_1(a0,a1,P0,P1,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options);
else
[ax2{1}, a1x2{1}, Px2{1}, P1x2{1}, vx2{1}, Fix2{1}, Kix2{1}, Tx2{1}, Rx2{1}, Cx2{1}, regx2{1}, info2, M_2{1}, likx2{1}, alphahat2{1}, etahat2{1},TTx2{1},RRx2{1},CCx2{1}] = occbin.kalman_update_algo_3(a0,a1,P0,P1,data_index,Z,vv,Fi,Ki,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options,kalman_tol,nk);
end
if info2==0
use_index= 1;
if not(info==0 && isequal(regx2{1},regx)) && not(use_relaxation && likx2{1}>=likx)
% found a solution, different from previous or
% use_relaxation and likelihood is better
break
end
end
guess_regime(1).regimestart=[1 1+4*k];
guess_regime(1).regime=[1 0];
if is_multivariate
[ax2{2}, a1x2{2}, Px2{2}, P1x2{2}, vx2{2}, Tx2{2}, Rx2{2}, Cx2{2}, regx2{2}, info2, M_2{2}, likx2{2}, etahat2{2}, alphahat2{2}, V2{2}] = occbin.kalman_update_algo_1(a0,a1,P0,P1,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options);
else
[ax2{2}, a1x2{2}, Px2{2}, P1x2{2}, vx2{2}, Fix2{2}, Kix2{2}, Tx2{2}, Rx2{2}, Cx2{2}, regx2{2}, info2, M_2{2}, likx2{2}, alphahat2{2}, etahat2{2},TTx2{2},RRx2{2},CCx2{2}] = occbin.kalman_update_algo_3(a0,a1,P0,P1,data_index,Z,vv,Fi,Ki,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options,kalman_tol,nk);
end
if info2==0
use_index = 2;
% if use_relaxation and we are here, previous guess did not
% improve solution, so we test for this one
end
if use_index
% in case the second guess does not find a solution!
info2=0;
% a solution was found
break
end
end
end
if M_.occbin.constraint_nbr==2
for jk=0:1 % loop over other regime duration. this loop is shorter for parsimony. one may add an option ...
for k=1:5 % loop over current regime duration
gindex = 0;
for jr=1:2 % loop over current regime 1 or 2
if jr==1
regstart1 = 'regimestart1';
reg1 = 'regime1';
regstart2 = 'regimestart2';
reg2 = 'regime2';
else
regstart1 = 'regimestart2';
reg1 = 'regime2';
regstart2 = 'regimestart1';
reg2 = 'regime1';
end
for kk=1:2 % loop over current regime binding in expectation vs binding in current period
if kk==1
guess_regime(1).(regstart1)=[1 5 5+4*k];
guess_regime(1).(reg1)=[0 1 0];
else
guess_regime(1).(regstart1)=[1 1+4*k];
guess_regime(1).(reg1)=[1 0];
end
for kj=1:1+1*(jk>0)
% loop over other regime slack or binding in current period or binding in
% expectation
if jk==0
% other regime is slack
guess_regime(1).(regstart2) = 1;
guess_regime(1).(reg2) = 0;
else % jk>0
if kj==1
% other regime binding in current period
guess_regime(1).(regstart2)=[1 1+4*jk];
guess_regime(1).(reg2) = [1 0];
else
% other regime binding in expectation
guess_regime(1).(regstart2)=[1 5 5+4*jk];
guess_regime(1).(reg2) = [0 1 0];
end
end
gindex = gindex+1;
if is_multivariate
[ax2{gindex}, a1x2{gindex}, Px2{gindex}, P1x2{gindex}, vx2{gindex}, Tx2{gindex}, Rx2{gindex}, Cx2{gindex}, regx2{gindex}, info2, M_2{gindex}, likx2{gindex}, etahat2{gindex}, alphahat2{gindex}, V2{gindex}] = occbin.kalman_update_algo_1(a0,a1,P0,P1,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options);
else
[ax2{gindex}, a1x2{gindex}, Px2{gindex}, P1x2{gindex}, vx2{gindex}, Fix2{gindex}, Kix2{gindex}, Tx2{gindex}, Rx2{gindex}, Cx2{gindex}, regx2{gindex}, info2, M_2{gindex}, likx2{gindex}, alphahat2{gindex}, etahat2{gindex},TTx2{gindex},RRx2{gindex},CCx2{gindex}] = occbin.kalman_update_algo_3(a0,a1,P0,P1,data_index,Z,vv,Fi,Ki,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options,kalman_tol,nk);
end
if info2==0
use_index= gindex;
if not(info==0 && isequal(regx2{gindex},regx)) && not(use_relaxation && likx2{gindex}>=likx)
% found a solution, different from previous one
% use_relaxation and likelihood improves
break
end
end
end % loop over other regime slack, binding in expectation or binding in current period
if info2==0
if not(info==0 && isequal(regx2{gindex},regx)) && not(use_relaxation && likx2{gindex}>=likx)
% found a solution, different from previous one
% use_relaxation and likelihood improves
break
end
end
end % loop over current regime binding in expectation vs binding in current period
if info2==0
if not(info==0 && isequal(regx2{gindex},regx)) && not(use_relaxation && likx2{gindex}>=likx)
% found a solution, different from previous one
% use_relaxation and likelihood improves
break
end
end
end % loop over current regime 1 or 2
if use_index
info2=0;
break
end
end % loop over current regime duration
if use_index
break
end
end % loop over other regime duration
end % 2 constraints
if info2==0
% so that we DO NOT enter IVF step
info0=0;
info1=0;
end
if info2==0 && likx2{use_index}<likx
ax=ax2{use_index};
a1x=a1x2{use_index};
Px=Px2{use_index};
P1x=P1x2{use_index};
vx=vx2{use_index};
Tx=Tx2{use_index};
Rx=Rx2{use_index};
Cx=Cx2{use_index};
regx=regx2{use_index};
info=info2;
M_= M_2{use_index};
likx=likx2{use_index};
etahat=etahat2{use_index};
alphahat=alphahat2{use_index};
if is_multivariate
V=V2{use_index};
else
Fix = Fix2{use_index};
Kix = Kix2{use_index};
TTx = TTx2{use_index};
RRx = RRx2{use_index};
CCx = CCx2{use_index};
end
end
options_.occbin.filter.guess_regime = false;
end
if options_.occbin.likelihood.loss_function_regime_guess && (info0 || info1) %|| (info==0 && ~isequal(regx(1),base_regime))
[~, out] = occbin.findmin(d_index, a0, P1, Qt, Y, Z, occbin_options.opts_simul,M_, dr,endo_steady_state,exo_steady_state,exo_det_steady_state, options_);
if out.error_flag==0
options_.occbin.filter.guess_regime = true;
guess_regime=out.regime_history;
guess_regime = [guess_regime base_regime];
if is_multivariate
[ax2, a1x2, Px2, P1x2, vx2, Tx2, Rx2, Cx2, regx2, info2, M_2, likx2, etahat2, alphahat2, V2] = occbin.kalman_update_algo_1(a0,a1,P0,P1,data_index,Z,vv,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options);
else
[ax2, a1x2, Px2, P1x2, vx2, Fix2, Kix2, Tx2, Rx2, Cx2, regx2, info2, M_2, likx2, alphahat2, etahat2,TTx2,RRx2,CCx2] = occbin.kalman_update_algo_3(a0,a1,P0,P1,data_index,Z,vv,Fi,Ki,Y,H,Qt,T0,R0,TT,RR,CC,guess_regime,M_,dr,endo_steady_state,exo_steady_state,exo_det_steady_state,options_,occbin_options,kalman_tol,nk);
end
options_.occbin.filter.guess_regime = false;
if info2==0 && likx2<likx
ax=ax2;
a1x=a1x2;
Px=Px2;
P1x=P1x2;
vx=vx2;
Tx=Tx2;
Rx=Rx2;
Cx=Cx2;
regx=regx2;
info=info2;
likx=likx2;
M_= M_2;
etahat=etahat2;
alphahat=alphahat2;
if is_multivariate
V=V2;
else
Fix = Fix2;
Kix = Kix2;
TTx = TTx2;
RRx = RRx2;
CCx = CCx2;
end
end
end
end
end

View File

@ -26,6 +26,9 @@ function [regime, regime_start, error_flag]=map_regime(binding_indicator,debug_s
% Journal of Monetary Economics 70, 22-38
error_flag=0;
if isempty(binding_indicator)
binding_indicator = false;
end
% analyse violvec and isolate contiguous periods in the other regime.
regime(1) = binding_indicator(1);
regime_index = 1;

View File

@ -42,6 +42,9 @@ if ismember(flag,{'all'})
end
if ismember(flag,{'filter','all'})
options_occbin_.filter.state_covariance = false;
options_occbin_.filter.guess_regime = false;
options_occbin_.filter.periodic_solution = true;
options_occbin_.filter.use_relaxation = false;
end
@ -69,6 +72,7 @@ if ismember(flag,{'irf','all'})
end
if ismember(flag,{'likelihood','all'})
options_occbin_.likelihood.brute_force_regime_guess = true;
options_occbin_.likelihood.curb_retrench = false;
options_occbin_.likelihood.first_period_occbin_update = 1;
options_occbin_.likelihood.full_output = false;
@ -77,10 +81,12 @@ if ismember(flag,{'likelihood','all'})
options_occbin_.likelihood.init_binding_indicator = false(0);
options_occbin_.likelihood.inversion_filter = false;
options_occbin_.likelihood.IVF_shock_observable_mapping = [];
options_occbin_.likelihood.loss_function_regime_guess = false;
options_occbin_.likelihood.maxit = 30; % this is for occbin solver algo
options_occbin_.likelihood.max_number_of_iterations = 10; % this is for occbin_kalman_update loop
options_occbin_.likelihood.max_check_ahead_periods=inf;
options_occbin_.likelihood.periods = 100;
options_occbin_.likelihood.number_of_initial_periods_with_extra_regime_guess=0;
options_occbin_.likelihood.periods = 3;
options_occbin_.likelihood.check_ahead_periods=200;
options_occbin_.likelihood.periodic_solution=false;
options_occbin_.likelihood.piecewise_only = true;
@ -193,6 +199,8 @@ if ismember(flag,{'simul','all'})
options_occbin_.simul.periods=100;
options_occbin_.simul.check_ahead_periods=200;
options_occbin_.simul.periodic_solution=false;
options_occbin_.simul.periodic_solution_threshold=1;
options_occbin_.simul.periodic_solution_strict=true;
options_occbin_.simul.piecewise_only = false;
options_occbin_.simul.reset_check_ahead_periods_in_new_period = false;
options_occbin_.simul.reset_regime_in_new_period = false;
@ -215,7 +223,7 @@ if ismember(flag,{'smoother','all'})
options_occbin_.smoother.maxit = 30; % this is for occbin solver algo
options_occbin_.smoother.max_check_ahead_periods=inf;
options_occbin_.smoother.max_number_of_iterations = 10; % this is for smoother loop
options_occbin_.smoother.periods = 100;
options_occbin_.smoother.periods = 3;
options_occbin_.smoother.check_ahead_periods=200;
options_occbin_.smoother.periodic_solution=false;
options_occbin_.smoother.piecewise_only = true;

View File

@ -136,6 +136,8 @@ for shock_period = 1:n_shocks_periods
binding_indicator_history={};
max_err = NaN(max_iter,1);
regime_violates_constraint_in_expectation = false(max_iter,1);
number_of_periods_with_violations = zeros(max_iter,1);
regime_exit_period = ones(max_iter,1);
while (regime_change_this_iteration && iter<max_iter && ~is_periodic && ~is_periodic_loop)
iter = iter +1;
@ -194,9 +196,11 @@ for shock_period = 1:n_shocks_periods
if ~isinf(opts_simul_.max_check_ahead_periods) && opts_simul_.max_check_ahead_periods<length(binding_indicator)
end_periods = opts_simul_.max_check_ahead_periods;
last_indicator = false(length(binding_indicator)-end_periods,1);
regime_violates_constraint_in_last_period(iter) = any(binding.constraint_1(end_periods+1:end));
else
end_periods = length(binding_indicator);
last_indicator = false(0);
regime_violates_constraint_in_last_period(iter) = binding.constraint_1(end_periods);
end
% check if changes to the hypothesis of the duration for each
% regime
@ -215,6 +219,9 @@ for shock_period = 1:n_shocks_periods
% if max_check_ahead_periods<inf, enforce unconstrained regime for period larger than max_check_ahead_periods
binding_constraint_new=[binding.constraint_1(1:end_periods);last_indicator];
relaxed_constraint_new = [relax.constraint_1(1:end_periods);not(last_indicator)];
number_of_periods_with_violations(iter) = sum(binding_indicator -((binding_indicator | binding_constraint_new) & ~(binding_indicator & relaxed_constraint_new)));
regime_exit_period(iter) = max(regime_history(shock_period).regimestart);
if curb_retrench % apply Gauss-Seidel idea of slowing down the change in the guess
% for the constraint -- only relax one
% period at a time starting from the last
@ -252,20 +259,35 @@ for shock_period = 1:n_shocks_periods
if size(binding_indicator,1)== size(binding_indicator_history{kiter},1)
% vvv = [binding_indicator_history{kiter}; false(size(binding_indicator,1)- size(binding_indicator_history{kiter},1), 1)];
% is_periodic(kiter) = isequal(vvv, binding_indicator);
is_periodic(kiter) = isequal(binding_indicator_history{kiter}, binding_indicator) && length(find(binding_indicator_history{iter}-binding_indicator))==1;
is_periodic(kiter) = isequal(binding_indicator_history{kiter}, binding_indicator) && sum(binding_indicator_history{iter}-binding_indicator)<=opts_simul_.periodic_solution_threshold;
else
is_periodic(kiter)=false;
end
end
is_periodic_all =is_periodic;
is_periodic = any(is_periodic);
is_periodic_strict = is_periodic;
if is_periodic_loop && ~is_periodic
if ~opts_simul_.periodic_solution_strict && any(number_of_periods_with_violations(~regime_violates_constraint_in_expectation(1:iter))<=opts_simul_.periodic_solution_threshold)
is_periodic=true;
is_periodic_all=false(size(is_periodic_loop_all));
is_periodic_all(1) = true; % here we consider all guesses and pick the best one according to the criteria below
else
do_nothing=true;
end
end
if is_periodic && periodic_solution
inx = find(is_periodic_all,1):iter;
inx1 = inx(find(~regime_violates_constraint_in_expectation(inx)));
if not(isempty(inx1))
inx=inx1;
end
[merr,imerr]=min(max_err(inx));
if is_periodic_strict || isempty(inx1)
[merr,imerr]=min(max_err(inx));
else
[merr,imerr]=min(number_of_periods_with_violations(inx));
end
inx = inx(imerr);
binding_indicator=binding_indicator_history{inx};
if inx<iter

View File

@ -228,7 +228,7 @@ for shock_period = 1:n_shocks_periods
err_binding_constraint_new = [err.binding_constraint_1(1:end_periods); err.binding_constraint_2(1:end_periods)];
err_relaxed_constraint_new = [err.relax_constraint_1(1:end_periods); err.relax_constraint_2(1:end_periods)];
% check if changes_
if any(binding_constraint_new & ~my_binding_indicator(:)) || any(relaxed_constraint_new & my_binding_indicator(:))
err_violation = err_binding_constraint_new(binding_constraint_new & ~my_binding_indicator(:));
@ -243,6 +243,11 @@ for shock_period = 1:n_shocks_periods
binding_constraint_new=[binding.constraint_1(1:end_periods);last_indicator; binding.constraint_2(1:end_periods);last_indicator];
relaxed_constraint_new = [relax.constraint_1(1:end_periods);not(last_indicator); relax.constraint_2(1:end_periods);not(last_indicator)];
tmp_nper(1) = sum(binding_indicator(:,1) - (binding_indicator(:,1) | [binding.constraint_1(1:end_periods);last_indicator]) & ~(binding_indicator(:,1) & [relax.constraint_1(1:end_periods);not(last_indicator)]));
tmp_nper(2) = sum(binding_indicator(:,2) - (binding_indicator(:,2) | [binding.constraint_2(1:end_periods);last_indicator]) & ~(binding_indicator(:,2) & [relax.constraint_2(1:end_periods);not(last_indicator)]));
number_of_periods_with_violations(iter) = max(tmp_nper);
regime_exit_period(iter,1) = max(regime_history(shock_period).regimestart1);
regime_exit_period(iter,2) = max(regime_history(shock_period).regimestart2);
if curb_retrench % apply Gauss-Seidel idea of slowing down the change in the guess
% for the constraint -- only relax one
% period at a time starting from the last
@ -276,7 +281,7 @@ for shock_period = 1:n_shocks_periods
is_periodic_loop(kiter) = false;
end
end
% is_periodic_loop_all =is_periodic_loop;
is_periodic_loop_all =is_periodic_loop;
is_periodic_loop = any(is_periodic_loop);
% only accept periodicity where regimes differ by one
% period!
@ -285,20 +290,35 @@ for shock_period = 1:n_shocks_periods
if size(binding_indicator,1)== size(binding_indicator_history{kiter},1)
% vvv = [binding_indicator_history{kiter}; false(size(binding_indicator,1)- size(binding_indicator_history{kiter},1), 1)];
% is_periodic(kiter) = isequal(vvv, binding_indicator);
is_periodic(kiter) = isequal(binding_indicator_history{kiter}, binding_indicator) && length(find(binding_indicator_history{iter}(:,1)-binding_indicator(:,1)))<=1 && length(find(binding_indicator_history{iter}(:,2)-binding_indicator(:,2)))<=1;
is_periodic(kiter) = isequal(binding_indicator_history{kiter}, binding_indicator) && sum(binding_indicator_history{iter}(:,1)-binding_indicator(:,1))<=opts_simul_.periodic_solution_threshold && sum(binding_indicator_history{iter}(:,2)-binding_indicator(:,2))<=opts_simul_.periodic_solution_threshold;
else
is_periodic(kiter)=false;
end
end
is_periodic_all = is_periodic;
is_periodic = any(is_periodic);
is_periodic_strict = is_periodic;
if is_periodic_loop && ~is_periodic
if ~opts_simul_.periodic_solution_strict && any(number_of_periods_with_violations(~regime_violates_constraint_in_expectation(1:iter))<opts_simul_.periodic_solution_threshold)
is_periodic=true;
is_periodic_all=false(size(is_periodic_loop_all));
is_periodic_all(1) = true; % here we consider all guesses and pick the best one according to the criteria below
else
do_nothing=true;
end
end
if is_periodic && periodic_solution
inx = find(is_periodic_all,1):iter;
inx1 = inx(find(~regime_violates_constraint_in_expectation(inx)));
if not(isempty(inx1))
inx=inx1;
end
[min_err,index_min_err]=min(max_err(inx));
if is_periodic_strict || isempty(inx1)
[min_err,index_min_err]=min(max_err(inx));
else
[min_err,index_min_err]=min(number_of_periods_with_violations(inx));
end
inx = inx(index_min_err);
binding_indicator=binding_indicator_history{inx}; %select regime history with same result, but smallest error
if inx<iter %update if needed

View File

@ -1,23 +1,26 @@
function [dr, out, ss] = solver(M_, options_, dr ,steady_state, exo_steady_state, exo_det_steady_state)
% function [oo_, out, ss] = solver(M_,oo_,options_, dr ,steady_state, exo_steady_state, exo_det_steady_state
% [dr, out, ss] = solver(M_,oo_,options_, dr ,steady_state, exo_steady_state, exo_det_steady_state
% Solves the model with an OBC and produces simulations/IRFs
%
% INPUT:
% - M_ [structure] Matlab's structure describing the model
% - oo_ [structure] Matlab's structure containing the results
% - options_ [structure] Matlab's structure containing the options
% - M_ [structure] Matlab's structure describing the model
% - options_ [structure] Matlab's structure containing the options
% - dr [structure] model information structure
% - endo_steady_state [vector] steady state value for endogenous variables
% - exo_steady_state [vector] steady state value for exogenous variables
% - exo_det_steady_state [vector] steady state value for exogenous deterministic variables
%
% OUTPUT:
% - oo_ [structure] Matlab's structure containing the results
% - out [structure] simulation result containing fields:
% - linear: paths for endogenous variables ignoring OBC (linear solution)
% - piecewise: paths for endogenous variables satisfying the OBC (occbin/piecewise solution)
% - ys: vector of steady state values
% - regime_history: information on number and time of regime transitions
% - ss [structure] State space solution
% - T: [n_vars by n_vars by n_shock_period] array of transition matrices
% - R: [n_vars by n_exo by n_shock_period] array of shock response matrices
% - C: [n_vars by n_shock_period] array of constants
% - dr [structure] decision rules
% - out [structure] simulation result containing fields:
% - linear: paths for endogenous variables ignoring OBC (linear solution)
% - piecewise: paths for endogenous variables satisfying the OBC (occbin/piecewise solution)
% - ys: vector of steady state values
% - regime_history: information on number and time of regime transitions
% - ss [structure] State space solution
% - T: [n_vars by n_vars by n_shock_period] array of transition matrices
% - R: [n_vars by n_exo by n_shock_period] array of shock response matrices
% - C: [n_vars by n_shock_period] array of constants
% Copyright © 2021-2023 Dynare Team
%
@ -50,6 +53,7 @@ else
end
end
ss=struct();
if solve_dr
if isempty(options_.qz_criterium)
options_.qz_criterium = 1+1e-6;

View File

@ -18,7 +18,7 @@ function [pacmodl, lhs, rhs, pnames, enames, xnames, rname, pid, eid, xid, pname
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% Get the original equation to be estimated
[LHS, RHS] = get_lhs_and_rhs(eqname, M_, true);
[~, RHS] = get_lhs_and_rhs(eqname, M_, true);
% Check that the equation has a PAC expectation term.
if ~contains(RHS, 'pac_expectation', 'IgnoreCase', true)

View File

@ -41,7 +41,7 @@ function iterative_ols(eqname, params, data, range)
global M_ oo_ options_
[pacmodl, ~, rhs, ~, ~, ~, rname, ~, ~, ~, ~, ipnames_, params, data, ~] = ...
[pacmodl, ~, rhs, ~, ~, ~, rname, ~, ~, ~, ~, ipnames_, params, data] = ...
pac.estimate.init(M_, oo_, eqname, params, data, range);
% Set initial condition.

View File

@ -200,23 +200,23 @@ if isnan(ssr0) || isinf(ssr0) || ~isreal(ssr0)
end
if is_gauss_newton
[params1, SSR, exitflag] = gauss_newton(resfun, params0);
[params1, SSR] = gauss_newton(resfun, params0);
elseif is_lsqnonlin
if ismember('levenberg-marquardt', varargin)
% Levenberg Marquardt does not handle boundary constraints.
[params1, SSR, ~, exitflag] = lsqnonlin(resfun, params0, [], [], optimset(varargin{:}));
[params1, SSR] = lsqnonlin(resfun, params0, [], [], optimset(varargin{:}));
else
[params1, SSR, ~, exitflag] = lsqnonlin(resfun, params0, bounds(:,1), bounds(:,2), optimset(varargin{:}));
[params1, SSR] = lsqnonlin(resfun, params0, bounds(:,1), bounds(:,2), optimset(varargin{:}));
end
else
% Estimate the parameters by minimizing the sum of squared residuals.
[params1, SSR, exitflag] = dynare_minimize_objective(ssrfun, params0, ...
minalgo, ...
options_, ...
bounds, ...
parameter_names, ...
[], ...
[]);
[params1, SSR] = dynare_minimize_objective(ssrfun, params0, ...
minalgo, ...
options_, ...
bounds, ...
parameter_names, ...
[], ...
[]);
end
% Revert local modifications to the options.

View File

@ -40,7 +40,7 @@ end
errorcode = 0;
% Get the original equation to be estimated
[LHS, RHS] = get_lhs_and_rhs(eqname, M_, true);
[~, RHS] = get_lhs_and_rhs(eqname, M_, true);
% Check that the equation has a PAC expectation term.
if ~contains(RHS, 'pac_expectation', 'IgnoreCase', true)

View File

@ -76,8 +76,8 @@ if odd
end
y = y*rho;
end
y = prod([1:2:s1])*prod([1:2:s2])*y;
y = prod(1:2:s1)*prod(1:2:s2)*y;
if nargout > 1
dy = prod([1:2:s1])*prod([1:2:s2])*dy;
dy = prod(1:2:s1)*prod(1:2:s2)*dy;
end

View File

@ -61,7 +61,7 @@ s2 = s/2;
% Use univariate normal results
%
if m==1
y = V^s2*prod([1:2:s-1]);
y = V^s2*prod(1:2:s-1);
return
end
%
@ -104,4 +104,4 @@ for i=1:fix(prod(nu+1)/2)
end
end
end
y = y/prod([1:s2]);
y = y/prod(1:s2);

View File

@ -82,9 +82,9 @@ s2 = s/2;
% Use univariate normal results
%
if m==1
y = V^s2*prod([1:2:s-1]);
y = V^s2*prod(1:2:s-1);
if nargout > 1
dy = s2*V^(s2-1)*dV*prod([1:2:s-1]);
dy = s2*V^(s2-1)*dV*prod(1:2:s-1);
dy = reshape(dy,1,size(dV,3));
end
return
@ -169,8 +169,8 @@ for i=1:fix(prod(nu+1)/2)
end
end
end
y = y/prod([1:s2]);
y = y/prod(1:s2);
if nargout > 1
dy = dy/prod([1:s2]);
dy = dy/prod(1:s2);
dy = reshape(dy,1,size(dV,3));
end

View File

@ -89,7 +89,7 @@ if leads ==0
end
%disp('gensysToAMA:running ama');
try % try to run AIM
[bb,rts,ia,nexact,nnumeric,lgroots,aimcode] =...
[bb,rts,~,~,~,~,aimcode] =...
SPAmalg(theAIM_H,neq, lags,leads,condn,uprbnd);
catch
err = lasterror;

View File

@ -1,20 +1,19 @@
function y0 = get_irf(exo,varargin)
% function x = get_irf(exoname, vname1, vname2, ...)
function y0 = get_irf(exoname,varargin)
% function x = get_irf(exoname, varargin)
% returns IRF to individual exogenous for a list of variables and adds the
% steady state
%
% INPUTS:
% exo: exo variable name
% exoname: exo variable name
% vname1, vname2, ... : list of variable names
%
% OUTPUTS
% x: irf matrix [time x number of variables]
% y0: irf matrix [time x number of variables]
%
% SPECIAL REQUIREMENTS
% none
% Copyright © 2019 Dynare Team
% Copyright © 2019-2023 Dynare Team
%
% This file is part of Dynare.
%
@ -33,14 +32,44 @@ function y0 = get_irf(exo,varargin)
global M_ oo_
ys_ = [oo_.steady_state];
y0=zeros(length(oo_.irfs.([varargin{1} '_' exo]))+1,length(varargin));
[i_var,nvar] = varlist_indices(varargin,M_.endo_names);
for j=1:nvar
% mfys = strmatch(varargin{j},lgy_,'exact');
y0(:,j)=[0; oo_.irfs.([ varargin{j} '_' exo ])']+ys_(i_var(j));
if isfield(oo_,'irfs')
irf_fields=fieldnames(oo_.irfs);
else
error('get_irf: No IRFs detected in oo_')
end
exo_matches=find(endsWith(irf_fields,['_' exoname]));
if isempty(exo_matches)
error('get_irf: No IRFs for shock %s detected in oo_',exoname)
else
if nargin>1
endo_cell={};
i_var=[];
for var_iter=1:length(varargin)
temp=startsWith(irf_fields(exo_matches),varargin{var_iter});
if isempty(temp)
fprintf('get_irf: No IRF for variable %s detected in oo_',varargin{var_iter})
else
endo_cell=[endo_cell,varargin{var_iter}];
i_var=[i_var,strmatch(varargin(var_iter),M_.endo_names,'exact')];
end
end
else
endo_cell={};
i_var=[];
for var_iter=1:length(exo_matches)
endo_cell=[endo_cell,irf_fields{var_iter}(1:end-length(exoname)-1)];
i_var=[i_var,strmatch(endo_cell(end),M_.endo_names,'exact')];
end
end
end
ys_ = [oo_.steady_state];
nvars=length(endo_cell);
y0=zeros(length(oo_.irfs.([ endo_cell{1} '_' exoname ]))+1,nvars);
for j=1:nvars
y0(:,j)=[0; oo_.irfs.([ endo_cell{j} '_' exoname ])']+ys_(i_var(j));
end

View File

@ -1,14 +1,15 @@
function y0 = get_mean(varargin)
% function x = get_mean(vname1, vname2, <order>)
% returns the steady-state of a variable identified by its name
% function y0 = get_mean(varargin)
% returns the mean of a variable identified by its name
%
% INPUTS:
% vname1, vname2, ... : list of variable names
% order: if integer 1 or 2, optionally last input can trigger the order
% at which steady state is computed
% vargargin inputs containing
% - vname1, vname2, ... : list of variable names
% - order: if integer 1 or 2, optionally last input can trigger the order
% at which steady state is computed
%
% OUTPUTS
% x: steady state values
% y0: mean values
%
% SPECIAL REQUIREMENTS
% none
@ -30,27 +31,6 @@ function y0 = get_mean(varargin)
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
global M_ oo_ options_
global M_ options_ oo_
if ~isempty(regexp(varargin{end},'\d','ONCE')) && isempty(regexp(varargin{end},'\D','ONCE'))
order=eval(varargin{end});
else
order=1;
end
if order==1
ys_ = oo_.steady_state;
ys_ = evaluate_steady_state(ys_,[oo_.exo_steady_state; oo_.exo_det_steady_state],M_,options_,true);
elseif order==2
ys_ = oo_.dr.ys;
ys_(oo_.dr.order_var)=ys_(oo_.dr.order_var)+oo_.dr.ghs2./2;
else
return
end
lgy_ = M_.endo_names;
mfys=nan(length(varargin),1);
for j=1:length(varargin)
mfys(j) = find(strcmp(varargin{j},lgy_));
end
y0 = ys_(mfys);
y0=get_mean_no_globals(M_, oo_, options_, varargin{:});

View File

@ -0,0 +1,76 @@
function y0 = get_mean_no_globals(M_, oo_, options_, varargin)
% function y0 = get_mean_no_globals(M_, oo_, options_, varargin)
% returns the mean of a variable identified by its name
%
% INPUTS:
% M_ [structure] describing the model
% oo_ [structure] storing the results
% options_ [structure] describing the options
% vargargin inputs containing
% - vname1, vname2, ... : list of variable names
% - order: if integer 1 or 2, optionally last input can trigger the order
% at which steady state is computed
%
% OUTPUTS
% y0: mean values
%
% SPECIAL REQUIREMENTS
% none
% Copyright © 2019-2023 Dynare Team
%
% 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
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
if ~isempty(regexp(varargin{end},'\d','ONCE')) && isempty(regexp(varargin{end},'\D','ONCE'))
order=eval(varargin{end});
nvars=length(varargin)-1;
else
order=1;
nvars=length(varargin);
end
if order==1
if isfield(oo_,'dr') && isfield(oo_.dr,'ys')
ys_=oo_.dr.ys;
else
ys_ = oo_.steady_state;
ys_ = evaluate_steady_state(ys_,[oo_.exo_steady_state; oo_.exo_det_steady_state],M_,options_,true);
end
elseif order==2
if isfield(oo_,'dr') && isfield(oo_.dr,'ys')
ys_=oo_.dr.ys;
if ~isfield(oo_.dr,'ghs2')
error('get_mean: ghs2 needs to be present in oo_ to compute mean at order=2')
else
ys_(oo_.dr.order_var)=ys_(oo_.dr.order_var)+oo_.dr.ghs2./2;
end
else
error('get_mean: decision rules need to be present in oo_ to compute mean')
end
else
error('get_mean: order>2 not implemented')
end
mfys=NaN(nvars,1);
for j=1:nvars
endo_index=find(strcmp(varargin{j},M_.endo_names));
if isempty(endo_index)
error('get_mean: unknown variables %s requested',varargin{j})
else
mfys(j) = find(strcmp(varargin{j},M_.endo_names));
end
end
y0 = ys_(mfys);

View File

@ -33,7 +33,7 @@ global M_
i = strmatch(pname,M_.param_names,'exact');
if isempty(i)
error(sprintf('Can''t find parameter %s', pname))
error('Can''t find parameter %s', pname)
end
x = M_.params(i);

View File

@ -84,7 +84,7 @@ for i=1:length(varargin)
end
% Ensure that the equation tag name matches the LHS variable.
eqtagname = regexp(model{j}, 'name=''(\w*)''', 'match');
[lhs, ~] = getequation(model{j+1});
lhs = getequation(model{j+1});
endovar = getendovar(lhs);
eqtagname_ = strcat('name=''', endovar{1}, '''');
if ~isempty(eqtagname)

View File

@ -31,7 +31,7 @@ global M_ options_ oo_
% Check that the model is actually backward
if M_.maximum_lead
error(['backward_model_forecast:: The specified model is not backward looking!'])
error('backward_model_forecast:: The specified model is not backward looking!')
end
% Initialize returned argument.
@ -63,7 +63,7 @@ for i=1:M_.exo_nbr
end
% Set up initial conditions
[initialcondition, periods, innovations, options_local, M_local, oo_local, endonames, exonames, dynamic_resid, dynamic_g1, y] = ...
[initialcondition, periods, innovations, options_local, M_local, oo_local, endonames, ~, dynamic_resid, dynamic_g1] = ...
simul_backward_model_init(initialcondition, periods, options_, M_, oo_, zeros(periods, M_.exo_nbr));
% Get vector of indices for the selected endogenous variables.
@ -110,9 +110,9 @@ if withuncertainty
for i=1:B
innovations = transpose(sigma*randn(M_.exo_nbr, periods));
if options_.linear
[ysim__, xsim__, errorflag] = simul_backward_linear_model_(initialcondition, periods, options_local, M_local, oo_local, innovations, dynamic_resid, dynamic_g1);
[ysim__, ~, errorflag] = simul_backward_linear_model_(initialcondition, periods, options_local, M_local, oo_local, innovations, dynamic_resid, dynamic_g1);
else
[ysim__, xsim__, errorflag] = simul_backward_nonlinear_model_(initialcondition, periods, options_local, M_local, oo_local, innovations, dynamic_resid, dynamic_g1);
[ysim__, ~, errorflag] = simul_backward_nonlinear_model_(initialcondition, periods, options_local, M_local, oo_local, innovations, dynamic_resid, dynamic_g1);
end
if errorflag
error('Simulation failed.')

View File

@ -139,7 +139,7 @@ if ~isempty(innovationbaseline)
end
% Set up initial conditions
[initialcondition, periods, Innovations, options_local, M_local, oo_local, endonames, exonames, dynamic_resid, dynamic_g1, y] = ...
[initialcondition, periods, Innovations, options_local, M_local, oo_local, endonames, exonames, dynamic_resid, dynamic_g1] = ...
simul_backward_model_init(initialcondition, periods, options_, M_, oo_, Innovations);
% Get the covariance matrix of the shocks.

View File

@ -57,7 +57,7 @@ if isempty(initialconditions)
vertcat(M_.endo_names(1:M_.orig_endo_nbr), M_.exo_names));
end
[initialconditions, info] = checkdatabase(initialconditions, M_, false, true);
initialconditions = checkdatabase(initialconditions, M_, false, true);
% Test if the first argument contains all the lagged endogenous variables
endonames = M_.endo_names;

View File

@ -143,7 +143,7 @@ for it = initialconditions.nobs+(1:samplesize)
%
% Evaluate and check the residuals
%
[r, J] = dynamic_backward_model_for_simulation(ytm, dynamic_resid, dynamic_g1, ytm, x, M_.params, oo_.steady_state, M_.dynamic_g1_sparse_rowval, M_.dynamic_g1_sparse_colval, M_.dynamic_g1_sparse_colptr);
r = dynamic_backward_model_for_simulation(ytm, dynamic_resid, dynamic_g1, ytm, x, M_.params, oo_.steady_state, M_.dynamic_g1_sparse_rowval, M_.dynamic_g1_sparse_colval, M_.dynamic_g1_sparse_colptr);
residuals_evaluating_to_nan = isnan(r);
residuals_evaluating_to_inf = isinf(r);
residuals_evaluating_to_complex = ~isreal(r);

View File

@ -72,7 +72,7 @@ elseif isempty(varlist) && ~isempty(options_.endo_vars_for_moment_computations_i
end
elseif isempty(varlist) && isempty(options_.endo_vars_for_moment_computations_in_estimation)
skipline()
disp(['You did not declare endogenous variables after the estimation/calib_smoother command.'])
disp('You did not declare endogenous variables after the estimation/calib_smoother command.')
cas = '';
if options_.bayesian_irf
cas = 'Posterior IRFs';

View File

@ -52,7 +52,7 @@ if writelistofroutinestobecleared
end
end
end
[~, list_of_functions, ~] = cellfun(@fileparts, list_of_files, 'UniformOutput',false);
[~, list_of_functions] = cellfun(@fileparts, list_of_files, 'UniformOutput',false);
cellofchar2mfile(sprintf('%slist_of_functions_to_be_cleared.m', DYNARE_FOLDER), list_of_functions)
end
return
@ -79,7 +79,7 @@ if isempty(ext)
fname = [pathstr, name, '.m'];
else
if ~isequal(ext, '.m')
error(['The first argument needs to be the name of a matlab script (with an .m extension)!'])
error('The first argument needs to be the name of a matlab script (with an .m extension)!')
end
end
@ -88,13 +88,13 @@ if ~iscell(c)
end
if ndims(c)>2
error(['The cell passed has a second argument cannot have more than two dimensions!'])
error('The cell passed has a second argument cannot have more than two dimensions!')
end
variablename = inputname(2);
if isempty(variablename) && nargin<3
error(['You must pass the name of the cell (second input argument) as a string in the third input argument!'])
error('You must pass the name of the cell (second input argument) as a string in the third input argument!')
end
if nargin>2

View File

@ -35,4 +35,4 @@ end
parameters = strrep(parameters, ' ', '_');
[oo_, M_, options_, bayestopt_, Smoothed_variables_declaration_order_deviation_form] = evaluate_smoother(parameters, varlist, M_, oo_, options_, bayestopt_, estim_params_);
[oo_, M_, options_, bayestopt_] = evaluate_smoother(parameters, varlist, M_, oo_, options_, bayestopt_, estim_params_);

View File

@ -61,7 +61,7 @@ if (size(estim_params_.var_endo,1) || size(estim_params_.corrn,1))
end
% Fill or update bayestopt_ structure
[xparam1, estim_params_, BayesOptions, lb, ub, M_local] = set_prior(estim_params_, M_, options_);
[~, estim_params_, ~, lb, ub, M_local] = set_prior(estim_params_, M_, options_);
% Set restricted state space
options_plot_priors_old=options_.plot_priors;
options_.plot_priors=0;

View File

@ -272,7 +272,7 @@ else
end
NamFileInput={[M_.dname '/metropolis/'],[ModelName '_mh*_blck*.mat']};
[fout, nBlockPerCPU, totCPU] = masterParallel(options_.parallel, 1, npar,NamFileInput,'mcmc_diagnostics_core', localVars, [], options_.parallel_info);
[fout, ~, totCPU] = masterParallel(options_.parallel, 1, npar,NamFileInput,'mcmc_diagnostics_core', localVars, [], options_.parallel_info);
UDIAG = fout(1).UDIAG;
for j=2:totCPU
UDIAG = cat(3,UDIAG ,fout(j).UDIAG);

View File

@ -81,7 +81,7 @@ UDIAG = zeros(NumberOfLines,6,npar-fpar+1);
if whoiam
waitbarString = ['Please wait... MCMC diagnostics (' int2str(fpar) 'of' int2str(npar) ')...'];
if Parallel(ThisMatlab).Local
waitbarTitle=['Local '];
waitbarTitle='Local ';
else
waitbarTitle=[Parallel(ThisMatlab).ComputerName];
end

View File

@ -93,7 +93,7 @@ for nv = 1:n_vars % big loop over variables
% Find thinning factor for which first-order Markov Chain is preferred to second-order one
while(bic > 0)
thinned_chain=work(1:k_thin_current_var:n_runs,1);
[g2, bic] = first_vs_second_order_MC_test(thinned_chain);
[~, bic] = first_vs_second_order_MC_test(thinned_chain);
k_thin_current_var = k_thin_current_var+1;
end
@ -108,11 +108,11 @@ for nv = 1:n_vars % big loop over variables
beta = transition_matrix(2,1)/(transition_matrix(2,1)+transition_matrix(2,2)); %prob of going from 2 to 1
kmind=k_thin_current_var;
[g2, bic]=independence_chain_test(thinned_chain);
[~, bic]=independence_chain_test(thinned_chain);
while(bic > 0)
thinned_chain=work(1:kmind:n_runs,1);
[g2, bic] = independence_chain_test(thinned_chain);
[~, bic] = independence_chain_test(thinned_chain);
kmind = kmind+1;
end

View File

@ -63,7 +63,7 @@ ivar=zeros(n, 1);
for i=1:n
i_tmp = strmatch(var_list{i}, M_.endo_names, 'exact');
if isempty(i_tmp)
error (['One of the specified variables does not exist']) ;
error ('One of the specified variables does not exist') ;
else
ivar(i) = i_tmp;
end

View File

@ -55,7 +55,6 @@ options_.solve_tolx = eps^(2/3);
options_.solve_randomize_initial_guess = true;
options_.trust_region_initial_step_bound_factor = 1;
options_.dr_display_tol=1e-6;
options_.minimal_workspace = false;
options_.dp.maxit = 3000;
options_.steady.maxit = 50;
options_.simul.maxit = 50;

View File

@ -49,7 +49,7 @@ else
end
params=M_.params;
[U,Uy,W] = feval([M_.fname,'.objective.static'],zeros(M_.endo_nbr,1),[], M_.params);
[~,Uy,W] = feval([M_.fname,'.objective.static'],zeros(M_.endo_nbr,1),[], M_.params);
if any(any(isnan(Uy)))
info = 64 ; %the derivatives of the objective function contain NaN
return;

View File

@ -47,7 +47,7 @@ else
end
if mu<lb
error(['The prior expectation (%f) %scannot be smaller than the lower bound of the Beta distribution (%f)!'], mu, name1, lb)
error('The prior expectation (%f) %scannot be smaller than the lower bound of the Beta distribution (%f)!', mu, name1, lb)
end
if mu>ub

View File

@ -121,7 +121,7 @@ if (distribution==3)% Inverted Gamma 1 distribution
nu = 2;
s = 3*(m*m);
else
[mu, parameters] = mode_and_variance_to_mean(m,s2,2);
[~, parameters] = mode_and_variance_to_mean(m,s2,2);
nu = sqrt(parameters(1));
nu2 = 2*nu;
nu1 = 2;

View File

@ -48,6 +48,6 @@ X = randn(v, m) * H_inv_upper_chol;
% G = inv(X'*X);
% Rather compute inv(X'*X) using the SVD
[U,S,V] = svd(X, 0);
[~,S,V] = svd(X, 0);
SSi = 1 ./ (diag(S) .^ 2);
G = (V .* repmat(SSi', m, 1)) * V';

View File

@ -56,7 +56,7 @@ eqn = @(k) gammaln(1+2./k) - 2*gammaln(1+1./k) - log(1+sigma2/mu2);
eqn2 = @(k) eqn(k).*eqn(k);
kstar = fminbnd(eqn2, 1e-9, 100);
[shape, fval, exitflag] = fzero(eqn, kstar);
[shape, ~, exitflag] = fzero(eqn, kstar);
if exitflag<1
shape = NaN;

1
matlab/dseries Submodule

@ -0,0 +1 @@
Subproject commit c799f003eb8d8ca51ef2926f1e9deec1f80cb5e2

View File

@ -36,9 +36,9 @@ if ~(nargin >= 3)
end
if options_.smpl == 0
k = [1:size(oo_.endo_simul,2)];
k = 1:size(oo_.endo_simul,2);
else
k = [M_.maximum_lag+options_.smpl(1):M_.maximum_lag+options_.smpl(2)];
k = M_.maximum_lag+options_.smpl(1):M_.maximum_lag+options_.smpl(2);
end
if nargin == 3

View File

@ -69,7 +69,7 @@ else
running_text = varargin{2};
end
if Parallel.Local
waitbarTitle=['Local '];
waitbarTitle='Local ';
else
waitbarTitle=[Parallel.ComputerName];
end

View File

@ -83,7 +83,7 @@ if isoctave
skipline()
elseif octave_ver_less_than('7.1.0') % Should match the test in meson.build, and also the one in matlab/modules/dseries/src/initialize_dseries_class.m
skipline()
warning(['This version of Dynare has only been tested on Octave 7.1.0 and above. Dynare may fail to run or give unexpected result. Consider upgrading your version of Octave.'])
warning('This version of Dynare has only been tested on Octave 7.1.0 and above. Dynare may fail to run or give unexpected result. Consider upgrading your version of Octave.')
skipline()
end
else
@ -240,7 +240,7 @@ end
% https://forum.dynare.org/t/issue-with-dynare-preprocessor-4-6-1/15448/1
if ~fast
if ispc && ~isoctave && exist(['+',fname(1:end-4)],'dir')
[~,~]=rmdir(['+', fname(1:end-4)],'s');
[~,~]=rmdir(['+', fname(1:end-4)],'s'); % output required to suppress triggering error
end
end

View File

@ -58,7 +58,7 @@ p = {'/../contrib/ms-sbvar/TZcode/MatlabFiles/' ; ...
'/kalman/likelihood' ; ...
'/latex/' ; ...
'/lmmcp/' ; ...
'/modules/dseries/src/' ; ...
'/dseries/src/' ; ...
'/reporting/' ; ...
'/matrix_solver/'; ...
'/moments/'; ...

View File

@ -51,7 +51,7 @@ if ~isempty(endo_prior_restrictions.irf)
end
varlist = M_.endo_names(dr.order_var);
if isempty(T)
[T,R,SteadyState,infox,dr, M_.params] = dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
[T,R,~,~,dr, M_.params] = dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
else % check if T and R are given in the restricted form!!!
if size(T,1)<length(varlist)
varlist = varlist(dr.restrict_var_list);
@ -65,7 +65,7 @@ if ~isempty(endo_prior_restrictions.irf)
end
if ~varlistok
varlist = M_.endo_names(dr.order_var);
[T,R,SteadyState,infox,dr, M_.params] = dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
[T,R,~,~,dr, M_.params] = dynare_resolve(M_,options_,dr, endo_steady_state, exo_steady_state, exo_det_steady_state);
end
end
NT=1;
@ -132,13 +132,13 @@ if ~isempty(endo_prior_restrictions.moment)
for i=1:nvar
i_tmp = strmatch(var_list_(i,:), M_.endo_names, 'exact');
if isempty(i_tmp)
error (['One of the variable specified does not exist'])
error ('One of the variable specified does not exist')
else
ivar(i) = i_tmp;
end
end
options_.ar = max(abs(NTmin),NTmax);
[gamma_y,stationary_vars] = th_autocovariances(dr, ivar, M_, options_,1);
gamma_y = th_autocovariances(dr, ivar, M_, options_,1);
for t=NTmin:NTmax
RR = gamma_y{abs(t)+1};
if t==0
@ -171,4 +171,4 @@ if ~isempty(endo_prior_restrictions.moment)
if any(info_moment)
info=[49, info(2) + sum(info_moment(:,2))];
end
end
end

View File

@ -20,14 +20,14 @@ function e = ep_accuracy_check(M_,options_,oo_)
endo_simul = oo_.endo_simul;
n = size(endo_simul,2);
[initialconditions, innovations, pfm, ep, verbosity, options_, oo_] = ...
[~, innovations, pfm, ~, ~, options_, oo_] = ...
extended_path_initialization([], n-1, [], options_, M_, oo_);
options_.ep.accuracy.stochastic.order = options_.ep.stochastic.order;
[nodes,weights,nnodes] = setup_integration_nodes(options_.ep.accuracy,pfm);
[nodes,weights] = setup_integration_nodes(options_.ep.accuracy,pfm);
e = zeros(M_.endo_nbr,n);
for i=1:n
e(:,i) = euler_equation_error(endo_simul(:,i),oo_.exo_simul, ...
innovations, M_, options_,oo_,pfm,nodes,weights);
end
end

View File

@ -20,31 +20,29 @@ function e = euler_equation_error(y0,x,innovations,M_,options_,oo_,pfm,nodes,wei
dynamic_model = str2func([M_.fname '.dynamic']);
ep = options_.ep;
[y1, info_convergence, endogenousvariablespaths] = extended_path_core(ep.periods, ...
M_.endo_nbr, M_.exo_nbr, ...
innovations.positive_var_indx, ...
x, ep.init, y0, oo_.steady_state, ...
0, ...
ep.stochastic.order, M_, ...
pfm, ep.stochastic.algo, ...
ep.solve_algo, ...
ep.stack_solve_algo, ...
options_.lmmcp, options_, oo_, ...
[]);
y1 = extended_path_core(ep.periods, ...
M_.endo_nbr, M_.exo_nbr, ...
innovations.positive_var_indx, ...
x, ep.init, y0, oo_.steady_state, ...
0, ...
ep.stochastic.order, M_, ...
pfm, ep.stochastic.algo, ...
ep.solve_algo, ...
ep.stack_solve_algo, ...
options_.lmmcp, options_, oo_, ...
[]);
i_pred = find(M_.lead_lag_incidence(1,:));
i_fwrd = find(M_.lead_lag_incidence(3,:));
x1 = [x(2:end,:); zeros(1,M_.exo_nbr)];
for i=1:length(nodes)
x2 = x1;
x2(2,:) = x2(2,:) + nodes(i,:);
[y2, info_convergence, endogenousvariablespaths] = ...
extended_path_core(ep.periods, M_.endo_nbr, M_.exo_nbr, ...
innovations.positive_var_indx, x2, ep.init, ...
y1, oo_.steady_state, 0, ...
ep.stochastic.order, M_, pfm, ep.stochastic.algo, ...
ep.solve_algo, ep.stack_solve_algo, options_.lmmcp, ...
options_, oo_, []);
y2 = extended_path_core(ep.periods, M_.endo_nbr, M_.exo_nbr, ...
innovations.positive_var_indx, x2, ep.init, ...
y1, oo_.steady_state, 0, ...
ep.stochastic.order, M_, pfm, ep.stochastic.algo, ...
ep.solve_algo, ep.stack_solve_algo, options_.lmmcp, ...
options_, oo_, []);
z = [y0(i_pred); y1; y2(i_fwrd)];
res(:,i) = dynamic_model(z,x,M_.params,oo_.steady_state,2);
end

View File

@ -1,5 +1,5 @@
function [ts, oo_] = extended_path(initialconditions, samplesize, exogenousvariables, options_, M_, oo_)
% [ts, oo_] = extended_path(initialconditions, samplesize, exogenousvariables, options_, M_, oo_)
function [ts,oo_] = extended_path(initialconditions, samplesize, exogenousvariables, options_, M_, oo_)
% [ts,oo_] = extended_path(initialconditions, samplesize, exogenousvariables, options_, M_, oo_)
% Stochastic simulation of a non linear DSGE model using the Extended Path method (Fair and Taylor 1983). A time
% series of size T is obtained by solving T perfect foresight models.
%
@ -13,7 +13,7 @@ function [ts, oo_] = extended_path(initialconditions, samplesize, exogenousvaria
%
% OUTPUTS
% o ts [dseries] m*samplesize array, the simulations.
% o results [cell]
% o results [struct] results structure
%
% ALGORITHM
%
@ -106,9 +106,4 @@ if any(isnan(endogenous_variables_paths(:)))
end
ts = dseries(transpose(endogenous_variables_paths), initial_period, M_.endo_names);
oo_.endo_simul = transpose(ts.data);
assignin('base', 'Simulated_time_series', ts);
if ~nargout || nargout<2
assignin('base', 'oo_', oo_);
end
oo_.endo_simul = transpose(ts.data);

View File

@ -70,15 +70,14 @@ pfm.block = options_.block;
options_.stack_solve_algo = ep.stack_solve_algo;
% Compute the first order reduced form if needed.
%
% REMARK. It is assumed that the user did run the same mod file with stoch_simul(order=1) and save
% all the globals in a mat file called linear_reduced_form.mat;
dr = struct();
if ep.init
options_.order = 1;
oo_.dr=set_state_space(dr,M_);
[oo_.dr,Info,M_.params] = resol(0,M_,options_,oo_.dr,oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
[oo_.dr,info,M_.params] = resol(0,M_,options_,oo_.dr,oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
if info(1)
print_info(info,options_.noprint,options_);
end
end
% Do not use a minimal number of perdiods for the perfect foresight solver (with bytecode and blocks)

View File

@ -36,7 +36,7 @@ function Simulations = extended_path_mc(initialconditions, samplesize, replic, e
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
[initialconditions, innovations, pfm, ep, verbosity, options_, oo_] = ...
[initialconditions, innovations, pfm, ep, ~, options_, oo_] = ...
extended_path_initialization(initialconditions, samplesize, exogenousvariables, options_, M_, oo_);
% Check the dimension of the first input argument

View File

@ -49,11 +49,11 @@ else
end
pfm.nd = pfm.nyp+pfm.ny0+pfm.nyf;
pfm.nrc = pfm.nyf+1;
pfm.isp = [1:pfm.nyp];
pfm.is = [pfm.nyp+1:pfm.ny+pfm.nyp];
pfm.isp = 1:pfm.nyp;
pfm.is = pfm.nyp+1:pfm.ny+pfm.nyp;
pfm.isf = pfm.iyf+pfm.nyp;
pfm.isf1 = [pfm.nyp+pfm.ny+1:pfm.nyf+pfm.nyp+pfm.ny+1];
pfm.iz = [1:pfm.ny+pfm.nyp+pfm.nyf];
pfm.isf1 = pfm.nyp+pfm.ny+1:pfm.nyf+pfm.nyp+pfm.ny+1;
pfm.iz = 1:pfm.ny+pfm.nyp+pfm.nyf;
pfm.periods = options_.ep.periods;
pfm.steady_state = oo_.steady_state;
pfm.params = M_.params;

View File

@ -70,8 +70,8 @@ else
end
if verbose
disp ([' -----------------------------------------------------']);
disp (['MODEL SIMULATION :']);
disp (' -----------------------------------------------------');
disp ('MODEL SIMULATION :');
fprintf('\n');
end

Some files were not shown because too many files have changed in this diff Show More