diff --git a/.gitignore b/.gitignore index 9b1776232..5163c3a66 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ checksum # Make Check Rules *.trs +*.tls # Doc rules *.pdf diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c102d0bf3..4b1d1519c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,8 @@ variables: GIT_SUBMODULE_STRATEGY: recursive TERM: linux + MATLAB_VERSION: R2020a + OLD_MATLAB_VERSION: R2009b # The next stanza creates the version number used for the source tarball and the # binary packages. Here are the following possible cases: @@ -10,15 +12,11 @@ variables: # + if on master: use enterprise-unstable-$TIMESTAMP-$COMMIT # + on another branch: use $BRANCH-$TIMESTAMP-$COMMIT # - if in a personal repository: use $USER-$TIMESTAMP-$COMMIT -# -# Also sets the path and version of the default MATLAB installation. before_script: - '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Enterprise ]] && [[ -n $CI_COMMIT_TAG ]] && export VERSION=$CI_COMMIT_TAG' - '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Enterprise ]] && [[ $CI_COMMIT_REF_NAME == enterprise ]] && export VERSION=enterprise-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA' - '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Enterprise ]] && export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA' - '[[ -z $VERSION ]] && export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA' - - 'export MATLAB_PATH=$(dirname $(dirname $(readlink -f $(which matlab))))' - - 'export MATLAB_VERSION=$(echo version | matlab -nodesktop -nodisplay -nosplash 2>/dev/null | sed -En "/ans\ =/!d;n;n;s/^[^0-9]*([0-9]+\.[0-9]+).*$/\1/;p")' stages: - build @@ -29,7 +27,7 @@ build_binaries: stage: build script: - autoreconf -si - - ./configure --with-matlab=$MATLAB_PATH MATLAB_VERSION=$MATLAB_VERSION PACKAGE_VERSION=$VERSION PACKAGE_STRING="dynare $VERSION" + - ./configure --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION MATLAB_VERSION=$MATLAB_VERSION PACKAGE_VERSION=$VERSION PACKAGE_STRING="dynare $VERSION" - make -j $(nproc) LN_S="cp -p" artifacts: paths: @@ -68,9 +66,10 @@ build_doc: pkg_source: stage: test_and_pkg script: + - rm doc/manual/source/_static/mathjax && sed -i "/^mathjax_path *=/d" doc/manual/source/conf.py - 'for f in configure.ac preprocessor/configure.ac mex/build/matlab/configure.ac mex/build/octave/configure.ac; do sed -i "s/^AC_INIT(\[\(.*\)\],\s*\[\(.*\)\])/AC_INIT([\1], [$VERSION])/" $f; done' - autoreconf -si - - ./configure --with-matlab=$MATLAB_PATH MATLAB_VERSION=$MATLAB_VERSION + - ./configure --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION MATLAB_VERSION=$MATLAB_VERSION - make dist artifacts: paths: @@ -142,14 +141,14 @@ test_matlab: extends: .test_matlab_template script: - autoreconf -si - - ./configure --disable-octave --with-matlab=$MATLAB_PATH MATLAB_VERSION=$MATLAB_VERSION + - ./configure --disable-octave --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION MATLAB_VERSION=$MATLAB_VERSION - make -j $(($(nproc) * 3 / 4)) -C tests check-matlab test_old_matlab: extends: .test_matlab_template script: - autoreconf -si - - ./configure --disable-octave --with-matlab=/usr/local/MATLAB/R2009b MATLAB_VERSION=R2009b + - ./configure --disable-octave --with-matlab=/usr/local/MATLAB/$OLD_MATLAB_VERSION MATLAB_VERSION=$OLD_MATLAB_VERSION - make -C mex/build/matlab clean - make -j $(nproc) -C mex/build/matlab - make -j $(($(nproc) * 3 / 4)) -C tests check-matlab diff --git a/Makefile.am b/Makefile.am index cec400b5d..410ca9a22 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,7 +16,7 @@ ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = \ matlab \ contrib \ - NEWS \ + NEWS.md \ license.txt \ README.md \ COPYING \ @@ -34,9 +34,10 @@ all-local: preprocessor/src/dynare_m$(EXEEXT) ARCH="32"; \ fi; \ mkdir -p $(abs_srcdir)/matlab/preprocessor$$ARCH && \ - $(LN_S) -f $(abs_builddir)/preprocessor/src/dynare_m$(EXEEXT) $(abs_srcdir)/matlab/preprocessor$$ARCH && \ - mkdir -p $(abs_srcdir)/julia/preprocessor$$ARCH && \ - $(LN_S) -f $(abs_builddir)/preprocessor/src/dynare_m$(EXEEXT) $(abs_srcdir)/julia/preprocessor$$ARCH + $(LN_S) -f $(abs_builddir)/preprocessor/src/dynare_m$(EXEEXT) $(abs_srcdir)/matlab/preprocessor$$ARCH + +clean-local: + rm -rf $(abs_srcdir)/matlab/preprocessor32 $(abs_srcdir)/matlab/preprocessor64 dist-hook: rm -rf `find $(distdir)/matlab $(distdir)/examples -name *~` @@ -62,5 +63,4 @@ install-exec-local: cp preprocessor/src/dynare_m $(DESTDIR)$(pkglibdir)/matlab/preprocessor$$ARCH uninstall-local: - rm -f $(DESTDIR)$(bindir)/dynare++ rm -rf $(DESTDIR)$(pkglibdir) diff --git a/NEWS b/NEWS.md similarity index 55% rename from NEWS rename to NEWS.md index 49e307bfc..8ca144dfd 100644 --- a/NEWS +++ b/NEWS.md @@ -1,3 +1,421 @@ +Announcement for Dynare 4.6.1 (on 2020-03-13) +============================================= + +We are pleased to announce the release of Dynare 4.6.1. + +This maintenance release fixes various bugs. + +The Windows, macOS and source packages are already available for download at +[the Dynare website](https://www.dynare.org/download/). + +All users are strongly encouraged to upgrade. + +This release is compatible with MATLAB versions ranging from 7.9 (R2009b) to +9.7 (R2019b), and with GNU Octave versions 5.2.0 (under Windows) and 4.4.1 +(under macOS). + +Here is a list of the problems identified in version 4.6.0 and that have been +fixed in version 4.6.1: + +* Installation on macOS would fail if the GCC compiler was supposed to be + installed and `www.google.com` was not reachable or blocked +* Dynare++ was missing the `dynare_simul.m` file +* The parameter vector `M_.params` would not be correctly updated after calls + to `stoch_simul` and `discretionary_policy` if parameters had been modified + in a steady state file +* The `stoch_simul` command with both the `nograph` and `TeX` options would + crash +* The `stoch_simul` command with the `noprint` option would crash +* The `prior moments` command would crash if the used parameter vector + triggered an error code +* In case of problem, the `discretionary_policy` command would crash instead of + aborting with a proper error code +* Computing of prior/posterior statistics would not work in parallel +* Closing of parallel estimation on GNU/Linux could crash +* The `histval` command would not work in combination with the + `predetermined_variables` command +* Ramsey optimal policy with multiple instruments would crash if a steady state + file returned complex values, instead of providing an error message +* The `model_diagnostics` command would not correctly update the parameter + vector if the latter was set in a steady state file +* The `model_diagnostics` command would ignore the `nocheck` steady state flag + + +Announcement for Dynare 4.6.0 (on 2020-02-20) +============================================= + +We are pleased to announce the release of Dynare 4.6.0. + +This major release adds new features and fixes various bugs. + +The Windows, macOS and source packages are already available for download at +[the Dynare website](https://www.dynare.org/download/). + +All users are strongly encouraged to upgrade. + +This release is compatible with MATLAB versions ranging from 7.9 (R2009b) to +9.7 (R2019b), and with GNU Octave versions 5.2.0 (under Windows) and 4.4.1 +(under macOS). + +Major user-visible changes +-------------------------- + + - Stochastic simulations + + - The perturbation method is now available at an arbitrary approximation + order. In other words, the `order` option of `stoch_simul` accepts an + arbitrary positive integer (of course, up to some model-specific + computational limit). + + - New option `filtered_theoretical_moments_grid` of `stoch_simul`, that + supersedes `hp_ngrid`. + + - Estimation + + - Nonlinear estimation is now also available at an arbitrary approximation + order. In other words, the `order` option of `estimation` accepts an + arbitrary positive integer (of course, up to some model-specific + computational limit). + + - Various improvements to particle filters. + + - It is now possible to estimate models under optimal policy (see below). + + - Variance decomposition of observables now accounts for measurement error. + + - New option `mh_tune_jscale` of `estimation` command for tuning the scale + parameter of the proposal distribution of the Random Walk Metropolis + Hastings. + + - Added debugging info when parameters take a `NaN` or `Inf` value. + + - Option `mode_compute=1` is now available under Octave. + + - Perfect foresight and extended path + + - A significant speed improvement should be noted on large models (when + neither `bytecode` nor `block` option is used). The stacked problem is + now constructed using a dedicated machine-compiled library that greatly + speeds up the process (in particular, the time spent in that step can + become negligible when the `use_dll` option is used). + + - New options `print` and `noprint` of `perfect_foresight_solver` command. + + - Option `stack_solve_algo=2` is now available under Octave. + + - Steady state + + - Option `solve_algo=7` is now available under Octave. + + - Optimal policy + + - The `ramsey_policy` command is now deprecated. It is superseded by + successive calls to `ramsey_model`, `stoch_simul`, and + `evaluate_planner_objective` (in this order). + + - It is now possible to estimate a model under optimal policy (either + Ramsey or discretionary) by running the `estimation` command after either + `ramsey_model` or `discretionary_policy`. It is however not yet possible + to estimate parameters that appear in the discount factor of the social + planner. + + - Discretionary policy returns a more informative error message when the + objective has nonzero derivatives with respect to some variables. + + - Identification + + - Added minimal system identification check of *Komunjer and Ng (2011)*. + + - Added spectrum identification check of *Qu and Tkachenko (2012)*. + + - Identification is now also available for approximation orders 2 and 3 + with either analytical or numerical parameter derivatives. The relevant + moments and spectrum are computed from the pruned state space system + as in *Mutschler (2015)*. + + - All tests (moments, spectrum, minimal system, strength) can be turned + off. + + - More numerical options can be changed by the user. + + - Improved printing and storage (same folder) of results. + + - Sensitivity analysis + + - New `diffuse_filter` option to the `dynare_sensitivity` command. + + - Arbitrary expressions can now be passed for the interval boundaries in + `irf_calibration` and `moment_calibration`. ⚠ This breaks the + previous syntax, requiring that the lower/upper bounds be separated by + commas. + + - Forecasting and smoothing + + - In `conditional_forecast_paths`, it is no longer required that all + constrained paths be of the same length. There may now be a different + number of controlled variables at each period. In that case, the order of + declaration of endogenous controlled variables and of `controlled_varexo` + matters: if the second endogenous variable is controlled for less periods + than the first one, the second `controlled_varexo` isn't set for the last + periods. + + - New option `parameter_set` to the `calib_smoother` command. + + - ⚠ The results of `conditional_forecast` command is now saved in + `oo_` (used to be in a file) + + - Shock decomposition + + - Added `fast_realtime` option to real time shock decomposition (deactivated + by default, runs the smoother only twice: once for the last in-sample and + once for the last out-of-sample data point). + + - New `diff`, `flip`, `max_nrows`, `plot_init_date` and `plot_end_date` + options to `plot_shock_decomposition`. + + - New `initial_decomposition_decomposition` command, for computing and + plotting the decomposition of the effect of smoothed initial conditions of + state variables. + + - New `squeeze_shock_decomposition` command, for removing decompositions of + variables that are not of interest. + + - New `with_epilogue` option (common to `shock_decomposition`, + `realtime_shock_decomposition` and `initial_condition_decomposition`). + + - New `init2shocks` block to attribute initial conditions to shocks. + + - Macro processor + + - New object types: real (supersedes integers), boolean (distinct from + integers), tuple, user-defined function. + + - New operators: various mathematical functions, set operations on arrays + (union, intersection, difference, cartesian power and product), type + checking and conversion. + + - Added support for comprehensions (*e.g.* the set containing the squares of + all even numbers between 1 and 5 can be constructed with `[ i^2 for i in + 1:5 when mod(i,2) == 0]`). + + - User-defined functions can be declared using the `@#define` operator (*e.g.* + `@#define f(x) = 2*x^2+3*x+5`). + + - `@#elseif`-clauses are now supported in conditional statements. + + - `@#for` loops can iterate over several variables at the same time (*e.g.* + `@#for (i,j) in X`, where `X` is an array containing tuples of size 2). + + - Added the possibility to exclude some elements when iterating over `@#for` + loops (*e.g.* `@#for i in 1:5 when mod(i,2) == 0` iterates over all even + numbers between 1 and 5). + + - A `defined()` function allows testing whether macro variables have been + defined. + + - Empty arrays (with the `[]` syntax) are now possible. + + - Arrays of arrays are now supported. + + - New macro directives `@#echomacrovars` and `@#echomacrovars(save)` for + displaying or saving the values of all macro-variables. + + - Inline comments are now supported. + + - ⚠ All division operations are now done with doubles (as opposed to + integers). To achieve the old functionality, use the new `floor` operator. + + - ⚠ Colon syntax used to require braces around it to create an array + (*e.g.* `[1:3]` would create `[1,2,3]`). Now this is not necessary (`1:3` + creates `[1,2,3]` while `[1:3]` would create `[[1,2,3]]`). + + - ⚠ Previously, printing a boolean would print `1` or `0`. Now, it + prints `true` or `false`. To achieve the old functionality, you must cast + it to a real, *e.g.* `@{(real)(1!=0)}`. + + - LaTeX output + + - New command `write_latex_steady_state_model`. + + - New option `planner_discount_latex_name` of `ramsey_model` and + `discretionary_policy`. + + - New command `model_local_variable` command for assigning a LaTeX name to + model-local variables. + + - The `write_latex_static_model` and `write_latex_original_model` commands + now support the `write_equation_tags` option. + + - Compilation of the model (`use_dll` option) made easier and faster + + - Under Windows, it is no longer necessary to manually install the + compiler, since the latter is now shipped by the Dynare installer. + + - Under macOS, the Dynare installer now automatically downloads and + installs the compiler. + + - It is no longer necessary to configure MATLAB to let it know where the + compiler is, since the compilation is now done by the preprocessor. + + - The compilation phase is now faster on large models (this has been + achieved by disabling a few time-consuming and not-so-useful optimization + passes otherwise done by the compiler). + + - New `compilation_setup` block for specifying a custom compiler or custom + compilation flags. + + - Model, variables and parameters declaration + + - New syntax to declare model variables and parameters on-the-fly in the + `model` block. To do this, simply follow the symbol name with a vertical + line (`|`, pipe character) and either an `e`, an `x`, or a `p`. For + example, to declare a parameter named `alpha` in the model block, you + could write `alpha|p` directly in an equation where it appears. + Similarly, to declare an endogenous variable `c` in the model block you + could write `c|e`. + + - New syntax to declare model variable and parameters on-the-fly in + equation tags. In the tag, simply state the type of variable to be + declared (`endogenous`, `exogenous`, or `parameter` followed by an equal + sign and the variable name in single quotes. Hence, to declare a variable + `c` as endogenous in an equation tag, you can type `[endogenous='c']`. + + - New `epilogue` block for computing output variables of interest that may + not be necessarily defined in the model (*e.g.* various kinds of + real/nominal shares or relative prices, or annualized variables out of a + quarterly model). + + - Command-line options + + - Added the possibility to declare Dynare command-line options in the `.mod` + file. + + - New option `nopreprocessoroutput` to disable printing of messages from + the preprocessor. + + - It is now possible to assign an arbitrary macro-expression to a + macro-variable defined on the command-line, using the `-D` syntax. + + - New option `linemacro` to revert to the old format of the + macro-processed file (see below). + + - Preprocessor outputs and inputs + + - Added JSON output to the preprocessor. A representation of the model file + and the whole content of the `.mod` file is saved in `.json` files. + These JSON files can be easily parsed from any language (C++, Fortran, + Python, Julia, MATLAB, Octave…). This new feature opens the possibility to + develop alternative back-ends for the Dynare language. + + - ⚠ Most files generated by the preprocessor are now grouped under + two subdirectories. Assuming your file is `FILENAME.mod`, then M-files + and MEX-files will be under `+FILENAME/`, while other output (JSON, + LaTeX, source code for the MEX files) will be under `FILENAME/`. + + - The macro-generated output is now more readable (no more line numbers and + empty lines). The old behaviour can be restored using the `linemacro` + option (see above). + + - Ability to call the preprocessor by passing the `.mod` file as a string + argument from the macOS or GNU/Linux command line. + + - dseries classes + + - New functionalities and efficiency improvements. + + - Complete rewrite using the new `classdef` syntax and exploiting in place + modifications when possible. + + - Integration of the `dates` classes within `dseries`. + + - Reporting classes + + - Automatically create titlepage with page numbers/page titles. + + - Allow for the removal of headers and footers from a given page. + + - Allow user to set page number. + + - Split up report output. Create new files for the preamble, the body of + the report, and each individual page of the report. + + - The classes have been converted to the new `classdef` syntax. + + - Misc + + - External functions can be located in MATLAB/Octave namespaces. + + - Improvements to the balanced growth path test that is performed after + Dynare has detrended the model (given the trends on variables declared by + the user): the default tolerance has been raised, and a different value + can be set with new option `balanced_growth_test_tol` to the `model` + block; as a consequence, failing the test is now an error again. + + - New collection of MATLAB/Octave utilities to retrieve and alter objects: + `get_irf`, `get_mean`, `get_shock_stderr_by_name`, `get_smooth`, + `get_update`, `set_shock_stderr_value`. + + - ⚠ Previously, when some MEX files were missing, Dynare would + automatically fall back to slower M-file functional alternative; this is + no longer the case. It is however still possible to manually add these + alternatives in the MATLAB/Octave path (they are located under + `matlab/missing/mex`; this only applies to the `mjdgges`, `gensylv`, + `A_times_B_kronecker_C`, `sparse_hessian_times_B_kronecker_C` and + `local_state_space_iteration_2` DLLs). + + +Since there are a few backward-incompatible changes in this release, users may +want to have a look at the [upgrade +guide](https://git.dynare.org/Dynare/dynare/-/wikis/BreakingFeaturesIn4.6) to +adapt their existing codes. + + +Bugs that were present in 4.5.7 and that are fixed in 4.6.0 +----------------------------------------------------------- + +* Estimation: the check for stochastic singularity erroneously would only take + estimated measurement error into account. +* Estimation: if the Hessian at the mode was not positive definite, the Laplace + approximation returned a complex number, but only displayed the real-valued + part. +* Conditional Forecasting: using one period only would result in a crash. +* First-order approximation was not working with purely forward-looking models. +* The preprocessor would not allow for inline comments including macro + statements. +* Using the `STEADY_STATE()` operator on exogenous variables would lead to + crashes in stochastic simulations. +* `moment_calibration`: for autocorrelation functions, the x-axis labeling had + the wrong order. +* `plot_identification`: placement of white dots indicating infinite values was + incorrect +* Automatic detrending would sometime refuse to detrend model despite the user + having given correct trends. +* Using `use_dll` + `fast` options would not always recompile the model when + the equations were changed. +* Under certain circumstances, the combination of `bytecode` and + `stack_solve_algo=1` options could lead to crashes or wrong results. + + +References +---------- + + - Komunjer, I. and S. Ng (2011), “[Dynamic Identification of Dynamic + Stochastic General Equilibrium + Models](https://www.onlinelibrary.wiley.com/doi/abs/10.3982/ECTA8916),” + *Econometrica*, 79(6), 1995–2032 + + - Qu, Z. and D. Tkachenko (2012), “[Identification and frequency domain + quasi‐maximum likelihood estimation of linearized dynamic stochastic + general equilibrium + models](https://onlinelibrary.wiley.com/doi/abs/10.3982/QE126),” + *Quantitative Economics*, 3(1), 95–132 + + - Mutschler, W. (2015), “[Identification of DSGE models—The effect of + higher-order approximation and + pruning](https://www.sciencedirect.com/science/article/pii/S0165188915000731),” + *Journal of Economic Dynamics and Control*, 56, 34–54 + + Announcement for Dynare 4.5.7 (on 2019-02-06) ============================================= @@ -5,9 +423,7 @@ We are pleased to announce the release of Dynare 4.5.7. This is a bugfix release. -The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +The Windows packages are already available for download at: . The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -41,7 +457,7 @@ fixed in version 4.5.7: display LaTeX names. - Parameter updating via steady state files did not correctly work in - case of using [static]/[dynamic] equation tags. + case of using `[static]`/`[dynamic]` equation tags. - Memory leaks in `k_order_pert` (used by higher order stochastic simulations) could lead to crashes. @@ -63,7 +479,7 @@ fixed in version 4.5.7: - The model was not correctly specified when `identification` was run without another stochastic command in the `.mod` file - (e.g. `estimation`, `stoch_simul`, etc.). + (*e.g.* `estimation`, `stoch_simul`, etc.). - Realtime annualized shock decompositions added the wrong steady state value. @@ -83,8 +499,7 @@ We are pleased to announce the release of Dynare 4.5.6. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -129,8 +544,7 @@ We are pleased to announce the release of Dynare 4.5.5. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -169,8 +583,7 @@ We are pleased to announce the release of Dynare 4.5.4. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -210,7 +623,7 @@ fixed in version 4.5.4: - The `plot_shock_decomposition` command ignored various user-defined options like `fig_name`, `use_shock_groups` or `interactive` and instead used the default options. - - Nested `@#ifdef` and `@#ifndef` statements don't work in the macroprocessor. + - Nested `@#ifdef` and `@#ifndef` statements don’t work in the macroprocessor. @@ -223,8 +636,7 @@ This is a bugfix release. It comes less than 24 hours after the previous release because version 4.5.2 was affected by a critical bug for MATLAB older than R2016b. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -235,7 +647,7 @@ Here is a list of the problems identified in version 4.5.2 and that have been fixed in version 4.5.3: - - `isfile` routine was failing with matlab older than R2016b. This bug did not + - `isfile` routine was failing with MATLAB older than R2016b. This bug did not affect Octave. @@ -248,8 +660,7 @@ We are pleased to announce the release of Dynare 4.5.2. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -327,8 +738,7 @@ We are pleased to announce the release of Dynare 4.5.1. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -371,8 +781,7 @@ We are pleased to announce the release of Dynare 4.5.0. This major release adds new features and fixes various bugs. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and Debian/Ubuntu packages should follow soon. @@ -387,7 +796,7 @@ Here is the list of major user-visible changes: - Ramsey policy + Added command `ramsey_model` that builds the expanded model with - FOC conditions for the planner's problem but doesn't perform any + FOC conditions for the planner’s problem but doesn’t perform any computation. Usefull to compute Ramsey policy in a perfect foresight model, @@ -473,7 +882,7 @@ Here is the list of major user-visible changes: `consider_only_observed`, `posterior_max_subsample_draws`, `mh_conf_sig`, `diffuse_kalman_tol`, `dirname`, `nodecomposition` - + `load_mh_file` and `mh_recover` now try to load chain's proposal density, + + `load_mh_file` and `mh_recover` now try to load chain’s proposal density, + New option `load_results_after_load_mh` that allows loading some posterior results from a previous run if no new MCMC draws are @@ -519,11 +928,11 @@ Here is the list of major user-visible changes: pair allows loading the `_mh_scale.mat`-file storing the tuned scale factor from a previous run of `mode_compute=6`, - + New option `raftery_lewis_diagnostics` that computes Raftery/Lewis - (1992) convergence diagnostics, + + New option `raftery_lewis_diagnostics` that computes *Raftery and Lewis + (1992)* convergence diagnostics, + New option `fast_kalman_filter` that provides fast Kalman filter - using Chandrasekhar recursions as described in Ed Herbst (2015), + using Chandrasekhar recursions as described in *Ed Herbst (2015)*, + The `dsge_var` option now saves results at the posterior mode into `oo_.dsge_var`, @@ -631,7 +1040,7 @@ Here is the list of major user-visible changes: + New command `realtime_shock_decomposition` that for each period `T= [presample,...,nobs]` allows computing the: - * realtime historical shock decomposition `Y(t|T)`, i.e. without observing data in `[T+1,...,nobs]` + * realtime historical shock decomposition `Y(t|T)`, *i.e.* without observing data in `[T+1,...,nobs]` * forecast shock decomposition `Y(T+k|T)` @@ -684,12 +1093,12 @@ Here is the list of major user-visible changes: - Optimization algorithms + `mode_compute=2` Uses the simulated annealing as described by - Corana et al. (1987), + *Corana et al. (1987)*, - + `mode_compute=101` Uses SOLVEOPT as described by Kuntsevich and - Kappel (1997), + + `mode_compute=101` Uses SOLVEOPT as described by *Kuntsevich and + Kappel (1997)*, - + `mode_compute=102` Uses `simulannealbnd` from MATLAB's Global + + `mode_compute=102` Uses `simulannealbnd` from MATLAB’s Global Optimization Toolbox (if available), + New option `silent_optimizer` to shut off output from mode @@ -724,7 +1133,7 @@ Here is the list of major user-visible changes: + Introduces new path management to avoid conflicts with other toolboxes, - + Full compatibility with MATLAB 2014b's new graphic interface, + + Full compatibility with MATLAB 2014b’s new graphic interface, + When using `model(linear)`, Dynare automatically checks whether the model is truly linear, @@ -750,7 +1159,7 @@ Here is the list of major user-visible changes: -* Bugs and problems identified in version 4.4.3 and that have been fixed in version 4.5.0: +Bugs and problems identified in version 4.4.3 and that have been fixed in version 4.5.0: - BVAR models @@ -882,7 +1291,7 @@ Here is the list of major user-visible changes: + Option `kalman_algo=3` was broken with non-diagonal measurement error, + When using the diffuse Kalman filter with missing observations, an additive - factor log(2*pi) was missing in the last iteration step, + factor log(2π) was missing in the last iteration step, + Passing of the `MaxFunEvals` and `InitialSimplexSize` options to `mode_compute=8` was broken, @@ -930,7 +1339,7 @@ Here is the list of major user-visible changes: initialization of the MCMC erroneously crashed, + If the number of dropped draws via `mh_drop` coincided with the number of - draws in a `_mh'-file`, `oo_.posterior.metropolis.mean` and + draws in a `_mh`-file, `oo_.posterior.metropolis.mean` and `oo_.posterior.metropolis.Variance` were NaN. @@ -1113,7 +1522,7 @@ Here is the list of major user-visible changes: error code, but not an conformable-sized steady state vector. - Due to a bug in `mjdgges.mex` unstable parameter draws with - eigenvalues up to 1+1e-6 could be accepted as stable for the + eigenvalues up to 1+10⁻⁶ could be accepted as stable for the purpose of the Blanchard-Kahn conditions, even if `qz_criterium<1`. - The `use_dll` option on Octave for Windows required to pass a @@ -1163,8 +1572,7 @@ We are pleased to announce the release of Dynare 4.4.3. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -1177,11 +1585,11 @@ fixed in version 4.4.3: - When loading a dataset in XLS, XLSX or CSV format, the first observation was discarded. - - Reading data in an Excel-file with only one variable wasz leading + - Reading data in an Excel-file with only one variable was leading to a crash. - - When using the k_order_perturbation option (which is implicit at - 3rd order) without the use_dll option, crashes or unexpected + - When using the `k_order_perturbation` option (which is implicit at + 3rd order) without the `use_dll` option, crashes or unexpected behavior could happen if some 2nd or 3rd derivative evaluates to zero (while not being symbolically zero) @@ -1189,7 +1597,7 @@ fixed in version 4.4.3: wrong results. - For Ramsey policy, the equation numbers associated with the - Lagrange multipliers stored in M_.aux_vars were erroneously one too + Lagrange multipliers stored in `M_.aux_vars` were erroneously one too low - When updating deep parameters in the steady state file, the changes @@ -1200,26 +1608,26 @@ fixed in version 4.4.3: results were returned (if second order derivates of the external functions were needed). - - The confidence level for computations in estimation, conf_sig could - not be changed and was fixed at 0.9. The new option mh_conf_sig is + - The confidence level for computations in estimation, `conf_sig` could + not be changed and was fixed at 0.9. The new option `mh_conf_sig` is now used to set this interval - Conditional forecasts with non-diagonal covariance matrix used an incorrect decomposition of the covariance matrix. A Cholesky factorization is used. - - Option geweke_interval was not effective, Dynare always defaulted + - Option `geweke_interval` was not effective, Dynare always defaulted to the standard value. - - The mode_file option lacked backward compatibility with older + - The `mode_file` option lacked backward compatibility with older Dynare versions. - - Loading an mh_mode file with the mode_file option was broken. + - Loading an `mh_mode` file with the `mode_file` option was broken. - - Using identification with var_exo_det leaded to crashes (the + - Using `identification` with `var_exo_det` leaded to crashes (the preprocessor now returns an error if they are used simultaneously) - - The identification command did not print results if the initial + - The `identification` command did not print results if the initial parameter set was invalid and then crashed later on if the MC sample is bigger than 1 @@ -1228,8 +1636,8 @@ fixed in version 4.4.3: - The use of external functions crashed the preprocessor when the derivatives of the external function are explicitly called in the - model block. The preprocessor now forbids the use of external - functions derivates in the model block. + `model` block. The preprocessor now forbids the use of external + functions derivates in the `model` block. - Using the block option when a variable does not appear in the current period crashed Dynare instead of providing an error @@ -1244,8 +1652,7 @@ We are pleased to announce the release of Dynare 4.4.2. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu LTS) should follow soon. @@ -1255,20 +1662,20 @@ and with GNU Octave versions 3.6 to 3.8. Here is a list of the problems identified in version 4.4.1 and that have been fixed in version 4.4.2: - - Geweke convergence diagnostics was computed on the wrong sample if `mh_drop' + - Geweke convergence diagnostics was computed on the wrong sample if `mh_drop` was not equal to the default of 0.5. - - The `loglinear' option of `stoch_simul' was displaying the steady state of + - The `loglinear` option of `stoch_simul` was displaying the steady state of the original values, not the logged ones, and was producing incorrect simulations and simulated moments. Theoretical moments were unaffected. - - The `optim' option of `estimation (for setting options to `mode_compute') + - The `optim` option of `estimation` (for setting options to `mode_compute`) was only working with at least MATLAB 8.1 (R2013a) or Octave 3.8. - For unit root models, theoretical HP filtered moments were sometimes erroneously displayed as NaN. - - Specifying an endogenous variable twice after the `estimation' command would + - Specifying an endogenous variable twice after the `estimation` command would lead to a crash in the computation of moments. - Deterministic simulations were crashing on some models with more than one @@ -1278,9 +1685,9 @@ fixed in version 4.4.2: working correctly (during the homotopy steps the perfect foresight model solver was called instead of the stochastic perfect foresight model solver). - - MCMC convergence diagnostics were not computed if `mh_replic' was less than + - MCMC convergence diagnostics were not computed if `mh_replic` was less than 2000; the test now relies on the total number of iterations (this only makes - a difference if option `load_mh_file' is used). + a difference if option `load_mh_file` is used). Announcement for Dynare 4.4.1 (on 2014-01-17) @@ -1292,8 +1699,7 @@ This release contains a few changes to the user interface and fixes various bugs. It also adds compatibility with Octave 3.8. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu) should follow soon. @@ -1304,31 +1710,31 @@ with GNU Octave versions 3.6 to 3.8. * Changes to the user interface: - - The syntax introduced in 4.4.0 for conditional forecast in a deterministic - setup was removed, and replaced by a new one that is better suited to the - task. More precisely, such deterministic forecasts are no longer done using - the `conditional_forecast' command. The latter is replaced by a group of - commands: `init_plan', `basic_plan' and `flip_plan'. See the reference - manual for more details. - - - Changes to the reporting module: option `annualAverages' to `addTable' has - been removed (use option `tableDataRhs' to `addSeries' instead); option - `vlineAfter' to `addTable' now also accepts a cell array. - - - Changes to the date and time series classes: implement broadcasting for - operations (+,-,* and /) between `dseries' class and scalar or vectors; add - the possibility of selecting an observation within a time series using a - formatted string containing a date. - + - The syntax introduced in 4.4.0 for conditional forecast in a deterministic + setup was removed, and replaced by a new one that is better suited to the + task. More precisely, such deterministic forecasts are no longer done using + the `conditional_forecast` command. The latter is replaced by a group of + commands: `init_plan`, `basic_plan` and `flip_plan`. See the reference + manual for more details. + + - Changes to the reporting module: option `annualAverages` to `addTable` has + been removed (use option `tableDataRhs` to `addSeries` instead); option + `vlineAfter` to `addTable` now also accepts a cell array. + + - Changes to the date and time series classes: implement broadcasting for + operations (`+`,`-`,`*` and `/`) between `dseries` class and scalar or vectors; add + the possibility of selecting an observation within a time series using a + formatted string containing a date. + * Bugs and problems identified in version 4.4.0 and that have been fixed in version 4.4.1: - - In MS-SBVAR, there was a bug preventing the computation of impulse responses - on a constant regime. - - - Under Octave, after modifying the MOD file, the changes were not taken into - account at the first Dynare run, but only at the second run. - + - In MS-SBVAR, there was a bug preventing the computation of impulse responses + on a constant regime. + + - Under Octave, after modifying the MOD file, the changes were not taken into + account at the first Dynare run, but only at the second run. + Announcement for Dynare 4.4.0 (on 2013-12-16) ============================================= @@ -1338,8 +1744,7 @@ We are pleased to announce the release of Dynare 4.4.0. This major release adds new features and fixes various bugs. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and Debian/Ubuntu packages should follow soon. @@ -1353,231 +1758,231 @@ Here is the list of major user-visible changes: * New major algorithms: - - Extended path at order 1 and above, also known as “stochastic extended - path”. This method is triggered by setting the `order' option of the - `extended_path' command to a value greater than 0. Dynare will then use a - Gaussian quadrature to take into account the effects of future uncertainty. - The time series for the endogenous variables are generated by assuming that - the agents believe that there will no more shocks after period t+order. - - - Alternative algorithms for computing decision rules of a stochastic model, - based on the cycle reduction and logarithmic reduction algorithms. These - methods are respectively triggered by giving `dr = cycle_reduction' or 'dr - = logarithmic_reduction' as an option to the `stoch_simul' command. - - - Pruning now works with 3rd order approximation, along the lines of - Andreasen, Fernández-Villaverde and Rubio-Ramírez (2013). - - - Computation of conditional forecast using an extended path method. This is - triggered by the new option `simulation_type = deterministic' in the - `conditional_forecast' command. In this case, the `expectation' command in - the `conditional_forecast_paths' block has to be used to indicate the nature - of expectations (whether shocks are a surprise or are perfectly - anticipated). - - - Endogenous priors as in Christiano, Trabandt and Walentin (2011). Those are - triggered by the new option `endogenous_prior' of the `estimation' command. - + - Extended path at order 1 and above, also known as “stochastic extended + path”. This method is triggered by setting the `order` option of the + `extended_path` command to a value greater than 0. Dynare will then use a + Gaussian quadrature to take into account the effects of future uncertainty. + The time series for the endogenous variables are generated by assuming that + the agents believe that there will no more shocks after period t+order. + + - Alternative algorithms for computing decision rules of a stochastic model, + based on the cycle reduction and logarithmic reduction algorithms. These + methods are respectively triggered by giving `dr = cycle_reduction` or `dr + = logarithmic_reduction` as an option to the `stoch_simul` command. + + - Pruning now works with 3rd order approximation, along the lines of + *Andreasen, Fernández-Villaverde and Rubio-Ramirez (2013)*. + + - Computation of conditional forecast using an extended path method. This is + triggered by the new option `simulation_type = deterministic` in the + `conditional_forecast` command. In this case, the `expectation` command in + the `conditional_forecast_paths` block has to be used to indicate the nature + of expectations (whether shocks are a surprise or are perfectly + anticipated). + + - Endogenous priors as in Christiano, Trabandt and Walentin (2011). Those are + triggered by the new option `endogenous_prior` of the `estimation` command. + * Other algorithmic improvements: - - New command `model_diagnostics' to perform various sanity checks on the - model. Note: in the past, some users may have used a preliminary MATLAB - function implementing this; the new command has the same syntax, except that - you shouldn't pass any argument to it. - - - Terminal conditions of perfect foresight simulations can now be specified in - growth rates. More specifically, the new option `differentiate_forward_vars' - of the `model' block will create auxiliary forward looking variables - expressed in first differences or growth rates of the actual forward looking - variables defined in the model. These new variables have obvious zero - terminal conditions whatever the simulation context and this in many cases - helps convergence of simulations. - - - Convergence diagnostics for single chain MCMC à la Geweke (1992, 1999). - - - New optimizer for the posterior mode (triggered by `mode_compute=10'): it - uses the simpsa algorithm, based on the combination of the non-linear - simplex and simulated annealing algorithms and proposed by Cardoso, Salcedo - and Feyo de Azevedo (1996). - - - The automatic detrending engine has been extended to work on models written - in logs. The corresponding trend variable type is `log_trend_var', and the - corresponding deflator type is `log_deflator'. - + - New command `model_diagnostics` to perform various sanity checks on the + model. Note: in the past, some users may have used a preliminary MATLAB + function implementing this; the new command has the same syntax, except that + you shouldn’t pass any argument to it. + + - Terminal conditions of perfect foresight simulations can now be specified in + growth rates. More specifically, the new option `differentiate_forward_vars` + of the `model` block will create auxiliary forward looking variables + expressed in first differences or growth rates of the actual forward looking + variables defined in the model. These new variables have obvious zero + terminal conditions whatever the simulation context and this in many cases + helps convergence of simulations. + + - Convergence diagnostics for single chain MCMC à la *Geweke (1992, 1999)*. + + - New optimizer for the posterior mode (triggered by `mode_compute=10`): it + uses the simpsa algorithm, based on the combination of the non-linear + simplex and simulated annealing algorithms and proposed by *Cardoso, Salcedo + and Feyo de Azevedo (1996)*. + + - The automatic detrending engine has been extended to work on models written + in logs. The corresponding trend variable type is `log_trend_var`, and the + corresponding deflator type is `log_deflator`. + * New features in the user interface: - - New set of functions for easily creating PDF reports including figures and - tables. See the “Reporting” section in the reference manual for more - details. - - - New MATLAB/Octave classes for handling time series. See the “Time series” - section in the reference manual for more details. - - - Datafiles in CSV format can now be used for estimation. - - - New macro processor `length' operator, returns the length of an array. - - - New option `all_values_required' of `initval' and `endval' blocks: enforces - initialization of all endogenous and exogenous variables within the block. - - - Option `ar' can now be given to the `estimation' command. - - - New options `nograph', `nointeractive' and `nowarn' to the `dynare' command, - for a better control of what is displayed. - - - New option `nostrict' to the `dynare' command, for allowing Dynare to - continue processing when there are more endogenous variables than equations - or when an undeclared symbol is assigned in `initval' or `endval'. - - - The information on MCMC acceptance rates, seeds, last log posterior - likelihood, and last parameter draw are now saved on the disk and can - be displayed with `internals --display-mh-history' or loaded into the - workspace with `internals --load-mh-history'. - - - New options `mode_check_neighbourhood_size', `mode_check_symmetric_plots' - and `mode_check_number_of_points', for a better control of the diagnostic - plots. - - - New option `parallel_local_files' of `model' block, for transferring extra - files during parallel computations. - - - New option `clock' of `set_dynare_seed', for setting a different seed at - each run. - - - New option `qz_zero_threshold' of the `check', `stoch_simul' and - `estimation' commands, for a better control of the situation where a - generalized eigenvalue is close to 0/0. - - - New `verbatim' block for inclusion of text that should pass through the - preprocessor and be placed as is in the `modfile.m' file. - - - New option `mcmc_jumping_covariance' of the `estimation' command, for a - better control of the covariance matrix used for the proposal density of the - MCMC sampler. - - - New option `use_calibration' of the `estimated_params_init', for using the - calibration of deep parameters and the elements of the covariance matrix - specified in the `shocks' block as starting values for the estimation. - - - New option `save_draws' of the `ms_simulation' command. - - - New option `irf_plot_threshold' of the `stoch_simul' and `estimation' - commands, for a better control of the display of IRFs which are almost nil. - - - New option `long_name' for endogenous, exogenous and parameter declarations, - which can be used to declare a long name for variables. That long name can - be programmatically retrieved in `M_.endo_names_long'. - + - New set of functions for easily creating PDF reports including figures and + tables. See the “Reporting” section in the reference manual for more + details. + + - New MATLAB/Octave classes for handling time series. See the “Time series” + section in the reference manual for more details. + + - Datafiles in CSV format can now be used for estimation. + + - New macro processor `length` operator, returns the length of an array. + + - New option `all_values_required` of `initval` and `endval` blocks: enforces + initialization of all endogenous and exogenous variables within the block. + + - Option `ar` can now be given to the `estimation` command. + + - New options `nograph`, `nointeractive` and `nowarn` to the `dynare` command, + for a better control of what is displayed. + + - New option `nostrict` to the `dynare` command, for allowing Dynare to + continue processing when there are more endogenous variables than equations + or when an undeclared symbol is assigned in `initval` or `endval`. + + - The information on MCMC acceptance rates, seeds, last log posterior + likelihood, and last parameter draw are now saved on the disk and can + be displayed with `internals --display-mh-history` or loaded into the + workspace with `internals --load-mh-history`. + + - New options `mode_check_neighbourhood_size`, `mode_check_symmetric_plots` + and `mode_check_number_of_points`, for a better control of the diagnostic + plots. + + - New option `parallel_local_files` of `model` block, for transferring extra + files during parallel computations. + + - New option `clock` of `set_dynare_seed`, for setting a different seed at + each run. + + - New option `qz_zero_threshold` of the `check`, `stoch_simul` and + `estimation` commands, for a better control of the situation where a + generalized eigenvalue is close to 0/0. + + - New `verbatim` block for inclusion of text that should pass through the + preprocessor and be placed as is in the `modfile.m` file. + + - New option `mcmc_jumping_covariance` of the `estimation` command, for a + better control of the covariance matrix used for the proposal density of the + MCMC sampler. + + - New option `use_calibration` of the `estimated_params_init`, for using the + calibration of deep parameters and the elements of the covariance matrix + specified in the `shocks` block as starting values for the estimation. + + - New option `save_draws` of the `ms_simulation` command. + + - New option `irf_plot_threshold` of the `stoch_simul` and `estimation` + commands, for a better control of the display of IRFs which are almost nil. + + - New option `long_name` for endogenous, exogenous and parameter declarations, + which can be used to declare a long name for variables. That long name can + be programmatically retrieved in `M_.endo_names_long`. + * Miscellaneous changes - - The deciles of some posterior moments were erroneously saved in a field - `Distribution' under `oo_'. This field is now called `deciles', for - consistency with other posterior moments and with the manual. Similarly, the - fields `Mean', `Median', `HPDsup', `HPDinf', and `Variance' are now - consistently capitalized. - - - The console mode now implies the `nodisplay' option. - + - The deciles of some posterior moments were erroneously saved in a field + `Distribution` under `oo_`. This field is now called `deciles`, for + consistency with other posterior moments and with the manual. Similarly, the + fields `Mean`, `Median`, `HPDsup`, `HPDinf`, and `Variance` are now + consistently capitalized. + + - The console mode now implies the `nodisplay` option. + * Bugs and problems identified in version 4.3.3 and that have been fixed in version 4.4.0: - - In an `endval' block, auxiliary variables were not given the right value. - This would not result in wrong results, but could prevent convergence of - the steady state computation. - - - Deterministic simulations with `stack_solve_algo=0' (the default value) were - crashing if some exogenous had a lag strictly greater than 1. - - - When using the `mode_file' option, the initial estimation checks were not - performed for the loaded mode, but for the original starting values. Thus, - potential prior violations by the mode only appeared during estimation, - leading to potentially cryptic crashes and error messages. - - - If a shock/measurement error variance was set to 0 in calibration, the - correlation matrix featured a 0 instead of a 1 on the diagonal, leading to - wrong estimation results. - - - In the presence of calibrated covariances, estimation did not enforce - positive definiteness of the covariance matrix. - - - Estimation using the `diffuse_filter' option together with the univariate - Kalman filter and a diagonal measurement error matrix was broken. - - - A purely backward model with `k_order_solver' was leading to crashes of - MATLAB/Octave. - - - Non-linear estimation was not skipping the specified presample when - computing the likelihood. - - - IRFs and theoretical moments at order > 1 were broken for purely - forward-looking models. - - - Simulated moments with constant variables was leading to crashes when - displaying autocorrelations. - - - The `osr' command was sometimes crashing with cryptic error messages because - of some unaccounted error codes returned from a deeper routine. - - - The check for stochastic singularity during initial estimation checks was - broken. - - - Recursive estimation starting with the pathological case of `nobs=1' was - crashing. - - - Conditional variance decomposition within or after estimation was crashing - when at least one shock had been calibrated to zero variance. - - - The `estimated_params_init' and `estimated_params_bounds' blocks were broken - for correlations. - - - The `filter_step_ahead' option was not producing any output in Bayesian - estimation. - - - Deterministic simulations were sometimes erroneously indicating convergence - although the residuals were actually NaN or Inf. - - - Supplying a user function in the `mode_compute' option was leading to - a crash. - - - Deterministic simulation of models without any exogenous variable was - crashing. - - - The MS-SBVAR code was not updating files between runs on Windows. This means - that if a MOD file was updated between runs in the same folder and a - `file_tag' was not changed, then the results would not change. - - - The `ramsey_policy' command was not putting in `oo_.planner_objective_value' - the value of the planner objective at the optimum. - + - In an `endval` block, auxiliary variables were not given the right value. + This would not result in wrong results, but could prevent convergence of + the steady state computation. + + - Deterministic simulations with `stack_solve_algo=0` (the default value) were + crashing if some exogenous had a lag strictly greater than 1. + + - When using the `mode_file` option, the initial estimation checks were not + performed for the loaded mode, but for the original starting values. Thus, + potential prior violations by the mode only appeared during estimation, + leading to potentially cryptic crashes and error messages. + + - If a shock/measurement error variance was set to 0 in calibration, the + correlation matrix featured a 0 instead of a 1 on the diagonal, leading to + wrong estimation results. + + - In the presence of calibrated covariances, estimation did not enforce + positive definiteness of the covariance matrix. + + - Estimation using the `diffuse_filter` option together with the univariate + Kalman filter and a diagonal measurement error matrix was broken. + + - A purely backward model with `k_order_solver` was leading to crashes of + MATLAB/Octave. + + - Non-linear estimation was not skipping the specified presample when + computing the likelihood. + + - IRFs and theoretical moments at order > 1 were broken for purely + forward-looking models. + + - Simulated moments with constant variables was leading to crashes when + displaying autocorrelations. + + - The `osr` command was sometimes crashing with cryptic error messages because + of some unaccounted error codes returned from a deeper routine. + + - The check for stochastic singularity during initial estimation checks was + broken. + + - Recursive estimation starting with the pathological case of `nobs=1` was + crashing. + + - Conditional variance decomposition within or after estimation was crashing + when at least one shock had been calibrated to zero variance. + + - The `estimated_params_init` and `estimated_params_bounds` blocks were broken + for correlations. + + - The `filter_step_ahead` option was not producing any output in Bayesian + estimation. + + - Deterministic simulations were sometimes erroneously indicating convergence + although the residuals were actually NaN or Inf. + + - Supplying a user function in the `mode_compute` option was leading to + a crash. + + - Deterministic simulation of models without any exogenous variable was + crashing. + + - The MS-SBVAR code was not updating files between runs on Windows. This means + that if a MOD file was updated between runs in the same folder and a + `file_tag` was not changed, then the results would not change. + + - The `ramsey_policy` command was not putting in `oo_.planner_objective_value` + the value of the planner objective at the optimum. + * References: - - Andreasen, Martin M., Jesús Fernández-Villaverde, and Juan Rubio-Ramírez - (2013): “The Pruned State-Space System for Non-Linear DSGE Models: Theory - and Empirical Applications,” NBER Working Paper, 18983 - - - Cardoso, Margarida F., R. L. Salcedo and S. Feyo de Azevedo (1996): “The - simplex simulated annealing approach to continuous non-linear optimization,” - Computers chem. Engng, 20(9), 1065-1080 - - - 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), 1999-2041 - - - Geweke, John (1992): “Evaluating the accuracy of sampling-based approaches - to the calculation of posterior moments,” in J.O. Berger, J.M. Bernardo, - A.P. Dawid, and A.F.M. Smith (eds.) Proceedings of the Fourth Valencia - International Meeting on Bayesian Statistics, pp. 169-194, Oxford University - Press - - - Geweke, John (1999): “Using simulation methods for Bayesian econometric - models: Inference, development and communication,” Econometric Reviews, - 18(1), 1-73 - + - Andreasen, Martin M., Jesús Fernández-Villaverde, and Juan Rubio-Ramirez + (2013): “The Pruned State-Space System for Non-Linear DSGE Models: Theory + and Empirical Applications,” *NBER Working Paper*, 18983 + + - Cardoso, Margarida F., R. L. Salcedo and S. Feyo de Azevedo (1996): “The + simplex simulated annealing approach to continuous non-linear optimization,” + *Computers chem. Engng*, 20(9), 1065-1080 + + - 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), 1999-2041 + + - Geweke, John (1992): “Evaluating the accuracy of sampling-based approaches + to the calculation of posterior moments,” in J.O. Berger, J.M. Bernardo, + A.P. Dawid, and A.F.M. Smith (eds.) *Proceedings of the Fourth Valencia + International Meeting on Bayesian Statistics*, pp. 169-194, Oxford University + Press + + - Geweke, John (1999): “Using simulation methods for Bayesian econometric + models: Inference, development and communication,” *Econometric Reviews*, + 18(1), 1-73 + Announcement for Dynare 4.3.3 (on 2013-04-12) ============================================= @@ -1587,8 +1992,7 @@ We are pleased to announce the release of Dynare 4.3.3. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu) should follow soon. @@ -1603,30 +2007,30 @@ fixed in version 4.3.3: - Estimation with measurement errors was wrong if a correlation between two measurement errors was calibrated - - Option `use_dll' was broken under Windows + - Option `use_dll` was broken under Windows - Degenerate case of purely static models (no leads/no lags) were not correctly handled - Deterministic simulations over a single period were not correctly done - - The sensitivity call `dynare_sensitivity(identification=1,morris=2)' was + - The sensitivity call `dynare_sensitivity(identification=1,morris=2)` was buggy when there are no shocks estimated - - Calls to `shock_decomposition' after using `selected_variables_only' option + - Calls to `shock_decomposition` after using `selected_variables_only` option fail - Sometimes, only the last open graph was saved, leading to missing and duplicate EPS/PDF graphs - Forecasting after maximum likelihood estimation when not forecasting at - least one observed variables (`var_obs') was leading to crashes + least one observed variables (`var_obs`) was leading to crashes - Some functionalities were crashing with MATLAB 8.1/R2013a (bytecode, MS-SBVAR) - - Sometimes only the first order autocorrelation of `moments_varendo' was - saved instead of all up to the value of `ar' option + - Sometimes only the first order autocorrelation of `moments_varendo` was + saved instead of all up to the value of `ar` option Announcement for Dynare 4.3.2 (on 2013-01-18) @@ -1637,8 +2041,7 @@ We are pleased to announce the release of Dynare 4.3.2. This is a bugfix release. The Windows packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The Mac and GNU/Linux packages (for Debian and Ubuntu) should follow soon. @@ -1653,17 +2056,17 @@ fixed in version 4.3.2: - Computation of posterior distribution of unconditional variance decomposition was sometimes crashing (only for very large models) - - Estimation with `mode_compute=6' was sometimes crashing + - Estimation with `mode_compute=6` was sometimes crashing - - Derivative of erf() function was incorrect + - Derivative of `erf()` function was incorrect - - The `check' command was not setting `oo_.dr.eigval' unless `stoch_simul' was + - The `check` command was not setting `oo_.dr.eigval` unless `stoch_simul` was also used - Computation of conditional forecast when the constraint is only on one period was buggy - - Estimation with `mode_compute=3' was crashing under Octave + - Estimation with `mode_compute=3` was crashing under Octave Announcement for Dynare 4.3.1 (on 2012-10-10) @@ -1673,8 +2076,7 @@ We are pleased to announce the release of Dynare 4.3.1. This release adds a few minor features and fixes various bugs. The Windows and Mac packages are already available for download at: - - http://www.dynare.org/download/dynare-stable +. The GNU/Linux packages (for Debian and Ubuntu) should follow soon. @@ -1688,54 +2090,54 @@ Here is the list of the main user-visible changes: * New features in the user interface: - - New `@#ifndef' directive in the macro-processor - - - Possibility of simultaneously specifying several output formats in the - `graph_format' option - - - Support for XLSX files in `datafile' option of `estimation' and in - `initval_file' - + - New `@#ifndef` directive in the macro-processor + + - Possibility of simultaneously specifying several output formats in the + `graph_format` option + + - Support for XLSX files in `datafile` option of `estimation` and in + `initval_file` + * Bugs and problems identified in version 4.3.0 and that have been fixed in version 4.3.1: - - Shock decomposition was broken - - - The welfare computation with `ramsey_policy' was buggy when used in - conjunction with `histval' - - - Estimation of models with both missing observations and measurement errors - was buggy - - - The option `simul_replic' was broken - - - The macro-processor directive `@#ifdef' was broken - - - Identification with `max_dim_cova_group > 1' was broken for specially - degenerate models (when parameter theta has pairwise collinearity of one - with multiple other parameters, i.e. when all couples (theta,b), (theta,c), - ... (theta,d) have perfect collinearity in the Jacobian of the model) - - - The `parallel_test' option was broken - - - Estimation with correlated shocks was broken when the correlations were - specified in terms of correlation and not in terms of co-variance - - - The Windows package was broken with MATLAB 7.1 and 7.2 - - - When using `mode_compute=0' with a mode file generated using - `mode_compute=6', the value of option `mh_jscale' was not loaded - - - Using exogenous deterministic variables at 2nd order was causing a crash - - - The option `no_create_init' for the `ms_estimation' command was broken - - - Loading of datafiles with explicit filename extensions was not working - - - The preprocessor had a memory corruption problem which could randomly lead - to crashes - + - Shock decomposition was broken + + - The welfare computation with `ramsey_policy` was buggy when used in + conjunction with `histval` + + - Estimation of models with both missing observations and measurement errors + was buggy + + - The option `simul_replic` was broken + + - The macro-processor directive `@#ifdef` was broken + + - Identification with `max_dim_cova_group > 1` was broken for specially + degenerate models (when parameter theta has pairwise collinearity of one + with multiple other parameters, *i.e.* when all couples (θ,b), (θ,c), + … (θ,d) have perfect collinearity in the Jacobian of the model) + + - The `parallel_test` option was broken + + - Estimation with correlated shocks was broken when the correlations were + specified in terms of correlation and not in terms of co-variance + + - The Windows package was broken with MATLAB 7.1 and 7.2 + + - When using `mode_compute=0` with a mode file generated using + `mode_compute=6`, the value of option `mh_jscale` was not loaded + + - Using exogenous deterministic variables at 2nd order was causing a crash + + - The option `no_create_init` for the `ms_estimation` command was broken + + - Loading of datafiles with explicit filename extensions was not working + + - The preprocessor had a memory corruption problem which could randomly lead + to crashes + Announcement for Dynare 4.3.0 (on 2012-06-15) ============================================= @@ -1744,8 +2146,7 @@ We are pleased to announce the release of Dynare 4.3.0. This major release adds new features and fixes various bugs. The Windows and Mac packages are already available for download at: - - http://www.dynare.org/download/dynare-4.3 +. The GNU/Linux packages should follow soon. @@ -1759,190 +2160,190 @@ Here is the list of the main user-visible changes: * New major algorithms: - - Nonlinear estimation with a particle filter based on a second order - approximation of the model, as in Fernández-Villaverde and Rubio-Ramírez - (2005); this is triggered by setting `order=2' in the `estimation' command - - - Extended path solution method as in Fair and Taylor (1983); see the - `extended_path' command - - - Support for Markov-Switching Structural Bayesian VARs (MS-SBVAR) along the - lines of Sims, Waggoner and Zha (2008) (see the dedicated section in the - reference manual) - - - Optimal policy under discretion along the lines of Dennis (2007); see the - `discretionary_policy' command - - - Identification analysis along the lines of Iskrev (2010); see the - `identification' command - - - The Global Sensitivity Analysis toolbox (Ratto, 2008) is now part of the - official Dynare distribution - + - Nonlinear estimation with a particle filter based on a second order + approximation of the model, as in *Fernández-Villaverde and Rubio-Ramirez + (2005)*; this is triggered by setting `order=2` in the `estimation` command + + - Extended path solution method as in *Fair and Taylor (1983)*; see the + `extended_path` command + + - Support for Markov-Switching Structural Bayesian VARs (MS-SBVAR) along the + lines of *Sims, Waggoner and Zha (2008)* (see the dedicated section in the + reference manual) + + - Optimal policy under discretion along the lines of *Dennis (2007)*; see the + `discretionary_policy` command + + - Identification analysis along the lines of *Iskrev (2010)*; see the + `identification` command + + - The Global Sensitivity Analysis toolbox (*Ratto, 2008*) is now part of the + official Dynare distribution + * Other algorithmic improvements: - - Stochastic simulation and estimation can benefit from block decomposition - (with the `block' option of `model'; only at 1st order) - - - Possibility of running smoother and filter on a calibrated model; see the - `calib_smoother' command - - - Possibility of doing conditional forecast on a calibrated model; see the - `parameter_set=calibration' option of the `conditional_forecast' command - - - The default algorithm for deterministic simulations has changed and is now - based on sparse matrices; the historical algorithm (Laffargue, Boucekkine - and Juillard) is still available under the `stack_solve_algo=6'option of the - `simul' command - - - Possibility of using an analytic gradient for the estimation; see the - `analytic_derivation' option of the `estimation' command - - - Implementation of the Nelder-Mead simplex based optimization routine for - computing the posterior mode; available under the `mode_compute=8' option of - the `estimation' command - - - Implementation of the CMA Evolution Strategy algorithm for computing the - posterior mode; available under the `mode_compute=9' option of the - `estimation' command - - - New solvers for Lyapunov equations which can accelerate the estimation of - large models; see the `lyapunov' option of the `estimation' command - - - New solvers for Sylvester equations which can accelerate the resolution of - large models with block decomposition; see the `sylvester' option of the - `stoch_simul' and `estimation' commands - - - The `ramsey_policy' command now displays the planner objective value - function under Ramsey policy and stores it in `oo_.planner_objective_value' - - - Theoretical autocovariances are now computed when the `block' option is - present - - - The `linear' option is now compatible with the `block' and `bytecode' - options - - - The `loglinear' option now works with purely backward or forward models at - first order - + - Stochastic simulation and estimation can benefit from block decomposition + (with the `block` option of `model`; only at 1st order) + + - Possibility of running smoother and filter on a calibrated model; see the + `calib_smoother` command + + - Possibility of doing conditional forecast on a calibrated model; see the + `parameter_set=calibration` option of the `conditional_forecast` command + + - The default algorithm for deterministic simulations has changed and is now + based on sparse matrices; the historical algorithm (*Laffargue, Boucekkine + and Juillard*) is still available under the `stack_solve_algo=6` option of the + `simul` command + + - Possibility of using an analytic gradient for the estimation; see the + `analytic_derivation` option of the `estimation` command + + - Implementation of the Nelder-Mead simplex based optimization routine for + computing the posterior mode; available under the `mode_compute=8` option of + the `estimation` command + + - Implementation of the CMA Evolution Strategy algorithm for computing the + posterior mode; available under the `mode_compute=9` option of the + `estimation` command + + - New solvers for Lyapunov equations which can accelerate the estimation of + large models; see the `lyapunov` option of the `estimation` command + + - New solvers for Sylvester equations which can accelerate the resolution of + large models with block decomposition; see the `sylvester` option of the + `stoch_simul` and `estimation` commands + + - The `ramsey_policy` command now displays the planner objective value + function under Ramsey policy and stores it in `oo_.planner_objective_value` + + - Theoretical autocovariances are now computed when the `block` option is + present + + - The `linear` option is now compatible with the `block` and `bytecode` + options + + - The `loglinear` option now works with purely backward or forward models at + first order + * New features in the user interface: - - New mathematical primitives allowed in model block: `abs()', `sign()' - - - The behavior with respect to graphs has changed: - - + By default, Dynare now displays graphs and saves them to disk in EPS - format only - - + The format can be changed to PDF or FIG with the new `graph_format' - option - - + It is possible to save graphs to disk without displaying them with the - new `nodisplay' option - - - New `nocheck' option to the `steady' command: tells not to check the steady - state and accept values given by the user (useful for models with unit - roots) - - - A series of deterministic shocks can be passed as a pre-defined vector in - the `values' statement of a `shocks' block - - - New option `sub_draws' in the `estimation' command for controlling the - number of draws used in computing the posterior distributions of various - objects - - - New macroprocessor command `@#ifdef' for testing if a macro-variable is - defined - - - New option `irf_shocks' of the `stoch_simul' command, to allow IRFs to be - created only for certain exogenous variables - - - In the parallel engine, possibility of assigning different weights to nodes - in the cluster and of creating clusters comprised of nodes with different - operating systems (see the relevant section in the reference manual) - - - It is now possible to redefine a parameter in the `steady_state_model' block - (use with caution) - - - New option `maxit' in the `simul' and `steady' commands to determine the - maximum number of iterations of the nonlinear solver - - - New option `homotopy_force_continue' in the `steady' command to control the - behavior when a homotopy fails - - - Possibility of globally altering the defaults of options by providing a file - in the `GlobalInitFile' field of the configuration file (use with caution) - - - New option `nolog' to the `dynare' command line to avoid creating a logfile - - - New option `-D' to the `dynare' command line with for defining - macro-variables - + - New mathematical primitives allowed in model block: `abs()`, `sign()` + + - The behavior with respect to graphs has changed: + + + By default, Dynare now displays graphs and saves them to disk in EPS + format only + + + The format can be changed to PDF or FIG with the new `graph_format` + option + + + It is possible to save graphs to disk without displaying them with the + new `nodisplay` option + + - New `nocheck` option to the `steady` command: tells not to check the steady + state and accept values given by the user (useful for models with unit + roots) + + - A series of deterministic shocks can be passed as a pre-defined vector in + the `values` statement of a `shocks` block + + - New option `sub_draws` in the `estimation` command for controlling the + number of draws used in computing the posterior distributions of various + objects + + - New macroprocessor command `@#ifdef` for testing if a macro-variable is + defined + + - New option `irf_shocks` of the `stoch_simul` command, to allow IRFs to be + created only for certain exogenous variables + + - In the parallel engine, possibility of assigning different weights to nodes + in the cluster and of creating clusters comprised of nodes with different + operating systems (see the relevant section in the reference manual) + + - It is now possible to redefine a parameter in the `steady_state_model` block + (use with caution) + + - New option `maxit` in the `simul` and `steady` commands to determine the + maximum number of iterations of the nonlinear solver + + - New option `homotopy_force_continue` in the `steady` command to control the + behavior when a homotopy fails + + - Possibility of globally altering the defaults of options by providing a file + in the `GlobalInitFile` field of the configuration file (use with caution) + + - New option `nolog` to the `dynare` command line to avoid creating a logfile + + - New option `-D` to the `dynare` command line with for defining + macro-variables + * Miscellaneous changes: - - The `use_dll' option of `model' now creates a MEX file for the static model - in addition to that for the dynamic model - - - The `unit_root_vars' command is now obsolete; use the `diffuse_filter' - option of the `estimation' command instead - - - New option `--burn' to Dynare++ to discard initial simulation points - - - New top-level MATLAB/Octave command `internals' for internal documentation - and unitary tests - + - The `use_dll` option of `model` now creates a MEX file for the static model + in addition to that for the dynamic model + + - The `unit_root_vars` command is now obsolete; use the `diffuse_filter` + option of the `estimation` command instead + + - New option `--burn` to Dynare++ to discard initial simulation points + + - New top-level MATLAB/Octave command `internals` for internal documentation + and unitary tests + * Bugs and problems identified in version 4.2.5 and that have been fixed in version 4.3.0: - - Backward models with the `loglinear' option were incorrectly handled - - - Solving for hyperparameters of inverse gamma priors was sometimes crashing - - - The deterministic solver for purely forward models was broken - - - When running `estimation' or `identification' on models with non-diagonal - structural error covariance matrices, while not simultaneously estimating - the correlation between shocks (i.e. calibrating the correlation), the - off-diagonal elements were incorrectly handled or crashes were occuring - - - When using the `prefilter' option, smoother plots were omitting the smoothed - observables - - - In the rare case of entering and expression x as x^(alpha-1) with x being 0 - in steady state and alpha being a parameter equal to 2, the Jacobian was - evaluating to 0 instead of 1 - - - Setting the prior for shock correlations was failing if a lower bound was not - explicitly specified - + - Backward models with the `loglinear` option were incorrectly handled + + - Solving for hyperparameters of inverse gamma priors was sometimes crashing + + - The deterministic solver for purely forward models was broken + + - When running `estimation` or `identification` on models with non-diagonal + structural error covariance matrices, while not simultaneously estimating + the correlation between shocks (*i.e.* calibrating the correlation), the + off-diagonal elements were incorrectly handled or crashes were occuring + + - When using the `prefilter` option, smoother plots were omitting the smoothed + observables + + - In the rare case of entering and expression `x` as `x^(alpha-1)` with `x` being 0 + in steady state and alpha being a parameter equal to 2, the Jacobian was + evaluating to 0 instead of 1 + + - Setting the prior for shock correlations was failing if a lower bound was not + explicitly specified + * References: - - Dennis, Richard (2007): “Optimal Policy In Rational Expectations Models: New - Solution Algorithms,” Macroeconomic Dynamics, 11(1), 31–55 - - - Fair, Ray and John Taylor (1983): “Solution and Maximum Likelihood - Estimation of Dynamic Nonlinear Rational Expectation Models,” Econometrica, - 51, 1169–1185 - - - Fernández-Villaverde, Jesús and Juan Rubio-Ramírez (2005): “Estimating - Dynamic Equilibrium Economies: Linear versus Nonlinear Likelihood,” Journal - of Applied Econometrics, 20, 891–910 - - - Iskrev, Nikolay (2010): “Local identification in DSGE models,” Journal of - Monetary Economics, 57(2), 189–202 - - - Ratto, Marco (2008): “Analysing DSGE models with global sensitivity - analysis'', Computational Economics, 31, 115–139 - - - Sims, Christopher A., Daniel F. Waggoner and Tao Zha (2008): “Methods for - inference in large multiple-equation Markov-switching models,” Journal of - Econometrics, 146, 255–274 - + - Dennis, Richard (2007): “Optimal Policy In Rational Expectations Models: New + Solution Algorithms,” *Macroeconomic Dynamics*, 11(1), 31–55 + + - Fair, Ray and John Taylor (1983): “Solution and Maximum Likelihood + Estimation of Dynamic Nonlinear Rational Expectation Models,” *Econometrica*, + 51, 1169–1185 + + - Fernández-Villaverde, Jesús and Juan Rubio-Ramirez (2005): “Estimating + Dynamic Equilibrium Economies: Linear versus Nonlinear Likelihood,” *Journal + of Applied Econometrics*, 20, 891–910 + + - Iskrev, Nikolay (2010): “Local identification in DSGE models,” *Journal of + Monetary Economics*, 57(2), 189–202 + + - Ratto, Marco (2008): “Analysing DSGE models with global sensitivity + analysis,” *Computational Economics*, 31, 115–139 + + - Sims, Christopher A., Daniel F. Waggoner and Tao Zha (2008): “Methods for + inference in large multiple-equation Markov-switching models,” *Journal of + Econometrics*, 146, 255–274 + Announcement for Dynare 4.2.5 (on 2012-03-14) @@ -1963,8 +2364,7 @@ The new release is compatible with MATLAB versions ranging from 7.0 (R14) to Note that GNU Octave users under Windows will have to upgrade to GNU Octave version 3.6.1 (MinGW). The Octave installer can be downloaded at: - - http://www.dynare.org/octave/Octave3.6.1_gcc4.6.2_20120303-setup.exe +. Here is a non-exhaustive list of the problems identified in version 4.2.4 and that have been fixed in version 4.2.5: @@ -1995,7 +2395,7 @@ This is a bugfix release. It comes only a few days after the previous release, because version 4.2.3 was affected by a critical bug (see below). The Windows package for the new release is already available for download at -the official Dynare website . The Mac and Linux packages +the official [Dynare website](http://www.dynare.org). The Mac and Linux packages should follow soon. All users are strongly encouraged to upgrade, especially those who have @@ -2013,7 +2413,7 @@ fixed in version 4.2.4: * Bayesian priors with inverse gamma distribution and very small variances were giving incorrect results in some cases - * The `model_diagnostics' command was broken + * The `model_diagnostics` command was broken Announcement for Dynare 4.2.3 (on 2011-11-30) @@ -2024,7 +2424,7 @@ We are pleased to announce the release of Dynare 4.2.3. This is a bugfix release. The Windows package is already available for download at the official -Dynare website . The Mac and Linux packages +[Dynare website](http://www.dynare.org). The Mac and Linux packages should follow soon. All users are strongly encouraged to upgrade. @@ -2035,23 +2435,23 @@ to 7.13 (R2011b) and with GNU Octave versions ranging from 3.0 to 3.4. Here is a non-exhaustive list of the problems identified in version 4.2.2 and that have been fixed in version 4.2.3: - * `steady_state_model' was broken for lags higher than 2 + * `steady_state_model` was broken for lags higher than 2 - * `simult_.m' was not working correctly with `order=3' if `k_order_solver' had + * `simult_.m` was not working correctly with `order=3` if `k_order_solver` had not been explicitly specified - * `stoch_simul' with `order=3' and without `periods' option was reporting + * `stoch_simul` with `order=3` and without `periods` option was reporting dummy theoretical moments - * Under Octave, option `solve_algo=0' was causing crashes in `check' and - `stoch_simul' + * Under Octave, option `solve_algo=0` was causing crashes in `check` and + `stoch_simul` * Identification module was broken * The test for singularity in the model reporting eigenvalues close to 0/0 was sometimes reporting false positives - * The `conditional_variance_decomposition' option was not working if one + * The `conditional_variance_decomposition` option was not working if one period index was 0. Now, Dynare reports an error if the periods are not strictly positive. @@ -2067,7 +2467,7 @@ We are pleased to announce the release of Dynare 4.2.2. This is a bugfix release. The Windows package is already available for download at the official -Dynare website . The Mac and Linux packages +[Dynare website](http://www.dynare.org). The Mac and Linux packages should follow soon. All users are strongly encouraged to upgrade. @@ -2088,31 +2488,31 @@ been fixed in version 4.2.2: slightly different in future releases (thanks to Marek Jarociński for spotting this) - * The `conditional_forecast' command was buggy: it was always using the - posterior mode, whatever the value of the `parameter_set' option + * The `conditional_forecast` command was buggy: it was always using the + posterior mode, whatever the value of the `parameter_set` option - * `STEADY_STATE' was not working correctly with certain types of + * `STEADY_STATE` was not working correctly with certain types of expressions (the priority of the addition and substraction operators was incorrectly handled) - * With the `block' option of `model', the preprocessor was failing on - expressions of the form "a^b" (with no endogenous in "a" but an - endogenous in "b") + * With the `block` option of `model`, the preprocessor was failing on + expressions of the form `a^b` (with no endogenous in `a` but an + endogenous in `b`) * Some native MATLAB statements were not correctly passed on to MATLAB - (e.g. x = { 'foo' 'bar' } ) + (*e.g.* `x = { 'foo' 'bar' }` ) - * `external_function' was crashing in some circumstances + * `external_function` was crashing in some circumstances * The lambda parameter for HP filter was restricted to integer values for no good reason - * The `load_mh_file' option of `estimation' was crashing under Octave + * The `load_mh_file` option of `estimation` was crashing under Octave for Windows (MinGW version) * Computation of steady state was failing on model contains auxiliary variables created by leads or lags larger than 2 or by of the - `EXPECTATION' operator + `EXPECTATION` operator * Compilation of MEX files for MATLAB was failing with GCC 4.6 @@ -2128,7 +2528,7 @@ places, the structure has been improved, an index of functions and variables has been added, the PDF/HTML rendering has been improved. The Windows package is already available for download at the official -Dynare website [1]. The Mac and Linux packages should follow soon. +[Dynare website](http://www.dynare.org). The Mac and Linux packages should follow soon. All users are strongly encouraged to upgrade. @@ -2137,20 +2537,20 @@ to 7.12 (R2011a) and with GNU Octave versions ranging from 3.0 to 3.4. Here is a list of the main bugfixes since version 4.2.0: - * The `STEADY_STATE' operator has been fixed + * The `STEADY_STATE` operator has been fixed * Problems with MATLAB 7.3 (R2006b) and older have been fixed - * The `partial_information' option of `stoch_simul' has been fixed + * The `partial_information` option of `stoch_simul` has been fixed - * Option `conditional_variance_decomposition' of `stoch_simul' and - `estimation' has been fixed + * Option `conditional_variance_decomposition` of `stoch_simul` and + `estimation` has been fixed - * Automatic detrending now works in conjunction with the `EXPECTATION' + * Automatic detrending now works in conjunction with the `EXPECTATION` operator - * Percentage signs inside strings in MATLAB statements (like disp('% - This is not a comment %')) now work + * Percentage signs inside strings in MATLAB statements (like `disp('% + This is not a comment %')`) now work * Beta prior with a very small standard deviation now work even if you do not have the MATLAB Statistical toolbox @@ -2158,15 +2558,13 @@ Here is a list of the main bugfixes since version 4.2.0: * External functions can now been used in assignment of model local variables - * `identification' command has been fixed + * `identification` command has been fixed - * Option `cova_compute' of `estimation' command has been fixed + * Option `cova_compute` of `estimation` command has been fixed - * Random crashes with 3rd order approximation without `use_dll' option + * Random crashes with 3rd order approximation without `use_dll` option have been eliminated -[1] http://www.dynare.org - Announcement for Dynare 4.2.0 (on 2011-02-15) ============================================= @@ -2188,38 +2586,44 @@ Here is the list of major user-visible changes: * New solution algorithms: - - Pruning for second order simulations has been added, as described in Kim, - Kim, Schaumburg and Sims (2008) [1,2] + - Pruning for second order simulations has been added, as described in *Kim, + Kim, Schaumburg and Sims (2008)*. It is triggered by option `pruning` of + `stoch_simul` (only 2nd order, not available at 3rd order). - - Models under partial information can be solved, as in Pearlman, Currie and - Levine (1986) [3,4] + - Models under partial information can be solved, as in *Pearlman, Currie and + Levine (1986)*. See . - New nonlinear solvers for faster deterministic simulations and steady state - computation [5] + computation. See + . * Dynare can now use the power of multi-core computers or of a cluster of - computer using parallelization [6] + computer using parallelization. See + . * New features in the user interface: - A steady state file can now be automatically generated, provided that the model can be solved analytically, and that the steady state as a function - of the parameters is declared with the new "steady_state_model" command [7] + of the parameters is declared with the new `steady_state_model` command. + See the entry for `steady_state_model` in the reference manual for more + details and an example. - For non-stationary models, Dynare is now able of automatically removing trends in all the equations: the user writes the equations in non-stationary form and declares the deflator of each variable. Then Dynare perform a check to determine if the proposed deflators are compatible with - balanced growth path, and, if yes, then it computes the detrended equations - [8] + balanced growth path, and, if yes, then it computes the detrended + equations. See . - - It is now possible to use arbitrary functions in the model block [9] + - It is now possible to use arbitrary functions in the model block. See + . * Other minor changes to the user interface: - - New primitives allowed in model block: normpdf(), erf() + - New primitives allowed in model block: `normpdf()`, `erf()` - - New syntax for DSGE-VAR [10] + - New syntax for DSGE-VAR. See . - Syntax of deterministic shocks has changed: after the values keyword, arbitrary expressions must be enclosed within parentheses (but numeric @@ -2227,60 +2631,53 @@ Here is the list of major user-visible changes: * Various improvements: - - Third order simulations now work without the "USE_DLL" option: + - Third order simulations now work without the `use_dll` option: installing a C++ compiler is no longer necessary for 3rd order - The HP filter works for empirical moments (previously it was only available for theoretical moments) - - "ramsey_policy" now displays the planner objective value function under - Ramsey policy and stores it in "oo_.planner_objective_value" + - `ramsey_policy` now displays the planner objective value function under + Ramsey policy and stores it in `oo_.planner_objective_value` - - Estimation: if the "selected_variables_only" option is present, then the + - Estimation: if the `selected_variables_only` option is present, then the smoother will only be run on variables listed just after the estimation command - - Estimation: in the "shocks" block, it is now possible to calibrate + - Estimation: in the `shocks` block, it is now possible to calibrate measurement errors on endogenous variables (using the same keywords than for calibrating variance/covariance matrix of exogenous shocks) - - It is possibile to choose the parameter set for shock decomposition [11] + - It is possibile to choose the parameter set for shock decomposition. See + . - The diffuse filter now works under Octave - - New option "console" on the Dynare command-line: use it when running Dynare + - New option `console` on the Dynare command-line: use it when running Dynare from the console, it will replace graphical waitbars by text waitbars for long computations - - Steady option "solve_algo=0" (uses fsolve()) now works under Octave + - Steady option `solve_algo=0` (uses `fsolve()`) now works under Octave * For Emacs users: - - New Dynare mode for Emacs editor (contributed by Yannick Kalantzis) + - New Dynare mode for Emacs editor (contributed by Yannick Kalantzis) - - Reference manual now available in Info format (distributed with - Debian/Ubuntu packages) + - Reference manual now available in Info format (distributed with + Debian/Ubuntu packages) * Miscellaneous: - - Deterministic models: leads and lags of two or more on endogenous - variables are now substituted by auxiliary variables; exogenous variables - are left as is [12] + - Deterministic models: leads and lags of two or more on endogenous + variables are now substituted by auxiliary variables; exogenous variables + are left as is. See . -[1] Kim, J., S. Kim, E. Schaumburg and C.A. Sims (2008), "Calculating and using +* References: + + - Kim, J., S. Kim, E. Schaumburg and C.A. Sims (2008), “Calculating and using second-order accurate solutions of discrete time dynamic equilibrium - models", Journal of Economic Dynamics and Control, 32(11), 3397-3414 -[2] It is triggered by option "pruning" of "stoch_simul" (only 2nd order, not - available at 3rd order) -[3] Pearlman J., D. Currie and P. Levine (1986), "Rational expectations models - with partial information", Economic Modelling, 3(2), 90-105 -[4] http://www.dynare.org/DynareWiki/PartialInformation -[5] http://www.dynare.org/DynareWiki/FastDeterministicSimulationAndSteadyStateComputation -[6] http://www.dynare.org/DynareWiki/ParallelDynare -[7] See the entry for "steady_state_model" in the reference manual for more - details and an example -[8] http://www.dynare.org/DynareWiki/RemovingTrends -[9] http://www.dynare.org/DynareWiki/ExternalFunctions -[10] http://www.dynare.org/DynareWiki/DsgeVar -[11] http://www.dynare.org/DynareWiki/ShockDecomposition -[12] http://www.dynare.org/DynareWiki/AuxiliaryVariables + models,” *Journal of Economic Dynamics and Control*, 32(11), 3397-3414 + + - Pearlman J., D. Currie and P. Levine (1986), “Rational expectations models + with partial information,” *Economic Modelling*, 3(2), 90-105 + diff --git a/README.md b/README.md index be34df871..c575d0564 100644 --- a/README.md +++ b/README.md @@ -234,7 +234,7 @@ All the prerequisites are packaged: - `texlive-fonts-extra` (for ccicons) - `texlive-latex-recommended` - `texlive-science` (for amstex) -- `texlive-generic-extra` (for Sphinx) +- `texlive-plain-generic` - `lmodern` (for macroprocessor PDF) - `python3-sphinx` - `latexmk` @@ -243,7 +243,7 @@ All the prerequisites are packaged: You can install them all at once with: ``` -apt install build-essential gfortran liboctave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex bison autoconf automake texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-latex-recommended texlive-science texlive-generic-extra lmodern python3-sphinx latexmk libjs-mathjax doxygen +apt install build-essential gfortran liboctave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex bison autoconf automake texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-latex-recommended texlive-science texlive-plain-generic lmodern python3-sphinx latexmk libjs-mathjax doxygen ``` ## Windows @@ -262,30 +262,32 @@ pacman -Syu ``` pacman -S git autoconf automake-wrapper bison flex make tar texinfo mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-x86_64-boost mingw-w64-x86_64-gsl mingw-w64-x86_64-matio mingw-w64-x86_64-openblas ``` -- **(Optional)** compile and install SLICOT, needed for the `kalman_steady_state` - MEX file +- Compile and install SLICOT, needed for the `kalman_steady_state` MEX file ``` wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz tar xf slicot_5.0+20101122.orig.tar.gz cd slicot-5.0+20101122 -make FORTRAN=gfortran OPTS="-O2 -fno-underscoring -fdefault-integer-8" LOADER=gfortran slicot.a +make FORTRAN=gfortran OPTS="-O2 -fno-underscoring -fdefault-integer-8" LOADER=gfortran lib mkdir -p /usr/local/lib cp slicot.a /usr/local/lib/libslicot64_pic.a cd .. ``` -- Clone and prepare the Dynare sources: +- Prepare the Dynare sources, either by unpacking the source tarball, or with: ``` git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git cd dynare autoreconf -si ``` -- Configure Dynare: +- Configure Dynare from the source directory: ``` -./configure --with-slicot=/usr/local --with-matlab=<…> MATLAB_VERSION=<…> --disable-octave +./configure --with-slicot=/usr/local --with-matlab=<…> MATLAB_VERSION=<…> --disable-octave --disable-doc ``` where the path and version of MATLAB are specified. Note that you should use the MSYS2 notation and not put spaces in the MATLAB path, so you probably want -to use something like `/c/Progra~1/MATLAB/…`. +to use something like `/c/Progra~1/MATLAB/…`. Alternatively, if your filesystem +does not have short filenames (8dot3), then you can run `mkdir -p +/usr/local/MATLAB && mount c:/Program\ Files/MATLAB /usr/local/MATLAB`, and +then pass `/usr/local/MATLAB/…` as MATLAB path to the configure script. - Compile: ``` make diff --git a/configure.ac b/configure.ac index 4c5d6b61d..3c8ccb939 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with Dynare. If not, see . AC_PREREQ([2.62]) -AC_INIT([dynare], [4.6-unstable]) +AC_INIT([dynare], [4.7-unstable]) AC_CONFIG_SRCDIR([preprocessor/src/DynareMain.cc]) AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax]) diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am index 11af152b0..ae0a57214 100644 --- a/doc/manual/Makefile.am +++ b/doc/manual/Makefile.am @@ -16,3 +16,4 @@ build/latex/dynare-manual.pdf: $(SRC) source/conf.py clean-local: rm -rf build + rm -rf utils/__pycache__ diff --git a/doc/manual/source/bibliography.rst b/doc/manual/source/bibliography.rst index db154cd02..a8442cbca 100644 --- a/doc/manual/source/bibliography.rst +++ b/doc/manual/source/bibliography.rst @@ -44,6 +44,7 @@ Bibliography * Kim, Jinill and Sunghyun Kim (2003): “Spurious welfare reversals in international business cycle models,” *Journal of International Economics*, 60, 471–500. * Kanzow, Christian and Stefania Petra (2004): “On a semismooth least squares formulation of complementarity problems with gap reduction,” *Optimization Methods and Software*, 19, 507–525. * Kim, Jinill, Sunghyun Kim, Ernst Schaumburg, and Christopher A. Sims (2008): “Calculating and using second-order accurate solutions of discrete time dynamic equilibrium models,” *Journal of Economic Dynamics and Control*, 32(11), 3397–3414. +* Komunjer, Ivana and Ng, Serena (2011): ”Dynamic identification of dynamic stochastic general equilibrium models”, *Econometrica*, 79, 1995–2032. * Koop, Gary (2003), *Bayesian Econometrics*, John Wiley & Sons. * Koopman, S. J. and J. Durbin (2000): “Fast Filtering and Smoothing for Multivariate State Space Models,” *Journal of Time Series Analysis*, 21(3), 281–296. * Koopman, S. J. and J. Durbin (2003): “Filtering and Smoothing of State Vector for Diffuse State Space Models,” *Journal of Time Series Analysis*, 24(1), 85–98. @@ -52,13 +53,16 @@ Bibliography * Liu, Jane and Mike West (2001): “Combined parameter and state estimation in simulation-based filtering”, in *Sequential Monte Carlo Methods in Practice*, Eds. Doucet, Freitas and Gordon, Springer Verlag. * Lubik, Thomas and Frank Schorfheide (2007): “Do Central Banks Respond to Exchange Rate Movements? A Structural Investigation,” *Journal of Monetary Economics*, 54(4), 1069–1087. * Murray, Lawrence M., Emlyn M. Jones and John Parslow (2013): “On Disturbance State-Space Models and the Particle Marginal Metropolis-Hastings Sampler”, *SIAM/ASA Journal on Uncertainty Quantification*, 1, 494–521. +* Mutschler, Willi (2015): “Identification of DSGE models - The effect of higher-order approximation and pruning“, *Journal of Economic Dynamics & Control*, 56, 34-54. * Pearlman, Joseph, David Currie, and Paul Levine (1986): “Rational expectations models with partial information,” *Economic Modelling*, 3(2), 90–105. * Planas, Christophe, Marco Ratto and Alessandro Rossi (2015): “Slice sampling in Bayesian estimation of DSGE models”. * Pfeifer, Johannes (2013): “A Guide to Specifying Observation Equations for the Estimation of DSGE Models”. * Pfeifer, Johannes (2014): “An Introduction to Graphs in Dynare”. +* Qu, Zhongjun and Tkachenko, Denis (2012): “Identification and frequency domain quasi-maximum likelihood estimation of linearized dynamic stochastic general equilibrium models“, *Quantitative Economics*, 3, 95–132. * Rabanal, Pau and Juan Rubio-Ramirez (2003): “Comparing New Keynesian Models of the Business Cycle: A Bayesian Approach,” Federal Reserve of Atlanta, *Working Paper Series*, 2003-30. * Raftery, Adrian E. and Steven Lewis (1992): “How many iterations in the Gibbs sampler?,” in *Bayesian Statistics, Vol. 4*, ed. J.O. Berger, J.M. Bernardo, A.P. * Dawid, and A.F.M. Smith, Clarendon Press: Oxford, pp. 763-773. * Ratto, Marco (2008): “Analysing DSGE models with global sensitivity analysis”, *Computational Economics*, 31, 115–139. +* Ratto, Marco and Iskrev, Nikolay (2011): “Identification Analysis of DSGE Models with DYNARE.“, *MONFISPOL* 225149. * Schorfheide, Frank (2000): “Loss Function-based evaluation of DSGE models,” *Journal of Applied Econometrics*, 15(6), 645–670. * Schmitt-Grohé, Stephanie and Martin Uríbe (2004): “Solving Dynamic General Equilibrium Models Using a Second-Order Approximation to the Policy Function,” *Journal of Economic Dynamics and Control*, 28(4), 755–775. * Schnabel, Robert B. and Elizabeth Eskow (1990): “A new modified Cholesky algorithm,” *SIAM Journal of Scientific and Statistical Computing*, 11, 1136–1158. @@ -68,6 +72,3 @@ Bibliography * Stock, James H. and Mark W. Watson (1999). “Forecasting Inflation,”, *Journal of Monetary Economics*, 44(2), 293–335. * Uhlig, Harald (2001): “A Toolkit for Analysing Nonlinear Dynamic Stochastic Models Easily,” in *Computational Methods for the Study of Dynamic Economies*, Eds. Ramon Marimon and Andrew Scott, Oxford University Press, 30–61. * Villemot, Sébastien (2011): “Solving rational expectations models at first order: what Dynare does,” *Dynare Working Papers*, 2, CEPREMAP. - - - diff --git a/doc/manual/source/conf.py b/doc/manual/source/conf.py index 209136329..308bc58ba 100644 --- a/doc/manual/source/conf.py +++ b/doc/manual/source/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright (C) 2018-2019 Dynare Team +# Copyright (C) 2018-2020 Dynare Team # # This file is part of Dynare. # @@ -23,7 +23,7 @@ import sys sys.path.insert(0, os.path.abspath('../utils')) extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.mathjax'] + 'sphinx.ext.mathjax'] source_suffix = '.rst' @@ -36,7 +36,7 @@ mathjax_path = 'mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML' master_doc = 'index' project = u'Dynare' -copyright = u'2019, Dynare Team' +copyright = u'2020, Dynare Team' author = u'Dynare Team' add_function_parentheses = False @@ -77,6 +77,7 @@ latex_elements = { warningBorderColor={RGB}{255,50,50},OuterLinkColor={RGB}{34,139,34}, \ InnerLinkColor={RGB}{51,51,255},TitleColor={RGB}{51,51,255}', 'papersize': 'a4paper', + 'preamble': r'\DeclareUnicodeCharacter{200B}{}', # Part of the workaround for #1707 } latex_documents = [ diff --git a/doc/manual/source/dynare-misc-commands.rst b/doc/manual/source/dynare-misc-commands.rst index 6a0af6eed..91311da9f 100644 --- a/doc/manual/source/dynare-misc-commands.rst +++ b/doc/manual/source/dynare-misc-commands.rst @@ -167,24 +167,26 @@ Dynare misc commands A ``1*Nblck`` array of doubles. Current acceptance ratios. -.. matcomm:: prior [options[, ...]]; +.. matcomm:: prior [OPTIONS[, ...]]; - Prints various informations about the prior distribution depending - on the options. If no options are provided, the command returns - the list of available options. Following options are available: + Prints information about the prior distribution given the provided + options. If no options are provided, the command returns the list of + available options. - ``table`` + *Options* + + .. option:: table Prints a table describing the marginal prior distributions (mean, mode, std., lower and upper bounds, HPD interval). - ``moments`` + .. option:: moments Computes and displays first and second order moments of the endogenous variables at the prior mode (considering the linearized version of the model). - ``moments(distribution)`` + .. option:: moments(distribution) Computes and displays the prior mean and prior standard deviation of the first and second moments of the endogenous @@ -193,7 +195,7 @@ Dynare misc commands stored in the ``prior`` subfolder in a ``_endogenous_variables_prior_draws.mat`` file. - ``optimize`` + .. option:: optimize Optimizes the prior density (starting from a random initial guess). The parameters such that the steady state does not @@ -203,7 +205,7 @@ Dynare misc commands defined over such regions, the optimization algorithm may fail to converge to the true solution (the prior mode). - ``simulate`` + .. option:: simulate Computes the effective prior mass using a Monte-Carlo. Ideally the effective prior mass should be equal to 1, otherwise @@ -215,6 +217,6 @@ Dynare misc commands :math:`p_A\neq p_B \leq 1` so that the prior mass of the compared models are identical. - ``plot`` + .. option:: plot Plots the marginal prior density. diff --git a/doc/manual/source/examples.rst b/doc/manual/source/examples.rst index 53838e533..457086877 100644 --- a/doc/manual/source/examples.rst +++ b/doc/manual/source/examples.rst @@ -56,3 +56,9 @@ description, please refer to the comments inside the files themselves. Baseline New Keynesian Model estimated in *Fernández-Villaverde (2010)*. It demonstrates how to use an explicit steady state file to update parameters and call a numerical solver. + +``Ramsey_Example.mod`` + + File demonstrating how to conduct optimal policy experiments in a + simple New Keynesian model either under commitment (Ramsey) or using + optimal simple rules (OSR) \ No newline at end of file diff --git a/doc/manual/source/index.rst b/doc/manual/source/index.rst index 98a280fef..2df8469ff 100644 --- a/doc/manual/source/index.rst +++ b/doc/manual/source/index.rst @@ -25,7 +25,7 @@ The following people used to be members of the team: * Stéphane Lhuissier * George Perendia -Copyright © 1996-2019, Dynare Team. +Copyright © 1996-2020, Dynare Team. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. @@ -34,7 +34,7 @@ A copy of the license can be found at `http://www.gnu.org/licenses/fdl.txt `__. Then install Octave, issuing the command ``brew -install octave`` at the Terminal prompt. You can then install the -latest stable version of Dynare by typing ``brew install dynare`` at -the Terminal prompt. You can also pass options to the installation -command. These options can be viewed by typing ``brew info dynare`` at -the Terminal prompt. +By default, the installer installs a version of GCC (for use with :opt:`use_dll`) +in the installation directory, under the ``.brew`` folder. To do so, it also +installs a version of `Homebrew `__ in the same folder and +Xcode Command Line Tools (this is an Apple product) in a system folder. + +All of this requires a bit of time and hard disk space. The amount of time it +takes will depend on your computing power and internet connection. To reduce +the time the Dynare installer takes, you can install Xcode Command Line Tools +yourself (see :ref:`prerequisites-macos`). Dynare, Homebrew, and GCC use +about 600 MB of disk space while the Xcode Command Line Tools require about 400 +MB. + +If you do not use the :opt:`use_dll` option, you have the choice to forgo the +installation of GCC and hence Dynare will only take about 50 MB of disk space. + +Dynare for Octave works with Octave installed via the package located here: +`https://octave-app.org `__. For other systems @@ -140,14 +149,17 @@ Users of Octave under GNU/Linux should install the package for MEX file compilation (under Debian, Ubuntu or Linux Mint, it can be done via ``apt install liboctave-dev``). +.. _prerequisites-macos: + Prerequisites on macOS ---------------------- Dynare now ships a compilation environment that can be used with the -:opt:`use_dll` option. Specifically, the Dynare installer downloads and -installs the Xcode Command Line Tools, installs `Homebrew `_ -under the Dynare installation directory (in the ``.brew`` folder), and finally -installs GCC. +:opt:`use_dll` option. To install this environment correctly, the Dynare +installer ensures that the Xcode Command Line Tools (an Apple product) have +been installed on a system folder. To install the Xcode Command Line Tools +yourself, simply type ``xcode-select --install`` into the Terminal +(``/Applications/Utilities/Terminal.app``) prompt. Configuration ============= @@ -209,10 +221,10 @@ command; the packaging does it for you. Under Arch Linux, you need to do:: octave:1> addpath /usr/lib/dynare/matlab -Under macOS, assuming that you have installed Dynare and Octave via -Homebrew, type:: +Under macOS, assuming you have installed Octave via `https://octave-app.org +`__, type:: - octave:1> addpath /usr/local/opt/dynare/lib/dynare/matlab + octave:1> addpath /Applications/Dynare/4.x.y/matlab If you don’t want to type this command every time you run Octave, you can put it in a file called ``.octaverc`` in your home directory diff --git a/doc/manual/source/introduction.rst b/doc/manual/source/introduction.rst index 0560d5c2f..962882356 100644 --- a/doc/manual/source/introduction.rst +++ b/doc/manual/source/introduction.rst @@ -55,7 +55,7 @@ manual. Part of Dynare is programmed in C++, while the rest is written using the `MATLAB`_ programming language. The latter implies that commercially-available MATLAB software is required in order to run Dynare. However, as an alternative to MATLAB, Dynare is also able to -run on top of `Octave`_ (basically a free clone of MATLAB): this +run on top of `GNU Octave`_ (basically a free clone of MATLAB): this possibility is particularly interesting for students or institutions who cannot afford, or do not want to pay for, MATLAB and are willing to bear the concomitant performance loss. @@ -104,10 +104,10 @@ For convenience, you can copy and paste the following into your BibTeX file: .. code-block:: bibtex @TechReport{Adjemianetal2011, - author = {Adjemian, St\'ephane and Bastani, Houtan and - Juillard, Michel and Karam\'e, Fr\'ederic and + author = {Adjemian, St\'ephane and Bastani, Houtan and + Juillard, Michel and Karam\'e, Fr\'ederic and Maih, Junior and Mihoubi, Ferhat and - Perendia, George and Pfeifer, Johannes and + Perendia, George and Pfeifer, Johannes and Ratto, Marco and Villemot, S\'ebastien}, title = {Dynare: Reference Manual Version 4}, year = {2011}, @@ -122,7 +122,7 @@ https://www.dynare.org. .. _MATLAB: https://www.mathworks.com/products/matlab/ -.. _Octave: https://www.octave.org/ +.. _GNU Octave: https://www.octave.org/ .. _CEPREMAP: https://www.cepremap.fr/ .. _web forum: https://forum.dynare.org/ .. _official Dynare website: https://www.dynare.org/ diff --git a/doc/manual/source/running-dynare.rst b/doc/manual/source/running-dynare.rst index 209d935a6..cb8270463 100644 --- a/doc/manual/source/running-dynare.rst +++ b/doc/manual/source/running-dynare.rst @@ -104,6 +104,23 @@ by the ``dynare`` command. Octave, it also means that the ``.mod`` file cannot be named ``test.mod`` or ``example.mod``. + .. _quote-note: + + .. note:: + Note on Quotes + + When passing command line options that contains a space (or, under + Octave, a double quote), you must surround the entire option (keyword + and argument) with single quotes, as in the following example. + + *Example* + + Call Dynare with options containing spaces + + .. code-block:: matlab + + >> dynare <> '-DA=[ i in [1,2,3] when i > 1 ]' 'conffile=C:\User\My Documents\config.txt' + *Options* .. option:: noclearall @@ -140,10 +157,11 @@ by the ``dynare`` command. .. option:: savemacro[=FILENAME] - Instructs ``dynare`` to save the intermediary file which is - obtained after macro processing (see :ref:`macro-proc-lang`); - the saved output will go in the file specified, or if no file - is specified in ``FILENAME-macroexp.mod`` + Instructs ``dynare`` to save the intermediary file which is obtained + after macro processing (see :ref:`macro-proc-lang`); the saved output + will go in the file specified, or if no file is specified in + ``FILENAME-macroexp.mod``. See the :ref:`note on quotes` + for info on passing a ``FILENAME`` argument containing spaces. .. option:: onlymacro @@ -152,19 +170,12 @@ by the ``dynare`` command. debugging purposes or for using the macro processor independently of the rest of Dynare toolbox. - .. option:: nolinemacro + .. option:: linemacro - Instructs the macro preprocessor to omit line numbering - information in the intermediary ``.mod`` file created after - the macro processing step. Useful in conjunction with - :opt:`savemacro ` when one wants that to reuse the intermediary - ``.mod`` file, without having it cluttered by line numbering - directives. - - .. option:: noemptylinemacro - - Passing this option removes all empty from the macro expanded - mod file created when the :opt:`savemacro ` option is used. + Instructs the macro preprocessor include ``@#line`` directives + specifying the line on which macro directives were encountered and + expanded from. Only useful in conjunction with :opt:`savemacro + `. .. option:: onlymodel @@ -305,9 +316,10 @@ by the ``dynare`` command. .. option:: matlabroot=<> - The path to the MATLAB installation for use with - :opt:`use_dll`. Dynare is able to set this automatically, - so you should not need to set it yourself. + The path to the MATLAB installation for use with :opt:`use_dll`. Dynare + is able to set this automatically, so you should not need to set it + yourself. See the :ref:`note on quotes` for info on + passing a ``<>`` argument containing spaces. .. option:: parallel[=CLUSTER_NAME] @@ -320,9 +332,11 @@ by the ``dynare`` command. .. option:: conffile=FILENAME - Specifies the location of the configuration file if it differs - from the default. See :ref:`conf-file`, for more information - about the configuration file and its default location. + Specifies the location of the configuration file if it differs from the + default. See :ref:`conf-file`, for more information about the + configuration file and its default location. See the :ref:`note on + quotes` for info on passing a ``FILENAME`` argument + containing spaces. .. option:: parallel_slave_open_mode @@ -338,18 +352,30 @@ by the ``dynare`` command. .. option:: -DMACRO_VARIABLE=MACRO_EXPRESSION - Defines a macro-variable from the command line (the same - effect as using the Macro directive ``@#define`` in a model - file, see :ref:`macro-proc-lang`). + Defines a macro-variable from the command line (the same effect as + using the Macro directive ``@#define`` in a model file, see + :ref:`macro-proc-lang`). See the :ref:`note on quotes` for + info on passing a ``MACRO_EXPRESSION`` argument containing spaces. Note + that an expression passed on the command line can reference variables + defined before it. + + *Example* + + Call dynare with command line defines + + .. code-block:: matlab + + >> dynare <> -DA=true '-DB="A string with space"' -DC=[1,2,3] '-DD=[ i in C when i > 1 ]' .. option:: -I<> - Defines a path to search for files to be included by the - macro processor (using the ``@#include`` command). Multiple - ``-I`` flags can be passed on the command line. The paths will - be searched in the order that the ``-I`` flags are passed and - the first matching file will be used. The flags passed here - take priority over those passed to ``@#includepath``. + Defines a path to search for files to be included by the macro + processor (using the ``@#include`` command). Multiple ``-I`` flags can + be passed on the command line. The paths will be searched in the order + that the ``-I`` flags are passed and the first matching file will be + used. The flags passed here take priority over those passed to + ``@#includepath``. See the :ref:`note on quotes` for info + on passing a ``<>`` argument containing spaces. .. option:: nostrict @@ -475,13 +501,14 @@ by the ``dynare`` command. after the name of the ``.mod`` file. They can alternatively be defined in the first line of the ``.mod`` file, this avoids typing them on the command line each time a ``.mod`` file is to be - run. This line must be a Dynare comment (ie must begin with //) - and the options must be comma separated between ``--+`` options: + run. This line must be a Dynare one-line comment (i.e. must begin with ``//``) + and the options must be whitespace separated between ``--+ options:`` and ``+--``. Note that any text after the ``+--`` will be discarded. As in the command line, if an option admits a value the equal symbol must not be surrounded by spaces. For instance ``json = compute`` is not correct, and should be written - ``json=compute``. + ``json=compute``. The ``nopathchange`` option cannot be specified in + this way, it must be passed on the command-line. *Output* diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst index 9f91c1edc..4808c2009 100644 --- a/doc/manual/source/the-model-file.rst +++ b/doc/manual/source/the-model-file.rst @@ -815,6 +815,19 @@ The parameter names are stored in ``M_.param_names``: Cell array containing the names of the model parameters. +.. matcomm:: get_param_by_name ('PARAMETER_NAME'); + + Given the name of a parameter, returns its calibrated value as it is + stored in ``M_.params``. + +.. matcomm:: set_param_value ('PARAMETER_NAME', MATLAB_EXPRESSION); + + Sets the calibrated value of a parameter to the provided expression. + This does essentially the same as the parameter initialization syntax + described above, except that it accepts arbitrary MATLAB/Octave expressions, + and that it works from MATLAB/Octave scripts. + + .. _model-decl: Model declaration @@ -1487,7 +1500,9 @@ in this case ``initval`` is used to specify the terminal conditions. steady; - simul(periods=200); + perfect_foresight_setup(periods=200); + perfect_foresight_solver; + In this example, the problem is finding the optimal path for consumption and capital for the periods :math:`t=1` to @@ -1527,7 +1542,9 @@ in this case ``initval`` is used to specify the terminal conditions. x = 1.1; end; - simul(periods=200); + perfect_foresight_setup(periods=200); + perfect_foresight_solver; + In this example, there is no `steady` command, hence the conditions are exactly those specified in the `initval` and `endval` blocks. @@ -1709,7 +1726,7 @@ in this case ``initval`` is used to specify the terminal conditions. objective function of the planner is computed. Note that the initial values of the Lagrange multipliers associated with the planner’s problem cannot be set (see - :ref:`planner_objective_value `). + :comm:`evaluate_planner_objective`). *Options* @@ -2029,6 +2046,17 @@ blocks. is strongly discouraged**. You should use a ``shocks`` block instead. +.. matcomm:: get_shock_stderr_by_name ('EXOGENOUS_NAME'); + + |br| Given the name of an exogenous variable, returns its standard + deviation, as set by a previous ``shocks`` block. + +.. matcomm:: set_shock_stderr_value ('EXOGENOUS_NAME', MATLAB_EXPRESSION); + + |br| Sets the standard deviation of an exgonous variable. This does + essentially the same as setting the standard error via a ``shocks`` block, + except that it accepts arbitrary MATLAB/Octave expressions, and that it + works from MATLAB/Octave scripts. Other general declarations ========================== @@ -2286,6 +2314,11 @@ After computation, the steady state is available in the following variable: ordered in the order of declaration used in the ``var`` command (which is also the order used in ``M_.endo_names``). +.. matcomm:: get_mean ('ENDOGENOUS_NAME' [, 'ENDOGENOUS_NAME']... ); + + Returns the steady of state of the given endogenous variable(s), as it is + stored in ``oo_.steady_state``. Note that, if the steady state has not yet + been computed with ``steady``, it will first try to compute it. .. block:: homotopy_setup ; @@ -2522,7 +2555,7 @@ Getting information about the model =================================== .. command:: check ; - check (solve_algo = INTEGER); + check (OPTIONS...); |br| Computes the eigenvalues of the model linearized around the values specified by the last ``initval``, ``endval`` or ``steady`` @@ -2718,10 +2751,8 @@ speed-up on large models. .. option:: datafile = FILENAME - If the variables of the model are not constant over time, their - initial values, stored in a text file, could be loaded, using - that option, as initial values before a deterministic - simulation. + Used to specify path for all endogenous and exogenous variables. + Strictly equivalent to :comm:`initval_file`. *Output* @@ -3089,13 +3120,6 @@ Computing the stochastic solution moments. This option is only available with simulated moments. Default: no filter. - .. option:: hp_ngrid = INTEGER - - Number of points in the grid for the discrete Inverse Fast - Fourier Transform used in the HP filter computation. It may be - necessary to increase it for highly autocorrelated - processes. Default: ``512``. - .. option:: bandpass_filter Uses a bandpass filter with the default passband before @@ -3111,6 +3135,14 @@ Computing the stochastic solution e.g. :math:`6` to :math:`32` quarters if the model frequency is quarterly. Default: ``[6,32]``. + .. option:: filtered_theoretical_moments_grid = INTEGER + + When computing filtered theoretical moments (with either option + ``hp_filter`` or option ``bandpass_filter``), this option governs the + number of points in the grid for the discrete Inverse Fast Fourier + Transform. It may be necessary to increase it for highly autocorrelated + processes. Default: ``512``. + .. option:: irf = INTEGER Number of periods on which to compute the IRFs. Setting @@ -3437,6 +3469,10 @@ Computing the stochastic solution stored in ´´oo_.SpectralDensity´´, defined below. Default: do not request spectral density estimates. + .. option:: hp_ngrid = INTEGER + + Deprecated option. It has the same effect as + :opt:`filtered_theoretical_moments_grid `. *Output* @@ -3655,6 +3691,11 @@ Computing the stochastic solution For example, ``oo_.irfs.gnp_ea`` contains the effect on ``gnp`` of a one-standard deviation shock on ``ea``. +.. matcomm:: get_irf ('EXOGENOUS_NAME' [, 'ENDOGENOUS_NAME']... ); + + |br| Given the name of an exogenous variables, returns the IRFs for the + requested endogenous variable(s), as they are stored in ``oo_.irfs``. + The approximated solution of a model takes the form of a set of decision rules or transition equations expressing the current value of the endogenous variables of the model as function of the previous @@ -3760,7 +3801,7 @@ lag. We therefore have the following identity: Vector of numerical indices identifying the state variables in the vector of declared variables. ``M_.endo_names(M_.state_var)`` - therefore yields the name of all variables that are states in + therefore yields the name of all variables that are states in the model declaration, i.e. that show up with a lag. Internally, Dynare uses two orderings of the endogenous variables: the @@ -3778,10 +3819,10 @@ according to the declaration order. .. matvar:: oo_.dr.order_var This variables maps DR-order to declaration order. - + .. matvar:: oo_.dr.inv_order_var - This variable contains the inverse map. + This variable contains the inverse map. In other words, the k-th variable in the DR-order corresponds to the endogenous variable numbered ``oo_.dr.order_var(k)`` in declaration @@ -3811,7 +3852,7 @@ where :math:`y^s` is the steady state value of :math:`y` and .. matvar:: oo.dr.state_var Vector of numerical indices identifying the state variables in the - vector of declared variables, *given the current parameter values* + vector of declared variables, *given the current parameter values* for which the decision rules have been computed. It may differ from ``M_.state_var`` in case a state variable drops from the model given the current parameterization, because it only gets 0 coefficients in @@ -4619,7 +4660,8 @@ block decomposition of the model (see :opt:`block`). Note also that for the Random Walk Metropolis Hastings algorithm, it is possible to use option :opt:`mh_tune_jscale `, to automatically tune the value - of ``mh_jscale``. + of ``mh_jscale``. In this case, the ``mh_jscale`` option must + not be used. .. option:: mh_init_scale = DOUBLE @@ -4656,7 +4698,15 @@ block decomposition of the model (see :opt:`block`). stochastic nature of the algorithm (the proposals and the initial conditions of the markov chains if ``mh_nblocks>1``). This option is only available for the - Random Walk Metropolis Hastings algorithm. + Random Walk Metropolis Hastings algorithm. Must not be used in conjunction with + :opt:`mh_jscale = DOUBLE`. + + .. option:: mh_tune_guess = DOUBLE + + Specifies the initial value for the :opt:`mh_tune_jscale + ` option. Default: ``0.2``. Must not + be set if :opt:`mh_tune_jscale ` is + not used. .. option:: mh_recover @@ -4784,7 +4834,8 @@ block decomposition of the model (see :opt:`block`). state variables and estimated jointly with the original state variables of the model using a nonlinear filter. The algorithm implemented in Dynare - is described in *Liu and West (2001)*. + is described in *Liu and West (2001)*, and works with + ``k`` order local approximations of the model. ``12`` @@ -4855,10 +4906,8 @@ block decomposition of the model (see :opt:`block`). the computed mode for each estimated parameter in turn. This is helpful to diagnose problems with the optimizer. Note that for ``order>1`` the likelihood function resulting from the particle - filter is not differentiable anymore due to random chatter - introduced by selecting different particles for different - parameter values. For this reason, the ``mode_check`` plot may - look wiggly. + filter is not differentiable anymore due to the resampling + step. For this reason, the ``mode_check`` plot may look wiggly. .. option:: mode_check_neighbourhood_size = DOUBLE @@ -5770,12 +5819,12 @@ block decomposition of the model (see :opt:`block`). .. option:: order = INTEGER - Order of approximation, either ``1`` or ``2``. When equal to - ``2``, the likelihood is evaluated with a particle filter based - on a second order approximation of the model (see - *Fernandez-Villaverde and Rubio-Ramirez (2005)*). Default is - ``1``, i.e. the likelihood of the linearized model is evaluated - using a standard Kalman filter. + Order of approximation around the deterministic steady + state. When greater than 1, the likelihood is evaluated with a + particle or nonlinear filter (see *Fernandez-Villaverde and + Rubio-Ramirez (2005)*). Default is ``1``, i.e. the likelihood + of the linearized model is evaluated using a standard Kalman + filter. .. option:: irf = INTEGER @@ -6401,6 +6450,12 @@ block decomposition of the model (see :opt:`block`). oo_.SmoothedVariables.MOMENT_NAME.VARIABLE_NAME + .. matcomm:: get_smooth ('VARIABLE_NAME' [, 'VARIABLE_NAME']...); + + Returns the smoothed values of the given endogenous or exogenous + variable(s), as they are stored in the ``oo_.SmoothedVariables`` + and ``oo_.SmoothedShocks`` variables. + .. matvar:: oo_.UpdatedVariables Variable set by the ``estimation`` command (if used with the @@ -6417,6 +6472,10 @@ block decomposition of the model (see :opt:`block`). oo_.UpdatedVariables.MOMENT_NAME.VARIABLE_NAME + .. matcomm:: get_update ('VARIABLE_NAME' [, 'VARIABLE_NAME']...); + + Returns the updated values of the given variable(s), as they are stored + in the ``oo_.UpdatedVariables`` variable. .. matvar:: oo_.FilterCovariance @@ -6968,17 +7027,43 @@ Shock Decomposition See :opt:`nobs `. + .. option:: prefilter = INTEGER + + See :opt:`prefilter `. + + .. option:: loglinear + + See :opt:`loglinear `. + + .. option:: diffuse_kalman_tol = DOUBLE + + See :opt:`diffuse_kalman_tol `. + + .. option:: diffuse_filter + + See :opt:`diffuse_filter `. + + .. option:: xls_sheet = NAME + + See :opt:`xls_sheet `. + + .. option:: xls_range = RANGE + + See :opt:`xls_range `. + .. option:: use_shock_groups [= STRING] Uses shock grouping defined by the string instead of individual shocks in the decomposition. The groups of shocks are defined in the :bck:`shock_groups` block. - .. option:: colormap = STRING + .. option:: colormap = VARIABLE_NAME - Controls the ``colormap`` used for the shocks decomposition - graphs. See colormap in MATLAB/Octave manual for valid - arguments. + Controls the ``colormap`` used for the shocks decomposition graphs. + VARIABLE_NAME must be the name of a MATLAB/Octave variable that has + been declared beforehand and whose value will be passed to the + MATLAB/Octave ``colormap`` function (see the MATLAB/Octave manual for + the list of acceptable values). .. option:: nograph @@ -6995,6 +7080,11 @@ Shock Decomposition ``1``, the shock decomposition is computed conditional on the smoothed state variables in period 1. Default: ``0``. + .. option:: with_epilogue + + If set, then also compute the decomposition for variables declared in + the ``epilogue`` block (see :ref:`epilogue`). + *Output* .. matvar:: oo_.shock_decomposition @@ -7117,9 +7207,9 @@ Shock Decomposition See :opt:`use_shock_groups `. - .. option:: colormap = STRING + .. option:: colormap = VARIABLE_NAME - See :opt:`colormap `. + See :opt:`colormap `. .. option:: nograph @@ -7152,6 +7242,10 @@ Shock Decomposition integer defines the last observation (equivalent to :opt:`nobs`). Default: not enabled. + .. option:: with_epilogue + + See :opt:`with_epilogue`. + *Output* .. matvar:: oo_.realtime_shock_decomposition @@ -7256,9 +7350,9 @@ Shock Decomposition See :opt:`use_shock_groups `. - .. option:: colormap = STRING + .. option:: colormap = VARIABLE_NAME - See :opt:`colormap `. + See :opt:`colormap `. .. option:: nodisplay @@ -7367,6 +7461,206 @@ Shock Decomposition Default: ``0``. + .. option:: plot_init_date = DATE + + If passed, plots decomposition using ``plot_init_date`` as initial period. + Default: first observation in estimation + + .. option:: plot_end_date = DATE + + If passed, plots decomposition using ``plot_end_date`` as last period. + Default: last observation in estimation + + .. option:: diff + + If passed, plot the decomposition of the first difference of the list of variables. + If used in combination with :opt:`flip`, the ``diff`` operator is first applied. + Default: not activated + + .. option:: flip + + If passed, plot the decomposition of the opposite of the list of variables. + If used in combination with :opt:`diff`, the ``diff`` operator is first applied. + Default: not activated + + .. option:: max_nrows + + Maximum number of rows in the subplot layout of detailed shock + decomposition graphs. Note that columns are always 3. Default: 6 + + .. option:: with_epilogue + + See :opt:`with_epilogue`. + + .. option:: init2shocks + init2shocks = NAME + + Use the information contained in an :bck:`init2shocks` block, in order + to attribute initial conditions to shocks. The name of the block can be + explicitly given, otherwise it defaults to the ``default`` block. + + +.. block:: init2shocks ; + init2shocks (OPTIONS...); + + |br| This blocks gives the possibility of attributing the initial condition + of endogenous variables to the contribution of exogenous variables in the + shock decomposition. + + For example, in an AR(1) process, the contribution of the initial condition + on the process variable can naturally be assigned to the innovation of the + process. + + Each line of the block should have the syntax:: + + VARIABLE_1 [,] VARIABLE_2; + + Where VARIABLE_1 is an endogenous variable whose initial condition + will be attributed to the exogenous VARIABLE_2. + + The information contained in this block is used by the + :comm:`plot_shock_decomposition` command when given the ``init2shocks`` + option. + + *Options* + + .. option:: name = NAME + + Specifies a name for the block, that can be referenced from + ``plot_shock_decomposition``, so that several such blocks can coexist + in a single model file. If the name is unspecified, it defaults to + ``default``. + + *Example* + + :: + + var y y_s R pie dq pie_s de A y_obs pie_obs R_obs; + varexo e_R e_q e_ys e_pies e_A; + ... + + model; + dq = rho_q*dq(-1)+e_q; + A = rho_A*A(-1)+e_A; + ... + end; + + ... + + init2shocks; + dq e_q; + A e_A; + end; + + shock_decomposition(nograph); + + plot_shock_decomposition(init2shocks) y_obs R_obs pie_obs dq de; + + In this example, the initial conditions of ``dq`` and ``A`` will + be respectively attributed to ``e_q`` and ``e_A``. + + +.. command:: initial_condition_decomposition [VARIABLE_NAME]...; + initial_condition_decomposition (OPTIONS...) [VARIABLE_NAME]...; + + |br| This command computes and plots the decomposition of the effect of + smoothed initial conditions of state variables. The ``variable_names`` provided + govern which variables the decomposition is plotted for. + + Further note that, unlike the majority of Dynare commands, the + options specified below are overwritten with their defaults before + every call to ``initial_condition_decomposition``. Hence, if you want to + reuse an option in a subsequent call to + ``initial_condition_decomposition``, you must pass it to the command + again. + + *Options* + + .. option:: colormap = VARIABLE_NAME + + See :opt:`colormap `. + + .. option:: nodisplay + + See :opt:`nodisplay`. + + .. option:: graph_format = FORMAT + graph_format = ( FORMAT, FORMAT... ) + + See :opt:`graph_format `. + + .. option:: detail_plot + + Plots shock contributions using subplots, one per shock (or + group of shocks). Default: not activated + + .. option:: steadystate + + If passed, the the :math:`y`-axis value of the zero line in + the shock decomposition plot is translated to the steady state + level. Default: not activated + + .. option:: type = qoq | yoy | aoa + + For quarterly data, valid arguments are: ``qoq`` for + quarter-on-quarter plots, ``yoy`` for year-on-year plots of + growth rates, ``aoa`` for annualized variables, i.e. the value + in the last quarter for each year is plotted. Default value: + empty, i.e. standard period-on-period plots (``qoq`` for + quarterly data). + + .. option:: fig_name = STRING + + Specifies a user-defined keyword to be appended to the default + figure name set by ``plot_shock_decomposition``. This can + avoid to overwrite plots in case of sequential calls to + ``plot_shock_decomposition``. + + .. option:: write_xls + + Saves shock decompositions to Excel-file in the main + directory, named + ``FILENAME_shock_decomposition_TYPE_FIG_NAME_initval.xls``. This + option requires your system to be configured to be able to + write Excel files. [#f7]_ + + .. option:: plot_init_date = DATE + + If passed, plots decomposition using ``plot_init_date`` as initial period. + Default: first observation in estimation + + .. option:: plot_end_date = DATE + + If passed, plots decomposition using ``plot_end_date`` as last period. + Default: last observation in estimation + + .. option:: diff + + If passed, plot the decomposition of the first difference of the list of variables. + If used in combination with :opt:`flip`, the ``diff`` operator is first applied. + Default: not activated + + .. option:: flip + + If passed, plot the decomposition of the opposite of the list of variables. + If used in combination with :opt:`diff`, the ``diff`` operator is first applied. + Default: not activated + +.. command:: squeeze_shock_decomposition [VARIABLE_NAME]...; + + |br| For large models, the size of the information stored by shock + decompositions (especially various settings of realtime decompositions) may + become huge. This command allows to squeeze this information in two + possible ways: + + * Automatic (default): only the variables for which plotting has been + explicitly required with ``plot_shock_decomposition`` will have their + decomposition left in ``oo_`` after this command is run; + + * If a list of variables is passed to the command, then only those + variables will have their decomposition left in ``oo_`` after this + command is run. + Calibrated Smoother =================== @@ -7384,7 +7678,7 @@ Dynare can also run the smoother on a calibrated model: approximation of the model. By default, the command computes the smoothed variables and shocks - and stores the results in ``oo_.SmoothedVariables` and + and stores the results in ``oo_.SmoothedVariables`` and ``oo_.SmoothedShocks``. It also fills ``oo_.UpdatedVariables``. *Options* @@ -7431,6 +7725,14 @@ Dynare can also run the smoother on a calibrated model: See :opt:`diffuse_kalman_tol `. + .. option:: xls_sheet = NAME + + See :opt:`xls_sheet `. + + .. option:: xls_range = RANGE + + See :opt:`xls_range `. + .. _fore: Forecasting @@ -7849,7 +8151,7 @@ The forecast scenario can contain some simple shocks on the exogenous variables. This shocks are described using the function ``basic_plan``: -.. matcomm:: HANDLE = basic_plan (HANDLE, 'VAR_NAME', 'SHOCK_TYPE', DATES, MATLAB VECTOR OF DOUBLE | [DOUBLE | EXPR [DOUBLE | | EXPR] ] ); +.. matcomm:: HANDLE = basic_plan (HANDLE, `VAR_NAME', `SHOCK_TYPE', DATES, MATLAB VECTOR OF DOUBLE | [DOUBLE | EXPR [DOUBLE | EXPR] ] ); Adds to the forecast scenario a shock on the exogenous variable indicated between quotes in the second argument. The shock type @@ -7867,7 +8169,7 @@ compatible with the constrained path are in this case computed. In other words, a conditional forecast is performed. This kind of shock is described with the function ``flip_plan``: -.. matcomm:: HANDLE = flip_plan (HANDLE, 'VAR_NAME, 'VAR_NAME', 'SHOCK_TYPE', DATES, MATLAB VECTOR OF DOUBLE | [DOUBLE | EXPR [DOUBLE | | EXPR] ] ); +.. matcomm:: HANDLE = flip_plan (HANDLE, `VAR_NAME', `VAR_NAME', `SHOCK_TYPE', DATES, MATLAB VECTOR OF DOUBLE | [DOUBLE | EXPR [DOUBLE | EXPR] ] ); Adds to the forecast scenario a constrained path on the endogenous variable specified between quotes in the second argument. The @@ -7924,7 +8226,8 @@ computed with the command ``det_cond_forecast``: plot(dset_forecast.{'r','e'}); -.. command:: smoother2histval [(OPTIONS...)]; +.. command:: smoother2histval ; + smoother2histval(OPTIONS...); The purpose of this command is to construct initial conditions (for a subsequent simulation) that are the smoothed values of a @@ -7997,16 +8300,246 @@ Optimal policy ============== Dynare has tools to compute optimal policies for various types of -objectives. ``ramsey_model`` computes automatically the First Order -Conditions (FOC) of a model, given the ``planner_objective``. You can -then use other standard commands to solve, estimate or simulate this -new, expanded model. - -Alternatively, you can either solve for optimal policy under -commitment with ``ramsey_policy``, for optimal policy under discretion -with ``discretionary_policy`` or for optimal simple rule with ``osr`` +objectives. You can either solve for optimal policy under +commitment with ``ramsey_model``, for optimal policy under discretion +with ``discretionary_policy`` or for optimal simple rules with ``osr`` (also implying commitment). +.. command:: planner_objective MODEL_EXPRESSION ; + + |br| This command declares the policy maker objective, for use + with ``ramsey_model`` or ``discretionary_policy``. + + You need to give the one-period objective, not the discounted + lifetime objective. The discount factor is given by the + ``planner_discount`` option of ``ramsey_model`` and + ``discretionary_policy``. The objective function can only contain + current endogenous variables and no exogenous ones. This + limitation is easily circumvented by defining an appropriate + auxiliary variable in the model. + + With ``ramsey_model``, you are not limited to quadratic + objectives: you can give any arbitrary nonlinear expression. + + With ``discretionary_policy``, the objective function must be quadratic. + +Optimal policy under commitment (Ramsey) +---------------------------------------- + +.. command:: ramsey_model (OPTIONS...); + + |br| This command computes the First Order Conditions for maximizing + the policy maker objective function subject to the constraints + provided by the equilibrium path of the private economy. + + The planner objective must be declared with the :comm:`planner_objective` command. + + This command only creates the expanded model, it doesn’t perform + any computations. It needs to be followed by other instructions to + actually perform desired computations. Examples are calls to ``steady`` + to compute the steady state of the Ramsey economy, to ``stoch_simul`` + with various approximation orders to conduct stochastic simulations based on + perturbation solutions, to ``estimation`` in order to estimate models + under optimal policy with commitment, and to perfect foresight simulation + routines. + + See :ref:`aux-variables`, for an explanation of how Lagrange + multipliers are automatically created. + + *Options* + + This command accepts the following options: + + .. option:: planner_discount = EXPRESSION + + Declares or reassigns the discount factor of the central + planner ``optimal_policy_discount_factor``. Default: ``1.0``. + + .. option:: planner_discount_latex_name = LATEX_NAME + + Sets the LaTeX name of the ``optimal_policy_discount_factor`` + parameter. + + .. option:: instruments = (VARIABLE_NAME,...) + + Declares instrument variables for the computation of the + steady state under optimal policy. Requires a + ``steady_state_model`` block or a ``_steadystate.m`` file. See + below. + + *Steady state* + + Dynare takes advantage of the fact that the Lagrange multipliers + appear linearly in the equations of the steady state of the model + under optimal policy. Nevertheless, it is in general very + difficult to compute the steady state with simply a numerical + guess in ``initval`` for the endogenous variables. + + It greatly facilitates the computation, if the user provides an + analytical solution for the steady state (in + ``steady_state_model`` block or in a ``_steadystate.m`` file). In + this case, it is necessary to provide a steady state solution + CONDITIONAL on the value of the instruments in the optimal policy + problem and declared with the option ``instruments``. The initial value + of the instrument for steady state finding in this case is set with + ``initval``. Note that computing and displaying steady state values + using the ``steady``-command or calls to ``resid`` must come after + the ``ramsey_model`` statement and the ``initval``-block. + + Note that choosing the instruments is partly a matter of interpretation and + you can choose instruments that are handy from a mathematical + point of view but different from the instruments you would refer + to in the analysis of the paper. A typical example is choosing + inflation or nominal interest rate as an instrument. + + +.. block:: ramsey_constraints ; + + |br| This block lets you define constraints on the variables in + the Ramsey problem. The constraints take the form of a variable, + an inequality operator (> or <) and a constant. + + *Example* + + :: + + ramsey_constraints; + i > 0; + end; + +.. command:: evaluate_planner_objective ; + + This command computes, displays, and stores the value of the + planner objective function + under Ramsey policy in ``oo_.planner_objective_value``, given the + initial values of the endogenous state variables. If not specified + with ``histval``, they are taken to be at their steady state + values. The result is a 1 by 2 vector, where the first entry + stores the value of the planner objective when the initial + Lagrange multipliers associated with the planner’s problem are set + to their steady state values (see :comm:`ramsey_policy`). + + In contrast, the second entry stores the value of the planner + objective with initial Lagrange multipliers of the planner’s + problem set to 0, i.e. it is assumed that the planner exploits its + ability to surprise private agents in the first period of + implementing Ramsey policy. This is the value of implementating + optimal policy for the first time and committing not to + re-optimize in the future. + + Because it entails computing at least a second order approximation, the + computation of the planner objective value is skipped with a message when + the model is too large (more than 180 state variables, including lagged + Lagrange multipliers). + +.. command:: ramsey_policy [VARIABLE_NAME...]; + ramsey_policy (OPTIONS...) [VARIABLE_NAME...]; + + |br| This command is formally equivalent to the calling sequence + + :: + + ramsey_model; + stoch_simul(order=1); + evaluate_planner_objective; + + It computes the first order approximation of the + policy that maximizes the policy maker’s objective function + subject to the constraints provided by the equilibrium path of the + private economy and under commitment to this optimal policy. The + Ramsey policy is computed by approximating the equilibrium system + around the perturbation point where the Lagrange multipliers are + at their steady state, i.e. where the Ramsey planner acts as if + the initial multipliers had been set to 0 in the distant past, + giving them time to converge to their steady state + value. Consequently, the optimal decision rules are computed + around this steady state of the endogenous variables and the + Lagrange multipliers. + + This first order approximation to the optimal policy conducted by + Dynare is not to be confused with a naive linear quadratic + approach to optimal policy that can lead to spurious welfare + rankings (see *Kim and Kim (2003)*). In the latter, the optimal + policy would be computed subject to the first order approximated + FOCs of the private economy. In contrast, Dynare first computes + the FOCs of the Ramsey planner’s problem subject to the nonlinear + constraints that are the FOCs of the private economy and only then + approximates these FOCs of planner’s problem to first + order. Thereby, the second order terms that are required for a + second-order correct welfare evaluation are preserved. + + Note that the variables in the list after the ``ramsey_policy`` + command can also contain multiplier names. In that case, Dynare + will for example display the IRFs of the respective multipliers + when ``irf>0``. + + The planner objective must be declared with the :comm:`planner_objective` command. + + *Options* + + This command accepts all options of ``stoch_simul``, plus: + + .. option:: planner_discount = EXPRESSION + + See :opt:`planner_discount `. + + .. option:: instruments = (VARIABLE_NAME,...) + + Declares instrument variables for the computation of the + steady state under optimal policy. Requires a + ``steady_state_model`` block or a ``_steadystate.m`` file. See + below. + + Note that only a first order approximation of the optimal Ramsey + policy is available, leading to a second-order accurate welfare + ranking (i.e. ``order=1`` must be specified). + + *Output* + + This command generates all the output variables of + ``stoch_simul``. For specifying the initial values for the + endogenous state variables (except for the Lagrange multipliers), + see :bck:`histval`. + + + *Steady state* + + See :comm:`Ramsey steady state `. + +Optimal policy under discretion +------------------------------- + +.. command:: discretionary_policy [VARIABLE_NAME...]; + discretionary_policy (OPTIONS...) [VARIABLE_NAME...]; + + |br| This command computes an approximation of the optimal policy + under discretion. The algorithm implemented is essentially an LQ + solver, and is described by *Dennis (2007)*. + + You should ensure that your model is linear and your objective is + quadratic. Also, you should set the ``linear`` option of the + ``model`` block. + + It is possible to use the :comm:`estimation` command after the + ``discretionary_policy`` command, in order to estimate the model with + optimal policy under discretion. + + *Options* + + This command accepts the same options as ``ramsey_policy``, plus: + + .. option:: discretionary_tol = NON-NEGATIVE DOUBLE + + Sets the tolerance level used to assess convergence of the + solution algorithm. Default: ``1e-7``. + + .. option:: maxit = INTEGER + + Maximum number of iterations. Default: ``3000``. + +Optimal Simple Rules (OSR) +-------------------------- + .. command:: osr [VARIABLE_NAME...]; osr (OPTIONS...) [VARIABLE_NAME...]; @@ -8257,213 +8790,6 @@ with ``discretionary_policy`` or for optimal simple rule with ``osr`` ``M_.endo_names``. -.. command:: ramsey_model (OPTIONS...); - - |br| This command computes the First Order Conditions for maximizing - the policy maker objective function subject to the constraints - provided by the equilibrium path of the private economy. - - The planner objective must be declared with the - ``planner_objective`` command. - - This command only creates the expanded model, it doesn’t perform - any computations. It needs to be followed by other instructions to - actually perform desired computations. Note that it is the only - way to perform perfect foresight simulation of the Ramsey policy - problem. - - See :ref:`aux-variables`, for an explanation of how Lagrange - multipliers are automatically created. - - *Options* - - This command accepts the following options: - - .. option:: planner_discount = EXPRESSION - - Declares or reassigns the discount factor of the central - planner ``optimal_policy_discount_factor``. Default: ``1.0``. - - .. option:: instruments = (VARIABLE_NAME,...) - - Declares instrument variables for the computation of the - steady state under optimal policy. Requires a - ``steady_state_model`` block or a ``_steadystate.m`` file. See - below. - - *Steady state* - - Dynare takes advantage of the fact that the Lagrange multipliers - appear linearly in the equations of the steady state of the model - under optimal policy. Nevertheless, it is in general very - difficult to compute the steady state with simply a numerical - guess in ``initval`` for the endogenous variables. - - It greatly facilitates the computation, if the user provides an - analytical solution for the steady state (in - ``steady_state_model`` block or in a ``_steadystate.m`` file). In - this case, it is necessary to provide a steady state solution - CONDITIONAL on the value of the instruments in the optimal policy - problem and declared with option ``instruments``. Note that - choosing the instruments is partly a matter of interpretation and - you can choose instruments that are handy from a mathematical - point of view but different from the instruments you would refer - to in the analysis of the paper. A typical example is choosing - inflation or nominal interest rate as an instrument. - - -.. block:: ramsey_constraints ; - - |br| This block lets you define constraints on the variables in - the Ramsey problem. The constraints take the form of a variable, - an inequality operator (> or <) and a constant. - - *Example* - - :: - - ramsey_constraints; - i > 0; - end; - - -.. command:: ramsey_policy [VARIABLE_NAME...]; - ramsey_policy (OPTIONS...) [VARIABLE_NAME...]; - - |br| This command computes the first order approximation of the - policy that maximizes the policy maker’s objective function - subject to the constraints provided by the equilibrium path of the - private economy and under commitment to this optimal policy. The - Ramsey policy is computed by approximating the equilibrium system - around the perturbation point where the Lagrange multipliers are - at their steady state, i.e. where the Ramsey planner acts as if - the initial multipliers had been set to 0 in the distant past, - giving them time to converge to their steady state - value. Consequently, the optimal decision rules are computed - around this steady state of the endogenous variables and the - Lagrange multipliers. - - This first order approximation to the optimal policy conducted by - Dynare is not to be confused with a naive linear quadratic - approach to optimal policy that can lead to spurious welfare - rankings (see *Kim and Kim (2003)*). In the latter, the optimal - policy would be computed subject to the first order approximated - FOCs of the private economy. In contrast, Dynare first computes - the FOCs of the Ramsey planner’s problem subject to the nonlinear - constraints that are the FOCs of the private economy and only then - approximates these FOCs of planner’s problem to first - order. Thereby, the second order terms that are required for a - second-order correct welfare evaluation are preserved. - - Note that the variables in the list after the ``ramsey_policy`` - command can also contain multiplier names. In that case, Dynare - will for example display the IRFs of the respective multipliers - when ``irf>0``. - - The planner objective must be declared with the planner_objective command. - - See :ref:`aux-variables`, for an explanation of how this operator - is handled internally and how this affects the output. - - *Options* - - This command accepts all options of ``stoch_simul``, plus: - - .. option:: planner_discount = EXPRESSION - - See :opt:`planner_discount `. - - .. option:: instruments = (VARIABLE_NAME,...) - - Declares instrument variables for the computation of the - steady state under optimal policy. Requires a - ``steady_state_model`` block or a ``_steadystate.m`` file. See - below. - - Note that only a first order approximation of the optimal Ramsey - policy is available, leading to a second-order accurate welfare - ranking (i.e. ``order=1`` must be specified). - - *Output* - - This command generates all the output variables of - ``stoch_simul``. For specifying the initial values for the - endogenous state variables (except for the Lagrange multipliers), - see :bck:`histval`. - - .. _plan-obj: - - In addition, it stores the value of planner objective function - under Ramsey policy in ``oo_.planner_objective_value``, given the - initial values of the endogenous state variables. If not specified - with ``histval``, they are taken to be at their steady state - values. The result is a 1 by 2 vector, where the first entry - stores the value of the planner objective when the initial - Lagrange multipliers associated with the planner’s problem are set - to their steady state values (see :comm:`ramsey_policy`). - - In contrast, the second entry stores the value of the planner - objective with initial Lagrange multipliers of the planner’s - problem set to 0, i.e. it is assumed that the planner exploits its - ability to surprise private agents in the first period of - implementing Ramsey policy. This is the value of implementating - optimal policy for the first time and committing not to - re-optimize in the future. - - Because it entails computing at least a second order approximation, the - computation of the planner objective value is skipped with a message when - the model is too large (more than 180 state variables, including lagged - Lagrange multipliers). - - *Steady state* - - See :comm:`Ramsey steady state `. - - -.. command:: discretionary_policy [VARIABLE_NAME...]; - discretionary_policy (OPTIONS...) [VARIABLE_NAME...]; - - |br| This command computes an approximation of the optimal policy - under discretion. The algorithm implemented is essentially an LQ - solver, and is described by *Dennis (2007)*. - - You should ensure that your model is linear and your objective is - quadratic. Also, you should set the ``linear`` option of the - ``model`` block. - - *Options* - - This command accepts the same options than ``ramsey_policy``, plus: - - .. option:: discretionary_tol = NON-NEGATIVE DOUBLE - - Sets the tolerance level used to assess convergence of the - solution algorithm. Default: ``1e-7``. - - .. option:: maxit = INTEGER - - Maximum number of iterations. Default: ``3000``. - - -.. command:: planner_objective MODEL_EXPRESSION ; - - |br| This command declares the policy maker objective, for use - with ``ramsey_policy`` or ``discretionary_policy``. - - You need to give the one-period objective, not the discounted - lifetime objective. The discount factor is given by the - ``planner_discount`` option of ``ramsey_policy`` and - ``discretionary_policy``. The objective function can only contain - current endogenous variables and no exogenous ones. This - limitation is easily circumvented by defining an appropriate - auxiliary variable in the model. - - With ``ramsey_policy``, you are not limited to quadratic - objectives: you can give any arbitrary nonlinear expression. - - With ``discretionary_policy``, the objective function must be quadratic. - - Sensitivity and identification analysis ======================================= @@ -8880,14 +9206,27 @@ Performing identification analysis * reduced-form solution and linear rational expectation model as in *Ratto and Iskrev (2011)* - 2. Identification strength analysis based on sample information matrix as in - *Ratto and Iskrev (2011)* + Note that for orders 2 and 3, all identification checks are based on the pruned + state space system as in *Mutschler (2015)*. That is, theoretical moments and + spectrum are computed from the pruned ABCD-system, whereas the minimal system + criteria is based on the first-order system, but augmented by the theoretical + (pruned) mean at order 2 or 3. + + 2. Identification strength analysis based on (theoretical or simulated) curvature of + moment information matrix as in *Ratto and Iskrev (2011)* 3. Parameter checks based on nullspace and multicorrelation coefficients to determine which (combinations of) parameters are involved *General Options* + .. option:: order = 1|2|3 + + Order of approximation. At orders 2 and 3 identification is based on the + pruned state space system. Note that the order set in other functions does + not overwrite the default. + Default: ``1``. + .. option:: parameter_set = OPTION See :opt:`parameter_set ` for @@ -8927,7 +9266,7 @@ Performing identification analysis triggers gsa prior sample. If equal to ``2``, triggers gsa Monte-Carlo sample (i.e. loads a sample corresponding to ``pprior=0`` and ``ppost=0`` in the ``dynare_sensitivity`` - options). If equal to ``FILENAME`` uses the provided path to + options). If equal to ``FILENAME`` uses the provided path to a specific user defined sample file. Default: ``0``. @@ -8945,13 +9284,15 @@ Performing identification analysis * ``0``: efficient sylvester equation method to compute analytical derivatives * ``1``: kronecker products method to compute analytical - derivatives + derivatives (only at order=1) * ``-1``: numerical two-sided finite difference method - to compute all identification Jacobians + to compute all identification Jacobians (numerical tolerance + level is equal to ``options_.dynatol.x``) * ``-2``: numerical two-sided finite difference method to compute derivatives of steady state and dynamic model numerically, the identification Jacobians are - then computed analytically + then computed analytically (numerical tolerance + level is equal to ``options_.dynatol.x``) Default: ``0``. @@ -9022,7 +9363,7 @@ Performing identification analysis .. option:: no_identification_spectrum Disables computations of identification check based on - Qu and Tkachenko (2012)'s G, i.e. Gram matrix of derivatives of + *Qu and Tkachenko (2012)*'s G, i.e. Gram matrix of derivatives of first moment plus outer product of derivatives of spectral density. .. option:: grid_nbr = INTEGER @@ -9036,7 +9377,7 @@ Performing identification analysis .. option:: no_identification_minimal Disables computations of identification check based on - Komunjer and Ng (2011)'s D, i.e. minimal state space system + *Komunjer and Ng (2011)*'s D, i.e. minimal state space system and observational equivalent spectral density transformations. *Misc Options* @@ -9083,8 +9424,8 @@ Performing identification analysis If equal to ``1``: finds problematic parameters in a bruteforce fashion: It computes the rank of the Jacobians for all possible parameter combinations. If the rank condition is not fullfilled, - these parameter sets are flagged as non-identifiable. - The maximum dimension of the group searched is triggered by + these parameter sets are flagged as non-identifiable. + The maximum dimension of the group searched is triggered by ``max_dim_subsets_groups``. Default: ``0``. @@ -10318,6 +10659,48 @@ below. See :opt:`regimes`. +.. _epilogue: + +Epilogue Variables +================== + +.. block:: epilogue ; + +The epilogue block is useful for computing output variables of interest that +may not be necessarily defined in the model (e.g. various kinds of real/nominal +shares or relative prices, or annualized variables out of a quarterly model). + +It can also provide several advantages in terms of computational efficiency and +flexibility: + +- You can calculate variables in the epilogue block after smoothers/simulations + have already been run without adding the new definitions and equations and + rerunning smoothers/simulations. Even posterior smoother subdraws can be + recycled for computing epilogue variables without rerunning subdraws with the + new definitions and equations. + +- You can also reduce the state space dimension in data + filtering/smoothing. Assume, for example, you want annualized variables as + outputs. If you define an annual growth rate in a quarterly model, you need + lags up to order 7 of the associated quarterly variable; in a medium/large + scale model this would just blow up the state dimension and increase by a + huge amount the computing time of a smoother. + +The ``epilogue`` block is terminated by ``end;`` and contains lines of the +form: + + NAME = EXPRESSION; + +*Example* + :: + + epilogue; + // annualized level of y + ya = exp(y)+exp(y(-1))+exp(y(-2))+exp(y(-3)); + // annualized growth rate of y + gya = ya/ya(-4)-1; + end; + Displaying and saving results ============================= @@ -10334,20 +10717,20 @@ Dynare has comments to plot the results of a simulation and to save the results. .. command:: dynatype (FILENAME) [VARIABLE_NAME...]; - |br| This command prints the listed variables in a text file named + |br| This command prints the listed endogenous or exogenous variables in a text file named FILENAME. If no VARIABLE_NAME is listed, all endogenous variables are printed. .. command:: dynasave (FILENAME) [VARIABLE_NAME...]; - |br| This command saves the listed variables in a binary file - named FILENAME. If no VARIABLE_NAME are listed, all endogenous + |br| This command saves the listed endogenous or exogenous variables in a binary file + named FILENAME. If no VARIABLE_NAME is listed, all endogenous variables are saved. - In MATLAB or Octave, variables saved with the ``dynasave command`` + In MATLAB or Octave, variables saved with the ``dynasave`` command can be retrieved by the command:: - load -mat FILENAME + load(FILENAME,'-mat') .. _macro-proc-lang: @@ -10481,6 +10864,8 @@ The following operators can be used on arrays: * Comparison operators: ``==, !=`` * Dereferencing: if ``v`` is an array, then ``v[2]`` is its 2nd element * Concatenation of two arrays: ``+`` + * Set union of two arrays: ``|`` + * Set intersection of two arrays: ``&`` * Difference ``-``: returns the first operand from which the elements of the second operand have been removed. * Cartesian product of two arrays: ``*`` @@ -10662,7 +11047,8 @@ Macro directives -.. macrodir:: @#define MACRO_VARIABLE = MACRO_EXPRESSION +.. macrodir:: @#define MACRO_VARIABLE + @#define MACRO_VARIABLE = MACRO_EXPRESSION @#define MACRO_FUNCTION = MACRO_EXPRESSION |br| Defines a macro-variable or macro function. @@ -10671,6 +11057,7 @@ Macro directives :: + @#define var // Equals 1 @#define x = 5 // Real @#define y = "US" // String @#define v = [ 1, 2, 4 ] // Real array @@ -10706,8 +11093,8 @@ Macro directives @#ifdef MACRO_VARIABLE @#ifndef MACRO_VARIABLE @#elseif MACRO_EXPRESSION - @#else - @#endif + @#else ​ + @#endif ​ |br| Conditional inclusion of some part of the ``.mod`` file. The lines between ``@#if``, ``@#ifdef``, or ``@#ifndef`` and the next ``@#elseif``, @@ -10795,7 +11182,7 @@ Macro directives @#for MACRO_VARIABLE in MACRO_EXPRESSION when MACRO_EXPRESSION @#for MACRO_TUPLE in MACRO_EXPRESSION @#for MACRO_TUPLE in MACRO_EXPRESSION when MACRO_EXPRESSION - @#endfor + @#endfor ​ |br| Loop construction for replicating portions of the ``.mod`` file. Note that this construct can enclose variable/parameters @@ -10868,7 +11255,7 @@ Macro directives |br| Asks the preprocessor to display some error message on standard output and to abort. The argument must evaluate to a string. -.. macrodir:: @#echomacrovars +.. macrodir:: @#echomacrovars ​ @#echomacrovars MACRO_VARIABLE_LIST @#echomacrovars(save) MACRO_VARIABLE_LIST diff --git a/doc/manual/source/time-series.rst b/doc/manual/source/time-series.rst index bb9ef1a69..f7dd8d484 100644 --- a/doc/manual/source/time-series.rst +++ b/doc/manual/source/time-series.rst @@ -24,12 +24,11 @@ Dates in a mod file ------------------- Dynare understands dates in a mod file. Users can declare annual, -quarterly, monthly or weekly dates using the following syntax:: +quarterly, or monthly dates using the following syntax:: 1990Y 1990Q3 1990M11 - 1990W49 Behind the scene, Dynare’s preprocessor translates these expressions into instantiations of the MATLAB/Octave’s class ``dates`` described @@ -165,14 +164,13 @@ The dates class .. class:: dates - :arg int freq: equal to 1, 4, 12 or 52 (resp. for annual, - quarterly, monthly or weekly dates). + :arg int freq: equal to 1, 4, or 12 (resp. for annual, + quarterly, or monthly dates). :arg int ndat: the number of declared dates in the object. :arg int time: a ``ndat*2`` array, the years are stored in the first column, the subperiods (1 for annual dates, - 1-4 for quarterly dates, 1-12 for monthly dates and - 1-52 for weekly dates) are stored in the second - column. + 1-4 for quarterly dates, and 1-12 for monthly + dates) are stored in the second column. Each member is private, one can display the content of a member but cannot change its value directly. Note that it is not possible @@ -187,14 +185,14 @@ The dates class |br| Returns an empty ``dates`` object with a given frequency (if the constructor is called with one input argument). ``FREQ`` is a character equal to ’Y’ or ’A’ for - annual dates, ’Q’ for quarterly dates, ’M’ for monthly dates - or ’W’ for weekly dates. Note that ``FREQ`` is not case - sensitive, so that, for instance, ’q’ is also allowed for - quarterly dates. The frequency can also be set with an integer - scalar equal to 1 (annual), 4 (quarterly), 12 (monthly) or 52 - (weekly). The instantiation of empty objects can be used to - rename the ``dates`` class. For instance, if one only works - with quarterly dates, object ``qq`` can be created as:: + annual dates, ’Q’ for quarterly dates, or ’M’ for monthly + dates. Note that ``FREQ`` is not case sensitive, so that, for + instance, ’q’ is also allowed for quarterly dates. The + frequency can also be set with an integer scalar equal to 1 + (annual), 4 (quarterly), or 12 (monthly). The instantiation of + empty objects can be used to rename the ``dates`` class. For + instance, if one only works with quarterly dates, object + ``qq`` can be created as:: qq = dates('Q') @@ -213,11 +211,11 @@ The dates class given by the string ``STRING``. This string has to be interpretable as a date (only strings of the following forms are admitted: ``'1990Y'``, ``'1990A'``, ``'1990Q1'``, - ``'1990M2'``, ``'1990W5'``), the routine ``isdate`` can be - used to test if a string is interpretable as a date. If more - than one argument is provided, they should all be dates - represented as strings, the resulting ``dates`` object - contains as many elements as arguments to the constructor. + ``'1990M2'``), the routine ``isdate`` can be used to test if a + string is interpretable as a date. If more than one argument + is provided, they should all be dates represented as strings, + the resulting ``dates`` object contains as many elements as + arguments to the constructor. .. construct:: dates(DATES) @@ -233,13 +231,13 @@ The dates class .. construct:: dates (FREQ, YEAR, SUBPERIOD) - |br| where ``FREQ`` is a single character (’Y’, ’A’, ’Q’, ’M’, - ’W’) or integer (1, 4, 12 or 52) specifying the frequency, - ``YEAR`` and ``SUBPERIOD`` are ``n*1`` vectors of - integers. Returns a ``dates`` object with ``n`` elements. If - ``FREQ`` is equal to ``'Y'``, ``'A'`` or ``1``, the third - argument is not needed (because ``SUBPERIOD`` is necessarily a - vector of ones in this case). + |br| where ``FREQ`` is a single character (’Y’, ’A’, ’Q’, ’M’) + or integer (1, 4, or 12) specifying the frequency, ``YEAR`` + and ``SUBPERIOD`` are ``n*1`` vectors of integers. Returns a + ``dates`` object with ``n`` elements. If ``FREQ`` is equal to + ``'Y'``, ``'A'`` or ``1``, the third argument is not needed + (because ``SUBPERIOD`` is necessarily a vector of ones in this + case). *Example* @@ -253,22 +251,44 @@ The dates class A list of the available methods, by alphabetical order, is given - below. Note that the MATLAB/Octave classes do not allow in place + below. Note that by default the methods do not allow in place modifications: when a method is applied to an object a new object is instantiated. For instance, to apply the method ``multiplybytwo`` to an object ``X`` we write:: - Y = X.multiplybytwo() + >> X = 2; + >> Y = X.multiplybytwo(); + >> X + + 2 + + >> Y + + 4 + or equivalently:: - Y = multiplybytwo(X) + >> Y = multiplybytwo(X); the object ``X`` is left unchanged, and the object ``Y`` is a - modified copy of ``X``. + modified copy of ``X`` (multiplied by two). This behaviour is + altered if the name of the method is postfixed with an + underscore. In this case the creation of a copy is avoided. For + instance, following the previous example, we would have:: + >> X = 2; + >> X.multiplybytwo_(); + >> X + + 4 + + Modifying the objects in place, with underscore methods, is + particularly useful if the methods are called in loops, since this + saves the object instantiation overhead. .. datesmethod:: C = append (A, B) + C = append_ (A, B) |br| Appends ``dates`` object ``B``, or a string that can be interpreted as a date, to the ``dates`` object ``A``. If ``B`` @@ -282,17 +302,43 @@ The dates class >> D = dates('1950Q1','1950Q2'); >> d = dates('1950Q3'); >> E = D.append(d); - >> F = D.append('1950Q3') + >> F = D.append('1950Q3'); >> isequal(E,F) ans = 1 >> F + F = + >> D - .. datesmethod:: C = colon (A, B) + D = + + >> D.append_('1950Q3') + + ans = + + + .. datesmethod:: B = char (A) + + |br| Overloads the MATLAB/Octave ``char`` function. Converts a + ``dates`` object into a character array. + + *Example* + + :: + + >> A = dates('1950Q1'); + > A.char() + + ans = + + '1950Q1' + + + .. datesmethod:: C = colon (A, B) C = colon (A, i, B) |br| Overloads the MATLAB/Octave colon (``:``) operator. A and B @@ -307,11 +353,42 @@ The dates class >> A = dates('1950Q1'); >> B = dates('1951Q2'); >> C = A:B + C = + >> D = A:2:B + D = + .. datesmethod:: B = copy (A) + + |br| Returns a copy of a ``dates`` object. + + + .. datesmethod:: disp (A) + + |br| Overloads the MATLAB/Octave disp function for ``dates`` object. + + + .. datesmethod:: display (A) + + |br| Overloads the MATLAB/Octave display function for ``dates`` object. + + *Example* + + :: + + >> disp(B) + + B = + + + >> display(B) + + B = + + .. datesmethod:: B = double (A) |br| Overloads the MATLAB/Octave ``double`` function. ``A`` is @@ -319,8 +396,7 @@ The dates class representation of a ``dates`` object, the integer and fractional parts respectively corresponding to the year and the subperiod. The fractional part is the subperiod number - minus one divided by the frequency (``1``, ``4``, ``12`` or - ``52``). + minus one divided by the frequency (``1``, ``4``, or ``12``). *Example*: @@ -342,8 +418,8 @@ The dates class |br| Overloads the MATLAB/Octave ``eq`` (equal, ``==``) operator. ``dates`` objects ``A`` and ``B`` must have the same number of elements (say, ``n``). The returned argument is a - ``n`` by ``1`` vector of zeros and ones. The i-th element of - ``C`` is equal to ``1`` if and only if the dates ``A(i)`` and + ``n`` by ``1`` vector of logicals. The i-th element of + ``C`` is equal to ``true`` if and only if the dates ``A(i)`` and ``B(i)`` are the same. *Example* @@ -356,8 +432,10 @@ The dates class ans = - 1 - 0 + 2x1 logical array + + 1 + 0 .. datesmethod:: C = ge (A, B) @@ -365,8 +443,8 @@ The dates class |br| Overloads the MATLAB/Octave ``ge`` (greater or equal, ``>=``) operator. ``dates`` objects ``A`` and ``B`` must have the same number of elements (say, ``n``). The returned - argument is a ``n`` by ``1`` vector of zeros and ones. The - i-th element of ``C`` is equal to ``1`` if and only if the + argument is a ``n`` by ``1`` vector of logicals. The + i-th element of ``C`` is equal to ``true`` if and only if the date ``A(i)`` is posterior or equal to the date ``B(i)``. *Example* @@ -379,8 +457,10 @@ The dates class ans = - 1 - 1 + 2x1 logical array + + 1 + 1 .. datesmethod:: C = gt (A, B) @@ -388,7 +468,7 @@ The dates class |br| Overloads the MATLAB/Octave ``gt`` (greater than, ``>``) operator. ``dates`` objects ``A`` and ``B`` must have the same number of elements (say, ``n``). The returned argument is a - ``n`` by ``1`` vector of zeros and ones. The i-th element of + ``n`` by ``1`` vector of logicals. The i-th element of ``C`` is equal to ``1`` if and only if the date ``A(i)`` is posterior to the date ``B(i)``. @@ -402,8 +482,10 @@ The dates class ans = - 0 - 1 + 2x1 logical array + + 0 + 1 .. datesmethod:: D = horzcat (A, B, C, ...) @@ -421,6 +503,7 @@ The dates class >> B = dates('1950Q2'); >> C = [A, B]; >> C + C = @@ -442,63 +525,53 @@ The dates class >> B = dates('1951Q1'):dates('1951Q4'); >> C = intersect(A, B); >> C + C = - .. datesmethod:: C = setdiff (A, B) - - |br| Overloads the MATLAB/Octave ``setdiff`` function. All the - input arguments must be ``dates`` objects. The returned - argument is a ``dates`` object all dates present in ``A`` but - not in ``B``. If ``A`` and ``B`` are disjoint ``dates`` - objects, the function returns ``A``. Returned dates in - ``dates`` object ``C`` are sorted by increasing order. - - *Example* - - :: - - >> A = dates('1950Q1'):dates('1969Q4') ; - >> B = dates('1960Q1'):dates('1969Q4') ; - >> C = dates('1970Q1'):dates('1979Q4') ; - >> d1 = setdiff(d1,d2); - >> d2 = setdiff(d1,d3); - d1 = - d2 = - - .. datesmethod:: B = isempty (A) - |br| Overloads the MATLAB/Octave ``isempty`` function for ``dates`` - objects``. + |br| Overloads the MATLAB/Octave ``isempty`` function. *Example* :: - >> A = dates('1950Q1'):dates('1951Q4'); + >> A = dates('1950Q1'); >> A.isempty() ans = - 0 + logical + 0 - .. datesmethod:: C = isequal (A, B) + >> B = dates(); + >> B.isempty() - |br| Overloads the MATLAB/Octave ``isequal`` function for - ``dates`` objects. + ans = + + logical + + 1 + + .. datesmethod:: C = isequal (A, B) + + |br| Overloads the MATLAB/Octave ``isequal`` function. *Example* :: - >> A = dates('1950Q1'):dates('1951Q4'); - >> isequal(A,A) + >> A = dates('1950Q1'); + >> B = dates('1950Q2'); + >> isequal(A, B) ans = - 1 + logical + + 0 .. datesmethod:: C = le (A, B) @@ -506,9 +579,9 @@ The dates class |br| Overloads the MATLAB/Octave ``le`` (less or equal, ``<=``) operator. ``dates`` objects ``A`` and ``B`` must have the same number of elements (say, ``n``). The returned - argument is a ``n`` by ``1`` vector of zeros and ones. The - i-th element of ``C`` is equal to ``1`` if and only if the - date ``A(i)`` is not posterior to the date ``B(i)``. + argument is a ``n`` by ``1`` vector of logicals. The + i-th element of ``C`` is equal to ``true`` if and only if the + date ``A(i)`` is anterior or equal to the date ``B(i)``. *Example* @@ -520,36 +593,37 @@ The dates class ans = - 1 - 0 + 2x1 logical array + + 1 + 0 .. datesmethod:: B = length (A) - |br| Overloads the MATLAB/Octave ``length`` function. Returns the - number of dates in ``dates`` object ``A`` (``B`` is a scalar - integer). + |br| Overloads the MATLAB/Octave ``length`` function. Returns + the number of elements in a ``dates`` object. *Example* :: - >> A = dates('1950Q1','1951Q2'); + >> A = dates('1950Q1'):dates(2000Q3); >> A.length() ans = - 2 + 203 - .. datesmethod:: C = lt (A, B) + .. datesmethod:: C = lt (A, B) - |br| Overloads the MATLAB/Octave ``lt`` (less than, ``<``) - operator. ``dates`` objects ``A`` and ``B`` must have the same - number of elements (say, ``n``). The returned argument is a - ``n`` by ``1`` vector of zeros and ones. The i-th element of - ``C`` is equal to ``1`` if and only if the date ``A(i)`` - preceeds the date ``B(i)``. + |br| Overloads the MATLAB/Octave ``lt`` (less than, + ``<``) operator. ``dates`` objects ``A`` and ``B`` must have + the same number of elements (say, ``n``). The returned + argument is a ``n`` by ``1`` vector of logicals. The + i-th element of ``C`` is equal to ``true`` if and only if the + date ``A(i)`` is anterior or equal to the date ``B(i)``. *Example* @@ -561,8 +635,10 @@ The dates class ans = - 0 - 0 + 2x1 logical array + + 0 + 0 .. datesmethod:: D = max (A, B, C, ...) @@ -577,6 +653,7 @@ The dates class >> A = {dates('1950Q2'), dates('1953Q4','1876Q2'), dates('1794Q3')}; >> max(A{:}) + ans = @@ -592,6 +669,7 @@ The dates class >> A = {dates('1950Q2'), dates('1953Q4','1876Q2'), dates('1794Q3')}; >> min(A{:}) + ans = @@ -619,17 +697,35 @@ The dates class 0 >> d1-(-ee) + ans = + .. datesmethod:: C = mtimes (A, B) + + |br| Overloads the MATLAB/Octave ``mtimes`` operator + (``*``). ``A`` and ``B`` are respectively expected to be a + ``dseries`` object and a scalar integer. Returns ``dates`` + object ``A`` replicated ``B`` times. + + *Example* + + :: + + >> d = dates('1950Q1'); + >> d*2 + + ans = + + .. datesmethod:: C = ne (A, B) |br| Overloads the MATLAB/Octave ``ne`` (not equal, ``~=``) operator. ``dates`` objects ``A`` and ``B`` must have the same number of elements (say, ``n``) or one of the inputs must be a single element ``dates`` object. The returned argument is a - ``n`` by ``1`` vector of zeros and ones. The i-th element of - ``C`` is equal to ``1`` if and only if the dates ``A(i)`` and + ``n`` by ``1`` vector of logicals. The i-th element of + ``C`` is equal to ``true`` if and only if the dates ``A(i)`` and ``B(i)`` are different. *Example* @@ -642,8 +738,10 @@ The dates class ans = - 0 - 1 + 2x1 logical array + + 0 + 1 .. datesmethod:: C = plus (A, B) @@ -654,7 +752,7 @@ The dates class ``B`` is a vector of integers, the ``plus`` operator shifts the ``dates`` object by ``B`` periods forward. - :ex: + *Example* :: @@ -673,7 +771,9 @@ The dates class .. datesmethod:: C = pop (A) - C = pop (A,B) + C = pop (A, B) + C = pop_ (A) + C = pop_ (A, B) |br| Pop method for ``dates`` class. If only one input is provided, the method removes the last element of a ``dates`` @@ -685,15 +785,58 @@ The dates class :: - >> d1 = dates('1950Q1','1950Q2'); - >> d1.pop() + >> d = dates('1950Q1','1950Q2'); + >> d.pop() + ans = - >> d1.pop(1) + >> d.pop_(1) + ans = + .. datesmethod:: C = remove (A, B) + C = remove_ (A, B) + + |br| Remove method for ``dates`` class. Both inputs have to be ``dates`` objects, removes dates in ``B`` from ``A``. + + *Example* + + :: + + >> d = dates('1950Q1','1950Q2'); + >> d.remove(dates('1950Q2')) + + ans = + + + .. datesmethod:: C = setdiff (A, B) + + |br| Overloads the MATLAB/Octave ``setdiff`` function. All the + input arguments must be ``dates`` objects. The returned + argument is a ``dates`` object all dates present in ``A`` but + not in ``B``. If ``A`` and ``B`` are disjoint ``dates`` + objects, the function returns ``A``. Returned dates in + ``dates`` object ``C`` are sorted by increasing order. + + *Example* + + :: + + >> A = dates('1950Q1'):dates('1969Q4'); + >> B = dates('1960Q1'):dates('1969Q4'); + >> C = dates('1970Q1'):dates('1979Q4'); + >> setdiff(A, B) + + ans = + + >> setdiff(A, C) + + ans = + + .. datesmethod:: B = sort (A) + B = sort_ (A) |br| Sort method for ``dates`` objects. Returns a ``dates`` object with elements sorted by increasing order. @@ -704,9 +847,46 @@ The dates class >> dd = dates('1945Q3','1938Q4','1789Q3'); >> dd.sort() + ans = + .. datesmethod:: B = strings (A) + + |br| Converts a ``dates`` object into a cell of char arrays. + + *Example* + + :: + + >> A = dates('1950Q1'); + >> A = A:A+1; + >> strings(A) + + ans = + + 1x2 cell array + + {'1950Q1'} {'1950Q2'} + + + .. datesmethod:: B = subperiod (A) + + |br| Returns the subperiod of a date (an integer scalar + between 1 and ``A.freq``). + + *Example* + + :: + + >> A = dates('1950Q2'); + >> A.subperiod() + + ans = + + 2 + + .. datesmethod:: B = uminus (A) |br| Overloads the MATLAB/Octave unary minus operator. Returns @@ -718,6 +898,7 @@ The dates class >> dd = dates('1945Q3','1938Q4','1973Q1'); >> -dd + ans = @@ -735,10 +916,12 @@ The dates class >> d1 = dates('1945Q3','1973Q1','1938Q4'); >> d2 = dates('1973Q1','1976Q1'); >> union(d1,d2) + ans = .. datesmethod:: B = unique (A) + B = unique_ (A) |br| Overloads the MATLAB/Octave ``unique`` function. Returns a ``dates`` object with repetitions removed (only the last @@ -750,6 +933,7 @@ The dates class >> d1 = dates('1945Q3','1973Q1','1945Q3'); >> d1.unique() + ans = @@ -764,9 +948,34 @@ The dates class >> dd = dates('1945Q3','1938Q4','1973Q1'); >> +dd + ans = + .. datesmethod:: D = vertcat (A, B, C, ...) + + |br| Overloads the MATLAB/Octave ``horzcat`` operator. All the + input arguments must be ``dates`` objects. The returned + argument is a ``dates`` object gathering all the dates given + in the input arguments (repetitions are not removed). + + + .. datesmethod:: B = year (A) + + |br| Returns the year of a date (an integer scalar + between 1 and ``A.freq``). + + *Example* + + :: + + >> A = dates('1950Q2'); + >> A.subperiod() + + ans = + + 1950 + .. _dseries-members: The dseries class @@ -804,26 +1013,34 @@ The dseries class input. Valid file types are ``.m``, ``.mat``, ``.csv`` and ``.xls/.xlsx`` (Octave only supports ``.xlsx`` files and the `io `__ package from - Octave-Forge must be installed). A typical ``.m`` file will - have the following form:: + Octave-Forge must be installed). The extension of the file + should be explicitly provided. A typical ``.m`` file will have + the following form:: + FREQ__ = 4; INIT__ = '1994Q3'; NAMES__ = {'azert';'yuiop'}; TEX__ = {'azert';'yuiop'}; + TAGS__ = struct() + DATA__ = {} azert = randn(100,1); yuiop = randn(100,1); If a ``.mat`` file is used instead, it should provide the same - informations. Note that the ``INIT__`` variable can be either - a ``dates`` object or a string which could be used to - instantiate the same ``dates`` object. If ``INIT__`` is not - provided in the ``.mat`` or ``.m`` file, the initial is by - default set equal to ``dates('1Y')``. If a second input - argument is passed to the constructor, ``dates`` object - *INITIAL_DATE*, the initial date defined in *FILENAME* is - reset to *INITIAL_DATE*. This is typically usefull if - ``INIT__`` is not provided in the data file. + informations, except that the data should not be given as a + set of vectors, but as a single matrix of doubles named + ``DATA__``. This array should have as many columns as elements + in ``NAMES__`` (the number of variables). Note that the + ``INIT__`` variable can be either a ``dates`` object or a + string which could be used to instantiate the same ``dates`` + object. If ``INIT__`` is not provided in the ``.mat`` or + ``.m`` file, the initial is by default set equal to + ``dates('1Y')``. If a second input argument is passed to the + constructor, ``dates`` object *INITIAL_DATE*, the initial date + defined in *FILENAME* is reset to *INITIAL_DATE*. This is + typically usefull if ``INIT__`` is not provided in the data + file. .. construct:: dseries (DATA_MATRIX[,INITIAL_DATE[,LIST_OF_NAMES[,TEX_NAMES]]]) dseries (DATA_MATRIX[,RANGE_OF_DATES[,LIST_OF_NAMES[,TEX_NAMES]]]) @@ -853,20 +1070,20 @@ The dseries class Creates a ``dseries`` object given the MATLAB Table provided as the sole argument. It is assumed that the first column of the table contains the - dates of the ``dseries`` and the first row contains the names. NB: This + dates of the ``dseries`` and the first row contains the names. This feature is not available under Octave or MATLAB R2013a or earlier. - *Example* + *Example* - Various ways to create a ``dseries`` object:: + Various ways to create a ``dseries`` object:: - do1 = dseries(1999Q3); - do2 = dseries('filename.csv'); - do3 = dseries([1; 2; 3], 1999Q3, {'var123'}, {'var_{123}'}); + do1 = dseries(1999Q3); + do2 = dseries('filename.csv'); + do3 = dseries([1; 2; 3], 1999Q3, {'var123'}, {'var_{123}'}); - >> do1 = dseries(dates('1999Q3')); - >> do2 = dseries('filename.csv'); - >> do3 = dseries([1; 2; 3], dates('1999Q3'), {'var123'}, {'var_{123}'}); + >> do1 = dseries(dates('1999Q3')); + >> do2 = dseries('filename.csv'); + >> do3 = dseries([1; 2; 3], dates('1999Q3'), {'var123'}, {'var_{123}'}); One can easily create subsamples from a ``dseries`` object using @@ -878,10 +1095,13 @@ The dseries class to the last observation, then ``ds(d)`` instantiates a new ``dseries`` object containing the subsample defined by ``d``. - A list of the available methods, by alphabetical order, is given below. + A list of the available methods, by alphabetical order, is given + below. As in the previous section the in place modifications + versions of the methods are postfixed with an underscore. - .. dseriesmethod:: A = abs(B) + .. dseriesmethod:: A = abs (B) + abs_ (B) |br| Overloads the ``abs()`` function for ``dseries`` objects. Returns the absolute value of the variables in @@ -912,7 +1132,8 @@ The dseries class 1973Q3 | 0.99791 | 0.22677 - .. dseriesmethod:: [A, B] = align(A, B) + .. dseriesmethod:: [A, B] = align (A, B) + align_ (A, B) If ``dseries`` objects ``A`` and ``B`` are defined on different time ranges, this function extends ``A`` and/or @@ -951,8 +1172,33 @@ The dseries class 2001Q1 | 0.17813 2001Q2 | 0.12801 + >> ts0 = dseries(rand(5,1),dates('2000Q1')); % 2000Q1 -> 2001Q1 + >> ts1 = dseries(rand(3,1),dates('2000Q4')); % 2000Q4 -> 2001Q2 + >> align_(ts0, ts1); % 2000Q1 -> 2001Q2 + >> ts1 - .. dseriesmethod:: B = baxter_king_filter(A, hf, lf, K) + ts1 is a dseries object: + + | Variable_1 + 2000Q1 | NaN + 2000Q2 | NaN + 2000Q3 | NaN + 2000Q4 | 0.66653 + 2001Q1 | 0.17813 + 2001Q2 | 0.12801 + + + .. dseriesmethod:: C = backcast (A, B[, diff]) + backcast_ (A, B[, diff]) + + Backcasts ``dseries`` object ``A`` with ``dseries`` object B's + growth rates (except if the last optional argument, ``diff``, + is true in which case first differences are used). Both + ``dseries`` objects must have the same frequency. + + + .. dseriesmethod:: B = baxter_king_filter (A, hf, lf, K) + baxter_king_filter_ (A, hf, lf, K) |br| Implementation of the *Baxter and King* (1999) band pass filter for ``dseries`` objects. This filter isolates business @@ -997,7 +1243,17 @@ The dseries class set(gca,'XTickLabel',strings(ts1.dates(id))); - .. dseriesmethod:: C = chain(A, B) + .. dseriesmethod:: B = center (A[, geometric]) + center_ (A[, geometric]) + + |br| Centers variables in ``dseries`` object ``A`` around their + arithmetic means, except if the optional argument ``geometric`` + is set equal to ``true`` in which case all the variables are + divided by their geometric means. + + + .. dseriesmethod:: C = chain (A, B) + chain_ (A, B) |br| Merge two ``dseries`` objects along the time dimension. The two objects must have the same number of @@ -1043,7 +1299,7 @@ The dseries class 1951Q2 | 6 - .. dseriesmethod:: [error_flag, message ] = check(A) + .. dseriesmethod:: [error_flag, message ] = check (A) |br| Sanity check of ``dseries`` object ``A``. Returns ``1`` if there is an error, ``0`` otherwise. The second output @@ -1051,7 +1307,68 @@ The dseries class error. - .. dseriesmethod:: B = cumprod(A[, d[, v]]) + .. dseriesmethod:: B = copy (A) + + |br| Returns a copy of ``A``. If an inplace modification method + is applied to ``A``, object ``B`` will not be affected. Note + that if ``A`` is assigned to ``C``, ``C = A``, then any in + place modification method applied to ``A`` will change ``C``. + + *Example* + + :: + + >> a = dseries(randn(5,1)) + + a is a dseries object: + + | Variable_1 + 1Y | -0.16936 + 2Y | -1.1451 + 3Y | -0.034331 + 4Y | -0.089042 + 5Y | -0.66997 + + >> b = copy(a); + >> c = a; + >> a.abs(); + >> a.abs_(); + >> a + + a is a dseries object: + + | Variable_1 + 1Y | 0.16936 + 2Y | 1.1451 + 3Y | 0.034331 + 4Y | 0.089042 + 5Y | 0.66997 + + >> b + + b is a dseries object: + + | Variable_1 + 1Y | -0.16936 + 2Y | -1.1451 + 3Y | -0.034331 + 4Y | -0.089042 + 5Y | -0.66997 + + >> c + + c is a dseries object: + + | Variable_1 + 1Y | 0.16936 + 2Y | 1.1451 + 3Y | 0.034331 + 4Y | 0.089042 + 5Y | 0.66997 + + + .. dseriesmethod:: B = cumprod (A[, d[, v]]) + cumprod_ (A[, d[, v]]) |br| Overloads the MATLAB/Octave ``cumprod`` function for ``dseries`` objects. The cumulated product cannot be computed @@ -1113,7 +1430,8 @@ The dseries class 7Y | 50.2655 - .. dseriesmethod:: B = cumsum(A[, d[, v]]) + .. dseriesmethod:: B = cumsum (A[, d[, v]]) + cumsum (A[, d[, v]]) |br| Overloads the MATLAB/Octave ``cumsum`` function for ``dseries`` objects. The cumulated sum cannot be computed if @@ -1184,14 +1502,46 @@ The dseries class 10Y | 10.1416 - .. dseriesmethod:: C = eq(A, B) + .. dseriesmethod:: B = detrend (A, m) + dentrend_ (A, m) + + |br| Detrends ``dseries`` object ``A`` with a fitted + polynomial of order ``m``. Note that each variable is + detrended with a different polynomial. + + + .. dseriesmethod:: B = diff (A) + diff_ (A) + + |br| Returns the first difference of ``dseries`` object ``A``. + + + .. datesmethod:: disp (A) + + |br| Overloads the MATLAB/Octave disp function for ``dseries`` object. + + + .. datesmethod:: display (A) + + |br| Overloads the MATLAB/Octave display function for + ``dseries`` object. ``display`` is the function called by + MATLAB to print the content of an object if a semicolon is + missing at the end of a MATLAB statement. If the ``dseries`` + object is defined over a too large time span, only the first + and last periods will be printed. If the ``dseries`` object + contains too many variables, only the first and last variables + will be printed. If all the periods and variables are + required, the ``disp`` method should be used instead. + + + .. dseriesmethod:: C = eq (A, B) |br| Overloads the MATLAB/Octave ``eq`` (equal, ``==``) operator. ``dseries`` objects ``A`` and ``B`` must have the same number of observations (say, :math:`T`) and variables (:math:`N`). The returned argument is a :math:`T \times N` - matrix of zeros and ones. Element :math:`(i,j)` of ``C`` is - equal to ``1`` if and only if observation :math:`i` for + matrix of logicals. Element :math:`(i,j)` of ``C`` is + equal to ``true`` if and only if observation :math:`i` for variable :math:`j` in ``A`` and ``B`` are the same. *Example* @@ -1204,12 +1554,42 @@ The dseries class ans = - 1 - 0 - 1 + 3x1 logical array + + 1 + 0 + 1 - .. dseriesmethod:: B = exp(A) + .. dseriesmethod:: l = exist (A, varname) + + |br| Tests if variable ``varname`` exists in ``dseries`` object ``A``. Returns + ``true`` iff variable exists in ``A``. + + *Example* + + :: + + >> ts = dseries(randn(100,1)); + >> ts.exist('Variable_1') + + ans = + + logical + + 1 + + >> ts.exist('Variable_2') + + ans = + + logical + + 0 + + + .. dseriesmethod:: B = exp (A) + exp_ (A) |br| Overloads the MATLAB/Octave ``exp`` function for ``dseries`` objects. @@ -1222,30 +1602,7 @@ The dseries class >> ts1 = ts0.exp(); - .. dseriesmethod:: l = exist(A, varname) - - |br| Tests if variable exists in ``dseries`` object ``A``. Returns - ``1`` (true) iff variable exists in ``A``. - - *Example* - - :: - - >> ts = dseries(randn(100,1)); - >> ts.exist('Variable_1') - - ans = - - 1 - - >> ts.exist('Variable_2') - - ans = - - 0 - - - .. dseriesmethod:: C = extract(A, B[, ...]) + .. dseriesmethod:: C = extract (A, B[, ...]) |br| Extracts some variables from a ``dseries`` object ``A`` and returns a ``dseries`` object ``C``. The input arguments @@ -1263,13 +1620,15 @@ The dseries class >> ts0 = dseries(ones(100,10)); >> ts1 = ts0{'Variable_1','Variable_2','Variable_3'}; - >> ts2 = ts0{'Variable_@1,2,3@'} - >> ts3 = ts0{'Variable_[1-3]$'} + >> ts2 = ts0{'Variable_@1,2,3@'}; + >> ts3 = ts0{'Variable_[1-3]$'}; >> isequal(ts1,ts2) && isequal(ts1,ts3) ans = - 1 + logical + + 1 It is possible to use up to two implicit loops to select variables:: @@ -1290,7 +1649,17 @@ The dseries class 1973Q4 | -0.03705 | -0.35899 | 0.85838 | -1.4675 | -2.1666 | -0.62032 - .. dseriesmethod:: f = freq(B) + .. dseriesmethod:: f = firstdate (A) + + |br| Returns the first period in ``dseries`` object ``A``. + + + .. dseriesmethod:: f = firstobservedperiod (A) + + |br| Returns the first period where all the variables in ``dseries`` object ``A`` are observed (non NaN). + + + .. dseriesmethod:: f = frequency (B) |br| Returns the frequency of the variables in ``dseries`` object ``B``. @@ -1299,14 +1668,14 @@ The dseries class :: >> ts = dseries(randn(3,2),'1973Q1'); - >> ts.freq + >> ts.frequency ans = 4 - .. dseriesmethod:: D = horzcat(A, B[, ...]) + .. dseriesmethod:: D = horzcat (A, B[, ...]) |br| Overloads the ``horzcat`` MATLAB/Octave’s method for ``dseries`` objects. Returns a ``dseries`` object ``D`` @@ -1341,7 +1710,8 @@ The dseries class 1952Q1 | NaN | NaN | 0.50946 - .. dseriesmethod:: B = hpcycle(A[, lambda]) + .. dseriesmethod:: B = hpcycle (A[, lambda]) + hpcycle_ (A[, lambda]) |br| Extracts the cycle component from a ``dseries`` ``A`` object using the *Hodrick and Prescott (1997)* filter and @@ -1381,7 +1751,8 @@ The dseries class set(gca,'XTickLabel',strings(ts.dates(id))); - .. dseriesmethod:: B = hptrend(A[, lambda]) + .. dseriesmethod:: B = hptrend (A[, lambda]) + hptrend_ (A[, lambda]) |br| Extracts the trend component from a ``dseries`` A object using the *Hodrick and Prescott (1997)* filter and returns a @@ -1409,20 +1780,7 @@ The dseries class set(gca,'XTickLabel',strings(ts0.dates(id))); - .. dseriesmethod:: f = init(B) - - |br| Returns the initial date in ``dseries`` object ``B``. - - *Example* - - :: - - >> ts = dseries(randn(3,2),'1973Q1'); - >> ts.init - ans = - - - .. dseriesmethod:: C = insert(A, B, I) + .. dseriesmethod:: C = insert (A, B, I) |br| Inserts variables contained in ``dseries`` object ``B`` in ``dseries`` object ``A`` at positions specified by integer @@ -1433,7 +1791,7 @@ The dseries class defined over the same time ranges, but it is assumed that they have common frequency. - :ex: + *Example* :: @@ -1457,29 +1815,50 @@ The dseries class 1950Q2 | 1 | 1 | 3.1416 | 1 | 1.7725 | 1 - .. dseriesmethod:: B = isempty(A) + .. dseriesmethod:: B = isempty (A) - |br| Overloads the MATLAB/octave’s ``isempty`` function. Returns - ``1`` if ``dseries`` object ``A`` is empty, ``0`` otherwise. + |br| Overloads the MATLAB/octave’s ``isempty`` function. Returns + ``true`` if ``dseries`` object ``A`` is empty. - .. dseriesmethod:: C = isequal(A,B) + .. dseriesmethod:: C = isequal (A, B) |br| Overloads the MATLAB/octave’s ``isequal`` function. Returns - ``1`` if ``dseries`` objects ``A`` and ``B`` are identical, ``0`` - otherwise. + ``true`` if ``dseries`` objects ``A`` and ``B`` are identical. - .. dseriesmethod:: B = lag(A[, p]) + .. dseriesmethod:: C = isinf (A) - Returns lagged time series. Default value of ``p``, the number + |br| Overloads the MATLAB/octave’s ``isinf`` function. Returns + a logical array, with element ``(i,j)`` equal to ``true`` if and + only if variable ``j`` is finite in period ``A.dates(i)``. + + + .. dseriesmethod:: C = isnan (A) + + |br| Overloads the MATLAB/octave’s ``isnan`` function. Returns + a logical array, with element ``(i,j)`` equal to ``true`` if and + only if variable ``j`` isn't NaN in period ``A.dates(i)``. + + + .. dseriesmethod:: C = isreal (A) + + |br| Overloads the MATLAB/octave’s ``isreal`` function. Returns + a logical array, with element ``(i,j)`` equal to ``true`` if and + only if variable ``j`` is real in period ``A.dates(i)``. + + + .. dseriesmethod:: B = lag (A[, p]) + lag_ (A[, p]) + + |br| Returns lagged time series. Default value of integer scalar ``p``, the number of lags, is ``1``. *Example* :: - >> ts0 = dseries(transpose(1:4),'1950Q1') + >> ts0 = dseries(transpose(1:4), '1950Q1') ts0 is a dseries object: @@ -1493,7 +1872,7 @@ The dseries class ts1 is a dseries object: - | lag(Variable_1,1) + | Variable_1 1950Q1 | NaN 1950Q2 | 1 1950Q3 | 2 @@ -1503,7 +1882,7 @@ The dseries class ts2 is a dseries object: - | lag(Variable_1,2) + | Variable_1 1950Q1 | NaN 1950Q2 | NaN 1950Q3 | 1 @@ -1517,7 +1896,7 @@ The dseries class ans is a dseries object: - | lag(Variable_1,1) + | Variable_1 1950Q1 | NaN 1950Q2 | 1 1950Q3 | 2 @@ -1529,32 +1908,39 @@ The dseries class ans is a dseries object: - | lag(Variable_1,1) + | Variable_1 1950Q1 | NaN 1950Q2 | 1 1950Q3 | 2 1950Q4 | 3 - .. dseriesmethod:: l = last(B) + .. dseriesmethod:: l = lastdate (B) - |br| Returns the last date in ``dseries`` object ``B``. + |br| Returns the last period in ``dseries`` object ``B``. *Example* :: >> ts = dseries(randn(3,2),'1973Q1'); - >> ts.last + >> ts.lastdate() + ans = - .. dseriesmethod:: B = lead(A[, p]) + .. dseriesmethod:: f = lastobservedperiod (A) - |br| Returns lead time series. Default value of ``p``, the - number of leads, is ``1``. As in the ``lag`` method, the - ``dseries`` class overloads the parenthesis so that - ``ts.lead(p)`` is equivalent to ``ts(p)``. + |br| Returns the last period where all the variables in ``dseries`` object ``A`` are observed (non NaN). + + + .. dseriesmethod:: B = lead (A[, p]) + lead_ (A[, p]) + + |br| Returns lead time series. Default value of integer scalar + ``p``, the number of leads, is ``1``. As in the ``lag`` + method, the ``dseries`` class overloads the parenthesis so + that ``ts.lead(p)`` is equivalent to ``ts(p)``. *Example* @@ -1565,7 +1951,7 @@ The dseries class ts1 is a dseries object: - | lead(Variable_1,1) + | Variable_1 1950Q1 | 2 1950Q2 | 3 1950Q3 | 4 @@ -1575,7 +1961,7 @@ The dseries class ts2 is a dseries object: - | lead(Variable_1,2) + | Variable_1 1950Q1 | 3 1950Q2 | 4 1950Q3 | NaN @@ -1606,7 +1992,29 @@ The dseries class in the ``model`` block is zero, but the residuals are non zero). - .. dseriesmethod:: B = log(A) + + .. dseriesmethod:: B = lineartrend (A) + + |br| Returns a linear trend centered on 0, the length of the + trend is given by the size of ``dseries`` object ``A`` (the + number of periods). + + *Example* + + :: + + >> ts = dseries(ones(3,1)); + >> ts.lineartrend() + + ans = + + -1 + 0 + 1 + + + .. dseriesmethod:: B = log (A) + log_ (A) |br| Overloads the MATLAB/Octave ``log`` function for ``dseries`` objects. @@ -1618,8 +2026,23 @@ The dseries class >> ts0 = dseries(rand(10,1)); >> ts1 = ts0.log(); + .. dseriesmethod:: B = mdiff (A) + mdiff_ (A) - .. dseriesmethod:: C = merge(A, B) + |br| Computes monthly growth rates of variables in + ``dseries`` object ``A``. + + + .. dseriesmethod:: B = mean (A[, geometric]) + + |br| Overloads the MATLAB/Octave ``mean`` function for + ``dseries`` objects. Returns the mean of each variable in + ``dseries`` object ``A``. If the second argument is ``true`` + the geometric mean is computed, otherwise (default) the + arithmetic mean is reported. + + + .. dseriesmethod:: C = merge (A, B[, legacy]) |br| Merges two ``dseries`` objects ``A`` and ``B`` in ``dseries`` object ``C``. Objects ``A`` and ``B`` need to have @@ -1629,71 +2052,75 @@ The dseries class select the variable ``x`` as defined in the second input argument, ``B``, except for the NaN elements in ``B`` if corresponding elements in ``A`` (ie same periods) are well - defined numbers. + defined numbers. This behaviour can be changed by setting the + optional argument ``legacy`` equal to true, in which case the + second variable overwrites the first one even if the second + variable has NaNs. *Example* :: - >> ts0 = dseries(rand(3,2),'1950Q1',{'A1';'A2'}) + >> ts0 = dseries(rand(3,2),'1950Q1',{'A1';'A2'}) - ts0 is a dseries object: + ts0 is a dseries object: - | A1 | A2 - 1950Q1 | 0.42448 | 0.92477 - 1950Q2 | 0.60726 | 0.64208 - 1950Q3 | 0.070764 | 0.1045 + | A1 | A2 + 1950Q1 | 0.96284 | 0.5363 + 1950Q2 | 0.25145 | 0.31866 + 1950Q3 | 0.34447 | 0.4355 - >> ts1 = dseries(rand(3,1),'1950Q2',{'A1'}) + >> ts1 = dseries(rand(3,1),'1950Q2',{'A1'}) - ts1 is a dseries object: + ts1 is a dseries object: - | A1 - 1950Q2 | 0.70023 - 1950Q3 | 0.3958 - 1950Q4 | 0.084905 + | A1 + 1950Q2 | 0.40161 + 1950Q3 | 0.81763 + 1950Q4 | 0.97769 - >> merge(ts0,ts1) + >> merge(ts0,ts1) - ans is a dseries object: + ans is a dseries object: - | A1 | A2 - 1950Q1 | NaN | 0.92477 - 1950Q2 | 0.70023 | 0.64208 - 1950Q3 | 0.3958 | 0.1045 - 1950Q4 | 0.084905 | NaN + | A1 | A2 + 1950Q1 | 0.96284 | 0.5363 + 1950Q2 | 0.40161 | 0.31866 + 1950Q3 | 0.81763 | 0.4355 + 1950Q4 | 0.97769 | NaN >> merge(ts1,ts0) ans is a dseries object: - | A1 | A2 - 1950Q1 | 0.42448 | 0.92477 - 1950Q2 | 0.60726 | 0.64208 - 1950Q3 | 0.070764 | 0.1045 - 1950Q4 | NaN | NaN + | A1 | A2 + 1950Q1 | 0.96284 | 0.5363 + 1950Q2 | 0.25145 | 0.31866 + 1950Q3 | 0.34447 | 0.4355 + 1950Q4 | 0.97769 | NaN - .. dseriesmethod:: C = minus(A, B) + .. dseriesmethod:: C = minus (A, B) - |br| Overloads the ``minus`` (``-``) operator for ``dseries`` - objects, element by element subtraction. If both ``A`` and - ``B`` are ``dseries`` objects, they do not need to be defined - over the same time ranges. If ``A`` and ``B`` are ``dseries`` - objects with :math:`T_A` and :math:`T_B` observations and - :math:`N_A` and :math:`N_B` variables, then :math:`N_A` must - be equal to :math:`N_B` or :math:`1` and :math:`N_B` must be - equal to :math:`N_A` or :math:`1`. If :math:`T_A=T_B`, - ``isequal(A.init,B.init)`` returns ``1`` and :math:`N_A=N_B`, - then the ``minus`` operator will compute for each couple - :math:`(t,n)`, with :math:`1\le t\le T_A` and :math:`1\le n\le - N_A`, ``C.data(t,n)=A.data(t,n)-B.data(t,n)``. If :math:`N_B` - is equal to :math:`1` and :math:`N_A>1`, the smaller - ``dseries`` object (``B``) is “broadcast” across the larger - ``dseries`` (``A``) so that they have compatible shapes, the - ``minus`` operator will subtract the variable defined in ``B`` - from each variable in ``A``. If ``B`` is a double scalar, then - the method ``minus`` will subtract ``B`` from all the + |br| Overloads the MATLAB/Octave ``minus`` (``-``) operator + for ``dseries`` objects, element by element subtraction. If + both ``A`` and ``B`` are ``dseries`` objects, they do not need + to be defined over the same time ranges. If ``A`` and ``B`` + are ``dseries`` objects with :math:`T_A` and :math:`T_B` + observations and :math:`N_A` and :math:`N_B` variables, then + :math:`N_A` must be equal to :math:`N_B` or :math:`1` and + :math:`N_B` must be equal to :math:`N_A` or :math:`1`. If + :math:`T_A=T_B`, ``isequal(A.init,B.init)`` returns ``1`` and + :math:`N_A=N_B`, then the ``minus`` operator will compute for + each couple :math:`(t,n)`, with :math:`1\le t\le T_A` and + :math:`1\le n\le N_A`, + ``C.data(t,n)=A.data(t,n)-B.data(t,n)``. If :math:`N_B` is + equal to :math:`1` and :math:`N_A>1`, the smaller ``dseries`` + object (``B``) is “broadcast” across the larger ``dseries`` + (``A``) so that they have compatible shapes, the ``minus`` + operator will subtract the variable defined in ``B`` from each + variable in ``A``. If ``B`` is a double scalar, then the + method ``minus`` will subtract ``B`` from all the observations/variables in ``A``. If ``B`` is a row vector of length :math:`N_A`, then the ``minus`` method will subtract ``B(i)`` from all the observations of variable ``i``, for @@ -1711,10 +2138,10 @@ The dseries class ans is a dseries object: - | minus(Variable_1,Variable_2) | minus(Variable_2,Variable_2) - 1Y | -0.48853 | 0 - 2Y | -0.50535 | 0 - 3Y | -0.32063 | 0 + | Variable_1 | Variable_2 + 1Y | -0.48853 | 0 + 2Y | -0.50535 | 0 + 3Y | -0.32063 | 0 >> ts1 @@ -1729,7 +2156,7 @@ The dseries class ans is a dseries object: - | minus(Variable_2,0.703) + | Variable_2 1Y | 0 2Y | 0.051148 3Y | -0.15572 @@ -1738,15 +2165,15 @@ The dseries class ans is a dseries object: - | minus(0.703,Variable_2) + | Variable_2 1Y | 0 2Y | -0.051148 3Y | 0.15572 - .. dseriesmethod:: C = mpower(A, B) + .. dseriesmethod:: C = mpower (A, B) - |br| Overloads the ``mpower`` (``^``) operator for ``dseries`` + |br| Overloads the MATLAB/Octave ``mpower`` (``^``) operator for ``dseries`` objects and computes element-by-element power. ``A`` is a ``dseries`` object with ``N`` variables and ``T`` observations. If ``B`` is a real scalar, then ``mpower(A,B)`` @@ -1765,7 +2192,7 @@ The dseries class ts1 is a dseries object: - | power(Variable_1,2) + | Variable_1 1Y | 1 2Y | 4 3Y | 9 @@ -1774,15 +2201,15 @@ The dseries class ts2 is a dseries object: - | power(Variable_1,Variable_1) + | Variable_1 1Y | 1 2Y | 4 3Y | 27 - .. dseriesmethod:: C = mrdivide(A, B) + .. dseriesmethod:: C = mrdivide (A, B) - |br| Overloads the ``mrdivide`` (``/``) operator for + |br| Overloads the MATLAB/Octave ``mrdivide`` (``/``) operator for ``dseries`` objects, element by element division (like the ``./`` MATLAB/Octave operator). If both ``A`` and ``B`` are ``dseries`` objects, they do not need to be defined over the @@ -1826,43 +2253,53 @@ The dseries class ans is a dseries object: - | divide(Variable_1,Variable_2) | divide(Variable_2,Variable_2) - 1Y | 0.80745 | 1 - 2Y | 4.2969 | 1 - 3Y | 0.59235 | 1 + | Variable_1 | Variable_2 + 1Y | 0.80745 | 1 + 2Y | 4.2969 | 1 + 3Y | 0.59235 | 1 - .. dseriesmethod:: C = mtimes(A, B) + .. dseriesmethod:: C = mtimes (A, B) - |br| Overloads the ``mtimes`` (``*``) operator for ``dseries`` - objects and the Hadammard product (the .* MATLAB/Octave - operator). If both ``A`` and ``B`` are ``dseries`` objects, - they do not need to be defined over the same time ranges. If - ``A`` and ``B`` are ``dseries`` objects with :math:`T_A` and - :math:`_B` observations and :math:`N_A` and :math:`N_B` - variables, then :math:`N_A` must be equal to :math:`N_B` or - :math:`1` and :math:`N_B` must be equal to :math:`N_A` or - :math:`1`. If :math:`T_A=T_B`, ``isequal(A.init,B.init)`` - returns ``1`` and :math:`N_A=N_B`, then the ``mtimes`` - operator will compute for each couple :math:`(t,n)`, with - :math:`1\le t\le T_A` and :math:`1\le n\le N_A`, - ``C.data(t,n)=A.data(t,n)*B.data(t,n)``. If :math:`N_B` is - equal to :math:`1` and :math:`N_A>1`, the smaller ``dseries`` - object (``B``) is “broadcast” across the larger ``dseries`` - (``A``) so that they have compatible shapes, ``mtimes`` - operator will multiply each variable defined in ``A`` by the - variable in ``B``, observation per observation. If ``B`` is a - double scalar, then the method ``mtimes`` will multiply all - the observations/variables in ``A`` by ``B``. If ``B`` is a - row vector of length :math:`N_A`, then the ``mtimes`` method - will multiply all the observations of variable ``i`` by - ``B(i)``, for :math:`i=1,...,N_A`. If ``B`` is a column vector - of length :math:`T_A`, then the ``mtimes`` method will perform - a multiplication of all the variables by ``B``, element by + |br| Overloads the MATLAB/Octave ``mtimes`` (``*``) operator + for ``dseries`` objects and the Hadammard product (the .* + MATLAB/Octave operator). If both ``A`` and ``B`` are + ``dseries`` objects, they do not need to be defined over the + same time ranges. If ``A`` and ``B`` are ``dseries`` objects + with :math:`T_A` and :math:`_B` observations and :math:`N_A` + and :math:`N_B` variables, then :math:`N_A` must be equal to + :math:`N_B` or :math:`1` and :math:`N_B` must be equal to + :math:`N_A` or :math:`1`. If :math:`T_A=T_B`, + ``isequal(A.init,B.init)`` returns ``1`` and :math:`N_A=N_B`, + then the ``mtimes`` operator will compute for each couple + :math:`(t,n)`, with :math:`1\le t\le T_A` and :math:`1\le n\le + N_A`, ``C.data(t,n)=A.data(t,n)*B.data(t,n)``. If :math:`N_B` + is equal to :math:`1` and :math:`N_A>1`, the smaller + ``dseries`` object (``B``) is “broadcast” across the larger + ``dseries`` (``A``) so that they have compatible shapes, + ``mtimes`` operator will multiply each variable defined in + ``A`` by the variable in ``B``, observation per + observation. If ``B`` is a double scalar, then the method + ``mtimes`` will multiply all the observations/variables in + ``A`` by ``B``. If ``B`` is a row vector of length + :math:`N_A`, then the ``mtimes`` method will multiply all the + observations of variable ``i`` by ``B(i)``, for + :math:`i=1,...,N_A`. If ``B`` is a column vector of length + :math:`T_A`, then the ``mtimes`` method will perform a + multiplication of all the variables by ``B``, element by element. - .. dseriesmethod:: C = ne(A, B) + .. dseriesmethod:: B = nanmean (A[, geometric]) + + |br| Overloads the MATLAB/Octave ``nanmean`` function for + ``dseries`` objects. Returns the mean of each variable in + ``dseries`` object ``A`` ignoring the NaN values. If the + second argument is ``true`` the geometric mean is computed, + otherwise (default) the arithmetic mean is reported. + + + .. dseriesmethod:: C = ne (A, B) |br| Overloads the MATLAB/Octave ``ne`` (not equal, ``~=``) operator. ``dseries`` objects ``A`` and ``B`` must have the @@ -1882,12 +2319,14 @@ The dseries class ans = - 0 - 1 - 0 + 3x1 logical array + + 0 + 1 + 0 - .. dseriesmethod:: B = nobs(A) + .. dseriesmethod:: B = nobs (A) |br| Returns the number of observations in ``dseries`` object ``A``. @@ -1904,10 +2343,32 @@ The dseries class 10 - .. dseriesmethod:: h = plot(A) - h = plot(A, B) - h = plot(A[, ...]) - h = plot(A, B[, ...]) + .. dseriesmethod:: B = onesidedhpcycle (A[, lambda[, init]]) + onesidedhpcycle_ (A[, lambda[, init]]) + + |br| Extracts the cycle component from a ``dseries`` ``A`` + object using a one sided HP filter (with a Kalman filter) and + returns a ``dseries`` object, ``B``. The default value for + ``lambda``, the smoothing parameter, is ``1600``. By default, + if ``ìnit`` is not provided, the initial value is based on the + first two observations. + + + .. dseriesmethod:: B = onesidedhptrend (A[, lambda[, init]]) + onesidedhptrend_ (A[, lambda[, init]]) + + |br| Extracts the trend component from a ``dseries`` ``A`` + object using a one sided HP filter (with a Kalman filter) and + returns a ``dseries`` object, ``B``. The default value for + ``lambda``, the smoothing parameter, is ``1600``. By default, + if ``ìnit`` is not provided, the initial value is based on the + first two observations. + + + .. dseriesmethod:: h = plot (A) + h = plot (A, B) + h = plot (A[, ...]) + h = plot (A, B[, ...]) |br| Overloads MATLAB/Octave’s ``plot`` function for ``dseries`` objects. Returns a MATLAB/Octave plot handle, that @@ -1967,35 +2428,36 @@ The dseries class >> set(h(2),'+r'); - .. dseriesmethod:: C = plus(A, B) + .. dseriesmethod:: C = plus (A, B) - |br| Overloads the ``plus`` (``+``) operator for ``dseries`` - objects, element by element addition. If both ``A`` and ``B`` - are ``dseries`` objects, they do not need to be defined over - the same time ranges. If ``A`` and ``B`` are ``dseries`` - objects with :math:`T_A` and :math:`T_B` observations and - :math:`N_A` and :math:`N_B` variables, then :math:`N_A` must - be equal to :math:`N_B` or :math:`1` and :math:`N_B` must be - equal to :math:`N_A` or :math:`1`. If :math:`T_A=T_B`, - ``isequal(A.init,B.init)`` returns ``1`` and :math:`N_A=N_B`, - then the ``plus`` operator will compute for each couple - :math:`(t,n)`, with :math:`1\le t\le T_A` and :math:`1\le n\le - N_A`, ``C.data(t,n)=A.data(t,n)+B.data(t,n)``. If :math:`N_B` - is equal to :math:`1` and :math:`N_A>1`, the smaller - ``dseries`` object (``B``) is “broadcast” across the larger - ``dseries`` (``A``) so that they have compatible shapes, the - plus operator will add the variable defined in ``B`` to each - variable in ``A``. If ``B`` is a double scalar, then the - method ``plus`` will add ``B`` to all the - observations/variables in ``A``. If ``B`` is a row vector of - length :math:`N_A`, then the ``plus`` method will add ``B(i)`` - to all the observations of variable ``i``, for - :math:`i=1,...,N_A`. If ``B`` is a column vector of length - :math:`T_A`, then the ``plus`` method will add ``B`` to all - the variables. + |br| Overloads the MATLAB/Octave ``plus`` (``+``) operator for + ``dseries`` objects, element by element addition. If both + ``A`` and ``B`` are ``dseries`` objects, they do not need to + be defined over the same time ranges. If ``A`` and ``B`` are + ``dseries`` objects with :math:`T_A` and :math:`T_B` + observations and :math:`N_A` and :math:`N_B` variables, then + :math:`N_A` must be equal to :math:`N_B` or :math:`1` and + :math:`N_B` must be equal to :math:`N_A` or :math:`1`. If + :math:`T_A=T_B`, ``isequal(A.init,B.init)`` returns ``1`` and + :math:`N_A=N_B`, then the ``plus`` operator will compute for + each couple :math:`(t,n)`, with :math:`1\le t\le T_A` and + :math:`1\le n\le N_A`, + ``C.data(t,n)=A.data(t,n)+B.data(t,n)``. If :math:`N_B` is + equal to :math:`1` and :math:`N_A>1`, the smaller ``dseries`` + object (``B``) is “broadcast” across the larger ``dseries`` + (``A``) so that they have compatible shapes, the plus operator + will add the variable defined in ``B`` to each variable in + ``A``. If ``B`` is a double scalar, then the method ``plus`` + will add ``B`` to all the observations/variables in ``A``. If + ``B`` is a row vector of length :math:`N_A`, then the ``plus`` + method will add ``B(i)`` to all the observations of variable + ``i``, for :math:`i=1,...,N_A`. If ``B`` is a column vector of + length :math:`T_A`, then the ``plus`` method will add ``B`` to + all the variables. - .. dseriesmethod:: C = pop(A[, B]) + .. dseriesmethod:: C = pop (A[, B]) + pop_ (A[, B]) |br| Removes variable ``B`` from ``dseries`` object ``A``. By default, if the second argument is not provided, the last @@ -2016,8 +2478,10 @@ The dseries class 3Y | 1 | 1 - .. dseriesmethod:: B = qdiff(A) - B = qgrowth(A) + .. dseriesmethod:: B = qdiff (A) + B = qgrowth (A) + qdiff_ (A) + qgrowth_ (A) |br| Computes quarterly differences or growth rates. @@ -2030,7 +2494,7 @@ The dseries class ts1 is a dseries object: - | qdiff(Variable_1) + | Variable_1 1950Q1 | NaN 1950Q2 | 1 1950Q3 | 1 @@ -2041,7 +2505,7 @@ The dseries class ts1 is a dseries object: - | qdiff(Variable_1) + | Variable_1 1950M1 | NaN 1950M2 | NaN 1950M3 | NaN @@ -2050,7 +2514,8 @@ The dseries class 1950M6 | 3 - .. dseriesmethod:: C = remove(A, B) + .. dseriesmethod:: C = remove (A, B) + remove_ (A, B) |br| Alias for the ``pop`` method with two arguments. Removes variable ``B`` from ``dseries`` object ``A``. @@ -2083,10 +2548,13 @@ The dseries class implicit loops can. - .. dseriesmethod:: B = rename(A,oldname,newname) + .. dseriesmethod:: B = rename (A, oldname, newname) + rename_ (A, oldname, newname) |br| Rename variable ``oldname`` to ``newname`` in ``dseries`` - object ``A``. Returns a ``dseries`` object.`` + object ``A``. Returns a ``dseries`` object. If more than one + variable needs to be renamed, it is possible to pass cells of + char arrays as second and third arguments. *Example* @@ -2102,33 +2570,34 @@ The dseries class 2Y | 1 | 1 - .. dseriesmethod:: C = rename(A,newname) + .. dseriesmethod:: C = rename (A, newname) + rename_ (A, newname) |br| Replace the names in ``A`` with those passed in the cell string array ``newname``. ``newname`` must have the same - number of cells as ``A`` has ``dseries``. Returns a - ``dseries`` object. + number of elements as ``dseries`` object ``A`` has + variables. Returns a ``dseries`` object. *Example* :: >> ts0 = dseries(ones(2,3)); - >> ts1 = ts0.rename({'Tree','Worst','President'}) + >> ts1 = ts0.rename({'TinkyWinky','Dipsy','LaaLaa'}) ts1 is a dseries object: - | Bush | Worst | President - 1Y | 1 | 1 | 1 - 2Y | 1 | 1 | 1 + | TinkyWinky | Dipsy | LaaLaa + 1Y | 1 | 1 | 1 + 2Y | 1 | 1 | 1 - .. dseriesmethod:: save(A, basename[, format]) + .. dseriesmethod:: save (A, basename[, format]) |br| Overloads the MATLAB/Octave ``save`` function and saves - ``dseries`` object ``A`` to disk. Possible formats are ``csv`` + ``dseries`` object ``A`` to disk. Possible formats are ``mat`` (this is the default), ``m`` (MATLAB/Octave script), and - ``mat`` (MATLAB binary data file). The name of the file + ``csv`` (MATLAB binary data file). The name of the file without extension is specified by ``basename``. *Example* @@ -2136,7 +2605,7 @@ The dseries class :: >> ts0 = dseries(ones(2,2)); - >> ts0.save('ts0'); + >> ts0.save('ts0', 'csv'); The last command will create a file ts0.csv with the following content:: @@ -2158,6 +2627,8 @@ The dseries class NAMES__ = {'Variable_1'; 'Variable_2'}; TEX__ = {'Variable_{1}'; 'Variable_{2}'}; + OPS__ = {}; + TAGS__ = struct(); Variable_1 = [ 1 @@ -2217,8 +2688,34 @@ The dseries class 1 3 - .. dseriesmethod:: B = tex_rename(A, name, newtexname) - B = tex_rename(A, newtexname) + .. dseriesmethod:: B = std (A[, geometric]) + + |br| Overloads the MATLAB/Octave ``std`` function for + ``dseries`` objects. Returns the standard deviation of each + variable in ``dseries`` object ``A``. If the second argument + is ``true`` the geometric standard deviation is computed + (default value of the second argument is ``false``). + + + .. dseriesmethod:: A = tag (A, a[, b, c]) + + |br| Add a tag to a variable in ``dseries`` object ``A``. + + *Example* + + :: + + >> ts = dseries(randn(10, 3)); + >> tag(ts, 'type'); % Define a tag name. + >> tag(ts, 'type', 'Variable_1', 'Stock'); + >> tag(ts, 'type', 'Variable_2', 'Flow'); + >> tag(ts, 'type', 'Variable_3', 'Stock'); + + + .. dseriesmethod:: B = tex_rename (A, name, newtexname) + B = tex_rename (A, newtexname) + tex_rename_ (A, name, newtexname) + tex_rename_ (A, newtexname) |br| Redefines the tex name of variable ``name`` to ``newtexname`` in ``dseries`` object ``A``. Returns a @@ -2250,7 +2747,7 @@ The dseries class ts1 is a dseries object: - | -Variable_1 + | Variable_1 1Y | -1 @@ -2281,7 +2778,7 @@ The dseries class 1950Q4 | 0.11171 | 0.67865 - .. dseriesmethod:: B = vobs(A) + .. dseriesmethod:: B = vobs (A) |br| Returns the number of variables in ``dseries`` object ``A``. @@ -2298,7 +2795,9 @@ The dseries class 2 -.. dseriesmethod:: B = ydiff(A) - B = ygrowth(A) +.. dseriesmethod:: B = ydiff (A) + B = ygrowth (A) + ydiff_ (A) + ygrowth_ (A) |br| Computes yearly differences or growth rates. diff --git a/doc/manual/utils/dynare_dom.py b/doc/manual/utils/dynare_dom.py index 6a2855913..82d83ead5 100644 --- a/doc/manual/utils/dynare_dom.py +++ b/doc/manual/utils/dynare_dom.py @@ -45,7 +45,7 @@ from sphinx.util.docfields import Field, GroupedField, TypedField class DynObject(ObjectDescription): has_arguments = True display_prefix = None - allow_nesting = False + allow_nesting = False def handle_signature(self, sig, signode): sig = sig.strip() @@ -76,9 +76,9 @@ class DynObject(ObjectDescription): if self.display_prefix: signode += addnodes.desc_annotation(self.display_prefix, self.display_prefix) - + signode += addnodes.desc_name(name, name) - + if self.has_arguments: if not arglist: signode += addnodes.desc_parameterlist() @@ -94,7 +94,7 @@ class DynObject(ObjectDescription): signode['first'] = not self.names self.state.document.note_explicit_target(signode) objects = self.env.domaindata['dynare']['objects'] - + if fullname in objects: self.state_machine.reporter.warning( 'duplicate object description of %s, ' % fullname + @@ -222,9 +222,9 @@ class DynSimpleObject(ObjectDescription): if self.display_prefix: signode += addnodes.desc_annotation(self.display_prefix, self.display_prefix) - + signode += addnodes.desc_name(name, name) - return fullname, prefix + return fullname, prefix def add_target_and_index(self, name_obj, sig, signode): fullname = name_obj[0] @@ -291,40 +291,40 @@ class DynareDomain(Domain): name = 'dynare' label = 'Dynare' object_types = { - 'function': ObjType(l_('function'), 'func'), - 'datesmethod': ObjType(l_('method'), 'datmeth'), - 'dseriesmethod': ObjType(l_('method'), 'dsermeth'), - 'reportingmethod': ObjType(l_('method'), 'repmeth'), - 'matcomm': ObjType(l_('matlab command'), 'mcomm'), - 'command': ObjType(l_('command'), 'comm'), - 'class': ObjType(l_('class'), 'class'), - 'block': ObjType(l_('block'), 'bck'), - 'confblock': ObjType(l_('config block'), 'cbck'), - 'macrodir': ObjType(l_('macro directive'), 'mdir'), - 'construct': ObjType(l_('constructor'), 'cstr'), - 'matvar': ObjType(l_('matlab variable'), 'mvar'), - 'specvar': ObjType(l_('special variable'), 'svar'), - 'operator': ObjType(l_('operator'), 'op'), - 'constant': ObjType(l_('constant'), 'const'), - 'option': ObjType(l_('option'), 'opt'), + 'function': ObjType(l_('function'), 'func'), + 'datesmethod': ObjType(l_('method'), 'datmeth'), + 'dseriesmethod': ObjType(l_('method'), 'dsermeth'), + 'reportingmethod': ObjType(l_('method'), 'repmeth'), + 'matcomm': ObjType(l_('matlab command'), 'mcomm'), + 'command': ObjType(l_('command'), 'comm'), + 'class': ObjType(l_('class'), 'class'), + 'block': ObjType(l_('block'), 'bck'), + 'confblock': ObjType(l_('config block'), 'cbck'), + 'macrodir': ObjType(l_('macro directive'), 'mdir'), + 'construct': ObjType(l_('constructor'), 'cstr'), + 'matvar': ObjType(l_('matlab variable'), 'mvar'), + 'specvar': ObjType(l_('special variable'), 'svar'), + 'operator': ObjType(l_('operator'), 'op'), + 'constant': ObjType(l_('constant'), 'const'), + 'option': ObjType(l_('option'), 'opt'), } directives = { - 'function': DynFunction, - 'datesmethod': DatesMethod, - 'dseriesmethod': DseriesMethod, - 'reportingmethod': ReportingMethod, - 'matcomm': MatComm, - 'command': DynComm, - 'class': DynClass, - 'block': DynBlock, - 'confblock': DynConfBlock, - 'macrodir': DynMacroDir, - 'construct': Constructor, - 'matvar': MatlabVar, - 'specvar': SpecialVar, - 'operator': Operator, - 'constant': Constant, - 'option': Option, + 'function': DynFunction, + 'datesmethod': DatesMethod, + 'dseriesmethod': DseriesMethod, + 'reportingmethod': ReportingMethod, + 'matcomm': MatComm, + 'command': DynComm, + 'class': DynClass, + 'block': DynBlock, + 'confblock': DynConfBlock, + 'macrodir': DynMacroDir, + 'construct': Constructor, + 'matvar': MatlabVar, + 'specvar': SpecialVar, + 'operator': Operator, + 'constant': Constant, + 'option': Option, } roles = { 'func': DynareXRefRole(), @@ -334,19 +334,19 @@ class DynareDomain(Domain): 'mcomm': DynareXRefRole(), 'comm': DynareXRefRole(), 'class': DynareXRefRole(), - 'bck': DynareXRefRole(), + 'bck': DynareXRefRole(), 'cbck': DynareXRefRole(), 'mdir': DynareXRefRole(), - 'cstr': DynareXRefRole(), - 'mvar': DynareXRefRole(), - 'svar': DynareXRefRole(), - 'op': DynareXRefRole(), + 'cstr': DynareXRefRole(), + 'mvar': DynareXRefRole(), + 'svar': DynareXRefRole(), + 'op': DynareXRefRole(), 'const': DynareXRefRole(), - 'opt': DynareXRefRole(), + 'opt': DynareXRefRole(), } initial_data = { 'objects': {}, - } + } def clear_doc(self, docname): for fullname, (fn, _l) in list(self.data['objects'].items()): diff --git a/doc/manual/utils/dynare_lex.py b/doc/manual/utils/dynare_lex.py index b695309aa..818d5cba3 100644 --- a/doc/manual/utils/dynare_lex.py +++ b/doc/manual/utils/dynare_lex.py @@ -33,53 +33,53 @@ class DynareLexer(RegexLexer): filenames = ['*.mod'] commands = ( - "dynare","var","varexo","varexo_det","parameters","change_type","model_local_variable", - "predetermined_variables","trend_var","log_trend_var","external_function", - "write_latex_original_model","write_latex_dynamic_model", - "write_latex_static_model","resid","initval_file","histval_file","dsample", - "periods","values","corr","steady","check","model_diagnostics","model_info", - "print_bytecode_dynamic_model"," print_bytecode_static_model", - "perfect_foresight_setup","perfect_foresight_solver","simul","stoch_simul", - "extended_path","varobs","estimation","unit_root_vars","bvar_density", - "model_comparison","shock_decomposition","realtime_shock_decomposition", - "plot_shock_decomposition","calib_smoother","forecast", - "conditional_forecast","plot_conditional_forecast","bvar_forecast", - "smoother2histval","osr","osr_params","ramsey_model","ramsey_policy", - "discretionary_policy","planner_objective","dynare_sensitivity", - "markov_switching","svar","sbvar","ms_estimation","ms_simulation", - "ms_compute_mdd","ms_compute_probabilities","ms_irf","ms_forecast", - "ms_variance_decomposition","rplot","dynatype","dynasave","set_dynare_seed", - "save_params_and_steady_state","load_params_and_steady_state", - "dynare_version","write_latex_definitions","write_latex_parameter_table", - "write_latex_prior_table","collect_latex_files","prior_function", - "posterior_function","generate_trace_plots") + "dynare","var","varexo","varexo_det","parameters","change_type","model_local_variable", + "predetermined_variables","trend_var","log_trend_var","external_function", + "write_latex_original_model","write_latex_dynamic_model", + "write_latex_static_model","resid","initval_file","histval_file","dsample", + "periods","values","corr","steady","check","model_diagnostics","model_info", + "print_bytecode_dynamic_model"," print_bytecode_static_model", + "perfect_foresight_setup","perfect_foresight_solver","simul","stoch_simul", + "extended_path","varobs","estimation","unit_root_vars","bvar_density", + "model_comparison","shock_decomposition","realtime_shock_decomposition", + "plot_shock_decomposition","calib_smoother","forecast", + "conditional_forecast","plot_conditional_forecast","bvar_forecast", + "smoother2histval","osr","osr_params","ramsey_model","ramsey_policy", + "discretionary_policy","planner_objective","dynare_sensitivity", + "markov_switching","svar","sbvar","ms_estimation","ms_simulation", + "ms_compute_mdd","ms_compute_probabilities","ms_irf","ms_forecast", + "ms_variance_decomposition","rplot","dynatype","dynasave","set_dynare_seed", + "save_params_and_steady_state","load_params_and_steady_state", + "dynare_version","write_latex_definitions","write_latex_parameter_table", + "write_latex_prior_table","collect_latex_files","prior_function", + "posterior_function","generate_trace_plots","evaluate_planner_objective") report_commands = ("report","addPage","addSection","addGraph","addTable", - "addSeries","addParagraph","addVspace","write","compile") + "addSeries","addParagraph","addVspace","write","compile") operators = ( "STEADY_STATE","EXPECTATION") macro_dirs = ( - "@#includepath", "@#include", "@#define", "@#if", - "@#ifdef", "@#ifndef", "@#else","@#endif", - "@#for", "@#endfor", "@#echo", "@#error") + "@#includepath", "@#include", "@#define", "@#if", + "@#ifdef", "@#ifndef", "@#else","@#endif", + "@#for", "@#endfor", "@#echo", "@#error") builtin_constants = ( - "inf", "nan") + "inf", "nan") tokens = { 'root': [ (r'\s*(%|//).*$', Comment), (words(( - 'model','steady_state_model','initval','endval','histval', - 'shocks','mshocks','homotopy_setup','observation_trends', - 'estimated_params','estimated_params_init','estimated_params_bounds', - 'shock_groups','conditional_forecast_paths','optim_weights', - 'osr_params_bounds','ramsey_constraints','irf_calibration', - 'moment_calibration','identification','svar_identification', - 'verbatim','end','node','cluster','paths','hooks'), prefix=r'\b', suffix=r'\s*\b'),Keyword.Reserved), + 'model','steady_state_model','initval','endval','histval','epilogue', + 'shocks','mshocks','homotopy_setup','observation_trends', + 'estimated_params','estimated_params_init','estimated_params_bounds', + 'shock_groups','conditional_forecast_paths','optim_weights', + 'osr_params_bounds','ramsey_constraints','irf_calibration', + 'moment_calibration','identification','svar_identification', + 'verbatim','end','node','cluster','paths','hooks'), prefix=r'\b', suffix=r'\s*\b'),Keyword.Reserved), (words(commands + report_commands, prefix=r'\b', suffix=r'\s*\b'), Name.Entity), @@ -92,20 +92,19 @@ class DynareLexer(RegexLexer): (r'\s*[a-zA-Z_]\s*', Name), - (r'\s*(\d+\.\d+|\d*\.\d+)([eEf][+-]?[0-9]+)?\s*', Number.Float), (r'\s*\d+[eEf][+-]?[0-9]+\s*', Number.Float), (r'\s*\d+\s*', Number.Integer), - - (r'"[^"]*"', String), + + (r'"[^"]*"', String), (r"`[^`]*'", String), - (r"'[^']*'", String), - - (r'\s*(-|\+|\*|\/|\^)\s*', Operator), + (r"'[^']*'", String), + + (r'\s*(-|\+|\*|\/|\^)\s*', Operator), (r'\s*(==|<=|>=|~=|<|>|&&|!)\s*', Operator), - (r'\s*[\[\](){}:@.,\|]\s*', Punctuation), - (r'\s*(=|:|;|>>|#|\$)\s*', Punctuation), - ] + (r'\s*[\[\](){}:@.,\|]\s*', Punctuation), + (r'\s*(=|:|;|>>|#|\$)\s*', Punctuation), + ] } diff --git a/dynare++/Makefile.am b/dynare++/Makefile.am index 36d74d5ce..806c55dbe 100644 --- a/dynare++/Makefile.am +++ b/dynare++/Makefile.am @@ -1 +1,11 @@ SUBDIRS = utils/cc sylv parser/cc tl doc integ kord src tests + +EXTRA_DIST = dynare_simul + +install-exec-local: + $(MKDIR_P) $(DESTDIR)$(pkglibdir)/dynare++ + cp -r dynare_simul/* $(DESTDIR)$(pkglibdir)/dynare++ + +uninstall-local: + rm -rf $(DESTDIR)$(pkglibdir)/dynare++ + diff --git a/dynare++/dynare_simul/dynare_simul.m b/dynare++/dynare_simul/dynare_simul.m new file mode 100644 index 000000000..095d417b7 --- /dev/null +++ b/dynare++/dynare_simul/dynare_simul.m @@ -0,0 +1,176 @@ +% +% SYNOPSIS +% +% r = dynare_simul(name, shocks) +% r = dynare_simul(name, prefix, shocks) +% r = dynare_simul(name, shocks, start) +% r = dynare_simul(name, prefix, shocks, start) +% +% name name of MAT-file produced by dynare++ +% prefix prefix of variables in the MAT-file +% shocks matrix of shocks +% start zero period value +% +% Note that this file requires the dynare_simul_ DLL to be in the path. +% This DLL is distributed with Dynare, under the mex/matlab or mex/octave +% subdirectory. +% +% SEMANTICS +% +% The command reads a decision rule from the MAT-file having the given +% prefix. Then it starts simulating the decision rule with zero time value +% equal to the given start. It uses the given shocks for the simulation. If +% the start is not given, the state about which the decision rule is +% centralized is taken (called fix point, or stochastic steady state, take +% your pick). +% +% prefix Use the prefix with which you called dynare++, the default +% prefix in dynare++ is 'dyn'. +% shocks Number of rows must be a number of exogenous shocks, +% number of columns gives the number of simulated +% periods. NaNs and Infs in the matrix are substitued by +% draws from the normal distribution using the covariance +% matrix given in the model file. +% start Vector of endogenous variables in the ordering given by +% _vars. +% +% Seed for random generator is derived from calling rand(1,1). Therefore, +% seeding can be controlled with rand('state') and rand('state',some_seed). +% +% EXAMPLES +% +% All examples suppose that the prefix is 'dyn' and that your_model.mat +% has been loaded into Matlab. +% +% 1. response to permanent negative shock to the third exo var EPS3 for +% 100 periods +% +% shocks = zeros(4,100); % 4 exogenous variables in the model +% shocks(dyn_i_EPS3,:) = -0.1; % the permanent shock to EPS3 +% r = dynare_simul('your_model.mat',shocks); +% +% 2. one stochastic simulation for 100 periods +% +% shocks = zeros(4,100)./0; % put NaNs everywhere +% r = dynare_simul('your_model.mat',shocks); +% +% 3. one stochastic simulation starting at 75% undercapitalized economy +% +% shocks = zeros(4,100)./0; % put NaNs everywhere +% ystart = dyn_ss; % get copy of DR fix point +% ystart(dyn_i_K) = 0.75*dyn_ss(dyn_i_K); % scale down the capital +% r = dynare_simul('your_model.mat',shocks,ystart); +% +% +% SEE ALSO +% +% "DSGE Models with Dynare++. A Tutorial.", Ondra Kamenik, 2005 + +% Copyright (C) 2005-2011, Ondra Kamenik +% Copyright (C) 2020, Dynare Team + + +function r = dynare_simul(varargin) + +if ~exist('dynare_simul_','file') + error('Can''t find dynare_simul_ DLL in the path. The simplest way to add it is to run Dynare once in this session.') +end + +% get the file name and load data +fname = varargin{1}; +load(fname); + +% set prefix, shocks, ystart +if ischar(varargin{2}) + prefix = varargin{2}; + if length(varargin) == 3 + shocks = varargin{3}; + ystart = NaN; + elseif length(varargin) == 4 + shocks = varargin{3}; + ystart = varargin{4}; + else + error('Wrong number of parameters.'); + end +else + prefix = 'dyn'; + if length(varargin) == 2 + shocks = varargin{2}; + ystart = NaN; + elseif length(varargin) == 3 + shocks = varargin{2}; + ystart = varargin{3}; + else + error('Wrong number of parameters.'); + end +end + +% load all needed variables but prefix_g_* +if exist([prefix '_nstat'],'var') + nstat = eval([prefix '_nstat']); +else + error(['Could not find variable ' prefix '_nstat in workspace']); +end +if exist([prefix '_npred'],'var') + npred = eval([prefix '_npred']); +else + error(['Could not find variable ' prefix '_npred in workspace']); +end +if exist([prefix '_nboth'],'var') + nboth = eval([prefix '_nboth']); +else + error(['Could not find variable ' prefix '_nboth in workspace']); +end +if exist([prefix '_nforw'],'var') + nforw = eval([prefix '_nforw']); +else + error(['Could not find variable ' prefix '_nforw in workspace']); +end +if exist([prefix '_ss'],'var') + ss = eval([prefix '_ss']); +else + error(['Could not find variable ' prefix '_ss in workspace']); +end +if exist([prefix '_vcov_exo'],'var') + vcov_exo = eval([prefix '_vcov_exo']); +else + error(['Could not find variable ' prefix '_vcov_exo in workspace']); +end +nexog = size(vcov_exo,1); + +if isnan(ystart) + ystart = ss; +end + +% newer version of dynare++ doesn't return prefix_g_0, we make it here if +% it does not exist in workspace +g_zero = [prefix '_g_0']; +if ~exist(g_zero,'var') + dr.g_0=zeros(nstat+npred+nboth+nforw,1); +else + dr.g_0=eval(g_zero); +end + +% make derstr a string of comma seperated existing prefix_g_* +order = 1; +cont = 1; +while cont == 1 + g_ord = [prefix '_g_' num2str(order)]; + if exist(g_ord,'var') + dr.(['g_' num2str(order)])=eval(g_ord); + order = order + 1; + else + cont = 0; + end +end + +% set seed +seed = ceil(10000*rand(1,1)); + +% call dynare_simul_ +[err,r]=dynare_simul_(order-1,nstat,npred,nboth,nforw,... + nexog,ystart,shocks,vcov_exo,seed,ss,dr); + +if err + error('Simulation failed') +end \ No newline at end of file diff --git a/dynare++/integ/cc/precalc_quadrature.hh b/dynare++/integ/cc/precalc_quadrature.hh index f997e0f17..1aa3f04bd 100644 --- a/dynare++/integ/cc/precalc_quadrature.hh +++ b/dynare++/integ/cc/precalc_quadrature.hh @@ -29,1042 +29,1045 @@ static const int gh_num_levels = 26; // Number of points in each level -static const int gh_num_points[] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 30, 32, 40, 50, 60, 64 -}; +static const int gh_num_points[] = + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 30, 32, 40, 50, 60, 64 + }; // Weights, starting with the first level -static const double gh_weights[] = { - // weights 1 = √π - 1.77245385090551588191942755656782537698745727539062, - // weights 2 - 0.886226925452758013649083741671e+00, - 0.886226925452758013649083741671e+00, - // weights 3 - 0.295408975150919337883027913890e+00, - 0.118163590060367735153211165556e+01, - 0.295408975150919337883027913890e+00, - // weights 4 - 0.813128354472451771430345571899e-01, - 0.804914090005512836506049184481e+00, - 0.804914090005512836506049184481e+00, - 0.813128354472451771430345571899e-01, - // weights 5 - 0.199532420590459132077434585942e-01, - 0.393619323152241159828495620852e+00, - 0.945308720482941881225689324449e+00, - 0.393619323152241159828495620852e+00, - 0.199532420590459132077434585942e-01, - // weights 6 - 0.453000990550884564085747256463e-02, - 0.157067320322856643916311563508e+00, - 0.724629595224392524091914705598e+00, - 0.724629595224392524091914705598e+00, - 0.157067320322856643916311563508e+00, - 0.453000990550884564085747256463e-02, - // weights 7 - 0.971781245099519154149424255939e-03, - 0.545155828191270305921785688417e-01, - 0.425607252610127800520317466666e+00, - 0.810264617556807326764876563813e+00, - 0.425607252610127800520317466666e+00, - 0.545155828191270305921785688417e-01, - 0.971781245099519154149424255939e-03, - // weights 8 - 0.199604072211367619206090452544e-03, - 0.170779830074134754562030564364e-01, - 0.207802325814891879543258620286e+00, - 0.661147012558241291030415974496e+00, - 0.661147012558241291030415974496e+00, - 0.207802325814891879543258620286e+00, - 0.170779830074134754562030564364e-01, - 0.199604072211367619206090452544e-03, - // weights 9 - 0.396069772632643819045862946425e-04, - 0.494362427553694721722456597763e-02, - 0.884745273943765732879751147476e-01, - 0.432651559002555750199812112956e+00, - 0.720235215606050957124334723389e+00, - 0.432651559002555750199812112956e+00, - 0.884745273943765732879751147476e-01, - 0.494362427553694721722456597763e-02, - 0.396069772632643819045862946425e-04, - // weights 10 - 0.764043285523262062915936785960e-05, - 0.134364574678123269220156558585e-02, - 0.338743944554810631361647312776e-01, - 0.240138611082314686416523295006e+00, - 0.610862633735325798783564990433e+00, - 0.610862633735325798783564990433e+00, - 0.240138611082314686416523295006e+00, - 0.338743944554810631361647312776e-01, - 0.134364574678123269220156558585e-02, - 0.764043285523262062915936785960e-05, - // weights 11 - 0.143956039371425822033088366032e-05, - 0.346819466323345510643413772940e-03, - 0.119113954449115324503874202916e-01, - 0.117227875167708503381788649308e+00, - 0.429359752356125028446073598601e+00, - 0.654759286914591779203940657627e+00, - 0.429359752356125028446073598601e+00, - 0.117227875167708503381788649308e+00, - 0.119113954449115324503874202916e-01, - 0.346819466323345510643413772940e-03, - 0.143956039371425822033088366032e-05, - // weights 12 - 0.265855168435630160602311400877e-06, - 0.857368704358785865456906323153e-04, - 0.390539058462906185999438432620e-02, - 0.516079856158839299918734423606e-01, - 0.260492310264161129233396139765e+00, - 0.570135236262479578347113482275e+00, - 0.570135236262479578347113482275e+00, - 0.260492310264161129233396139765e+00, - 0.516079856158839299918734423606e-01, - 0.390539058462906185999438432620e-02, - 0.857368704358785865456906323153e-04, - 0.265855168435630160602311400877e-06, - // weights 13 - 0.482573185007313108834997332342e-07, - 0.204303604027070731248669432937e-04, - 0.120745999271938594730924899224e-02, - 0.208627752961699392166033805050e-01, - 0.140323320687023437762792268873e+00, - 0.421616296898543221746893558568e+00, - 0.604393187921161642342099068579e+00, - 0.421616296898543221746893558568e+00, - 0.140323320687023437762792268873e+00, - 0.208627752961699392166033805050e-01, - 0.120745999271938594730924899224e-02, - 0.204303604027070731248669432937e-04, - 0.482573185007313108834997332342e-07, - // weights 14 - 0.862859116812515794532041783429e-08, - 0.471648435501891674887688950105e-05, - 0.355092613551923610483661076691e-03, - 0.785005472645794431048644334608e-02, - 0.685055342234652055387163312367e-01, - 0.273105609064246603352569187026e+00, - 0.536405909712090149794921296776e+00, - 0.536405909712090149794921296776e+00, - 0.273105609064246603352569187026e+00, - 0.685055342234652055387163312367e-01, - 0.785005472645794431048644334608e-02, - 0.355092613551923610483661076691e-03, - 0.471648435501891674887688950105e-05, - 0.862859116812515794532041783429e-08, - // weights 15 - 0.152247580425351702016062666965e-08, - 0.105911554771106663577520791055e-05, - 0.100004441232499868127296736177e-03, - 0.277806884291277589607887049229e-02, - 0.307800338725460822286814158758e-01, - 0.158488915795935746883839384960e+00, - 0.412028687498898627025891079568e+00, - 0.564100308726417532852625797340e+00, - 0.412028687498898627025891079568e+00, - 0.158488915795935746883839384960e+00, - 0.307800338725460822286814158758e-01, - 0.277806884291277589607887049229e-02, - 0.100004441232499868127296736177e-03, - 0.105911554771106663577520791055e-05, - 0.152247580425351702016062666965e-08, - // weights 16 - 0.265480747401118224470926366050e-09, - 0.232098084486521065338749423185e-06, - 0.271186009253788151201891432244e-04, - 0.932284008624180529914277305537e-03, - 0.128803115355099736834642999312e-01, - 0.838100413989858294154207349001e-01, - 0.280647458528533675369463335380e+00, - 0.507929479016613741913517341791e+00, - 0.507929479016613741913517341791e+00, - 0.280647458528533675369463335380e+00, - 0.838100413989858294154207349001e-01, - 0.128803115355099736834642999312e-01, - 0.932284008624180529914277305537e-03, - 0.271186009253788151201891432244e-04, - 0.232098084486521065338749423185e-06, - 0.265480747401118224470926366050e-09, - // weights 17 - 0.458057893079863330580889281222e-10, - 0.497707898163079405227863353715e-07, - 0.711228914002130958353327376218e-05, - 0.298643286697753041151336643059e-03, - 0.506734995762753791170069495879e-02, - 0.409200341495762798094994877854e-01, - 0.172648297670097079217645196219e+00, - 0.401826469470411956577635085257e+00, - 0.530917937624863560331883103379e+00, - 0.401826469470411956577635085257e+00, - 0.172648297670097079217645196219e+00, - 0.409200341495762798094994877854e-01, - 0.506734995762753791170069495879e-02, - 0.298643286697753041151336643059e-03, - 0.711228914002130958353327376218e-05, - 0.497707898163079405227863353715e-07, - 0.458057893079863330580889281222e-10, - // weights 18 - 0.782819977211589102925147471012e-11, - 0.104672057957920824443559608435e-07, - 0.181065448109343040959702385911e-05, - 0.918112686792940352914675407371e-04, - 0.188852263026841789438175325426e-02, - 0.186400423875446519219315221973e-01, - 0.973017476413154293308537234155e-01, - 0.284807285669979578595606820713e+00, - 0.483495694725455552876410522141e+00, - 0.483495694725455552876410522141e+00, - 0.284807285669979578595606820713e+00, - 0.973017476413154293308537234155e-01, - 0.186400423875446519219315221973e-01, - 0.188852263026841789438175325426e-02, - 0.918112686792940352914675407371e-04, - 0.181065448109343040959702385911e-05, - 0.104672057957920824443559608435e-07, - 0.782819977211589102925147471012e-11, - // weights 19 - 0.132629709449851575185289154385e-11, - 0.216305100986355475019693077221e-08, - 0.448824314722312295179447915594e-06, - 0.272091977631616257711941025214e-04, - 0.670877521407181106194696282100e-03, - 0.798886677772299020922211491861e-02, - 0.508103869090520673569908110358e-01, - 0.183632701306997074156148485766e+00, - 0.391608988613030244504042313621e+00, - 0.502974888276186530840731361096e+00, - 0.391608988613030244504042313621e+00, - 0.183632701306997074156148485766e+00, - 0.508103869090520673569908110358e-01, - 0.798886677772299020922211491861e-02, - 0.670877521407181106194696282100e-03, - 0.272091977631616257711941025214e-04, - 0.448824314722312295179447915594e-06, - 0.216305100986355475019693077221e-08, - 0.132629709449851575185289154385e-11, - // weights 20 - 0.222939364553415129252250061603e-12, - 0.439934099227318055362885145547e-09, - 0.108606937076928169399952456345e-06, - 0.780255647853206369414599199965e-05, - 0.228338636016353967257145917963e-03, - 0.324377334223786183218324713235e-02, - 0.248105208874636108821649525589e-01, - 0.109017206020023320013755033535e+00, - 0.286675505362834129719659706228e+00, - 0.462243669600610089650328639861e+00, - 0.462243669600610089650328639861e+00, - 0.286675505362834129719659706228e+00, - 0.109017206020023320013755033535e+00, - 0.248105208874636108821649525589e-01, - 0.324377334223786183218324713235e-02, - 0.228338636016353967257145917963e-03, - 0.780255647853206369414599199965e-05, - 0.108606937076928169399952456345e-06, - 0.439934099227318055362885145547e-09, - 0.222939364553415129252250061603e-12, - // weights 30 - 0.290825470013122622941102747365e-20, - 0.281033360275090370876277491534e-16, - 0.287860708054870606219239791142e-13, - 0.810618629746304420399344796173e-11, - 0.917858042437852820850075742492e-09, - 0.510852245077594627738963204403e-07, - 0.157909488732471028834638794022e-05, - 0.293872522892298764150118423412e-04, - 0.348310124318685523420995323183e-03, - 0.273792247306765846298942568953e-02, - 0.147038297048266835152773557787e-01, - 0.551441768702342511680754948183e-01, - 0.146735847540890099751693643152e+00, - 0.280130930839212667413493211293e+00, - 0.386394889541813862555601849165e+00, - 0.386394889541813862555601849165e+00, - 0.280130930839212667413493211293e+00, - 0.146735847540890099751693643152e+00, - 0.551441768702342511680754948183e-01, - 0.147038297048266835152773557787e-01, - 0.273792247306765846298942568953e-02, - 0.348310124318685523420995323183e-03, - 0.293872522892298764150118423412e-04, - 0.157909488732471028834638794022e-05, - 0.510852245077594627738963204403e-07, - 0.917858042437852820850075742492e-09, - 0.810618629746304420399344796173e-11, - 0.287860708054870606219239791142e-13, - 0.281033360275090370876277491534e-16, - 0.290825470013122622941102747365e-20, - // weights 32 - 0.731067642736e-22, - 0.923173653649e-18, - 0.119734401709e-14, - 0.421501021125e-12, - 0.593329146300e-10, - 0.409883216476e-08, - 0.157416779254e-06, - 0.365058512955e-05, - 0.541658406172e-04, - 0.536268365526e-03, - 0.365489032664e-02, - 0.175534288315e-01, - 0.604581309557e-01, - 0.151269734076e+00, - 0.277458142302e+00, - 0.375238352592e+00, - 0.375238352592e+00, - 0.277458142302e+00, - 0.151269734076e+00, - 0.604581309557e-01, - 0.175534288315e-01, - 0.365489032664e-02, - 0.536268365526e-03, - 0.541658406172e-04, - 0.365058512955e-05, - 0.157416779254e-06, - 0.409883216476e-08, - 0.593329146300e-10, - 0.421501021125e-12, - 0.119734401709e-14, - 0.923173653649e-18, - 0.731067642736e-22, - // weights 40 - 0.259104371384e-28, - 0.854405696375e-24, - 0.256759336540e-20, - 0.198918101211e-17, - 0.600835878947e-15, - 0.880570764518e-13, - 0.715652805267e-11, - 0.352562079135e-09, - 0.112123608322e-07, - 0.241114416359e-06, - 0.363157615067e-05, - 0.393693398108e-04, - 0.313853594540e-03, - 0.187149682959e-02, - 0.846088800823e-02, - 0.293125655361e-01, - 0.784746058652e-01, - 0.163378732713e+00, - 0.265728251876e+00, - 0.338643277425e+00, - 0.338643277425e+00, - 0.265728251876e+00, - 0.163378732713e+00, - 0.784746058652e-01, - 0.293125655361e-01, - 0.846088800823e-02, - 0.187149682959e-02, - 0.313853594540e-03, - 0.393693398108e-04, - 0.363157615067e-05, - 0.241114416359e-06, - 0.112123608322e-07, - 0.352562079135e-09, - 0.715652805267e-11, - 0.880570764518e-13, - 0.600835878947e-15, - 0.198918101211e-17, - 0.256759336540e-20, - 0.854405696375e-24, - 0.259104371384e-28, - // weights 50 - 0.183379404857e-36, - 0.167380166790e-31, - 0.121524412340e-27, - 0.213765830835e-24, - 0.141709359957e-21, - 0.447098436530e-19, - 0.774238295702e-17, - 0.809426189344e-15, - 0.546594403180e-13, - 0.250665552389e-11, - 0.811187736448e-10, - 0.190904054379e-08, - 0.334679340401e-07, - 0.445702996680e-06, - 0.458168270794e-05, - 0.368401905377e-04, - 0.234269892109e-03, - 0.118901178175e-02, - 0.485326382616e-02, - 0.160319410684e-01, - 0.430791591566e-01, - 0.945489354768e-01, - 0.170032455676e+00, - 0.251130856331e+00, - 0.305085129203e+00, - 0.305085129203e+00, - 0.251130856331e+00, - 0.170032455676e+00, - 0.945489354768e-01, - 0.430791591566e-01, - 0.160319410684e-01, - 0.485326382616e-02, - 0.118901178175e-02, - 0.234269892109e-03, - 0.368401905377e-04, - 0.458168270794e-05, - 0.445702996680e-06, - 0.334679340401e-07, - 0.190904054379e-08, - 0.811187736448e-10, - 0.250665552389e-11, - 0.546594403180e-13, - 0.809426189344e-15, - 0.774238295702e-17, - 0.447098436530e-19, - 0.141709359957e-21, - 0.213765830835e-24, - 0.121524412340e-27, - 0.167380166790e-31, - 0.183379404857e-36, - // weights 60 - 0.110958724796e-44, - 0.243974758810e-39, - 0.377162672698e-35, - 0.133255961176e-31, - 0.171557314767e-28, - 0.102940599693e-25, - 0.334575695574e-23, - 0.651256725748e-21, - 0.815364047300e-19, - 0.692324790956e-17, - 0.415244410968e-15, - 0.181662457614e-13, - 0.594843051597e-12, - 0.148895734905e-10, - 0.289935901280e-09, - 0.445682277521e-08, - 0.547555461926e-07, - 0.543351613419e-06, - 0.439428693625e-05, - 0.291874190415e-04, - 0.160277334681e-03, - 0.731773556963e-03, - 0.279132482894e-02, - 0.893217836028e-02, - 0.240612727660e-01, - 0.547189709320e-01, - 0.105298763697e+00, - 0.171776156918e+00, - 0.237868904958e+00, - 0.279853117522e+00, - 0.279853117522e+00, - 0.237868904958e+00, - 0.171776156918e+00, - 0.105298763697e+00, - 0.547189709320e-01, - 0.240612727660e-01, - 0.893217836028e-02, - 0.279132482894e-02, - 0.731773556963e-03, - 0.160277334681e-03, - 0.291874190415e-04, - 0.439428693625e-05, - 0.543351613419e-06, - 0.547555461926e-07, - 0.445682277521e-08, - 0.289935901280e-09, - 0.148895734905e-10, - 0.594843051597e-12, - 0.181662457614e-13, - 0.415244410968e-15, - 0.692324790956e-17, - 0.815364047300e-19, - 0.651256725748e-21, - 0.334575695574e-23, - 0.102940599693e-25, - 0.171557314767e-28, - 0.133255961176e-31, - 0.377162672698e-35, - 0.243974758810e-39, - 0.110958724796e-44, - // weights 64 - 0.553570653584e-48, - 0.167974799010e-42, - 0.342113801099e-38, - 0.155739062462e-34, - 0.254966089910e-31, - 0.192910359546e-28, - 0.786179778889e-26, - 0.191170688329e-23, - 0.298286278427e-21, - 0.315225456649e-19, - 0.235188471067e-17, - 0.128009339117e-15, - 0.521862372645e-14, - 0.162834073070e-12, - 0.395917776693e-11, - 0.761521725012e-10, - 0.117361674232e-08, - 0.146512531647e-07, - 0.149553293672e-06, - 0.125834025103e-05, - 0.878849923082e-05, - 0.512592913577e-04, - 0.250983698512e-03, - 0.103632909950e-02, - 0.362258697852e-02, - 0.107560405098e-01, - 0.272031289536e-01, - 0.587399819634e-01, - 0.108498349306e+00, - 0.171685842349e+00, - 0.232994786062e+00, - 0.271377424940e+00, - 0.271377424940e+00, - 0.232994786062e+00, - 0.171685842349e+00, - 0.108498349306e+00, - 0.587399819634e-01, - 0.272031289536e-01, - 0.107560405098e-01, - 0.362258697852e-02, - 0.103632909950e-02, - 0.250983698512e-03, - 0.512592913577e-04, - 0.878849923082e-05, - 0.125834025103e-05, - 0.149553293672e-06, - 0.146512531647e-07, - 0.117361674232e-08, - 0.761521725012e-10, - 0.395917776693e-11, - 0.162834073070e-12, - 0.521862372645e-14, - 0.128009339117e-15, - 0.235188471067e-17, - 0.315225456649e-19, - 0.298286278427e-21, - 0.191170688329e-23, - 0.786179778889e-26, - 0.192910359546e-28, - 0.254966089910e-31, - 0.155739062462e-34, - 0.342113801099e-38, - 0.167974799010e-42, - 0.553570653584e-48 -}; +static const double gh_weights[] = + { + // weights 1 = √π + 1.77245385090551588191942755656782537698745727539062, + // weights 2 + 0.886226925452758013649083741671e+00, + 0.886226925452758013649083741671e+00, + // weights 3 + 0.295408975150919337883027913890e+00, + 0.118163590060367735153211165556e+01, + 0.295408975150919337883027913890e+00, + // weights 4 + 0.813128354472451771430345571899e-01, + 0.804914090005512836506049184481e+00, + 0.804914090005512836506049184481e+00, + 0.813128354472451771430345571899e-01, + // weights 5 + 0.199532420590459132077434585942e-01, + 0.393619323152241159828495620852e+00, + 0.945308720482941881225689324449e+00, + 0.393619323152241159828495620852e+00, + 0.199532420590459132077434585942e-01, + // weights 6 + 0.453000990550884564085747256463e-02, + 0.157067320322856643916311563508e+00, + 0.724629595224392524091914705598e+00, + 0.724629595224392524091914705598e+00, + 0.157067320322856643916311563508e+00, + 0.453000990550884564085747256463e-02, + // weights 7 + 0.971781245099519154149424255939e-03, + 0.545155828191270305921785688417e-01, + 0.425607252610127800520317466666e+00, + 0.810264617556807326764876563813e+00, + 0.425607252610127800520317466666e+00, + 0.545155828191270305921785688417e-01, + 0.971781245099519154149424255939e-03, + // weights 8 + 0.199604072211367619206090452544e-03, + 0.170779830074134754562030564364e-01, + 0.207802325814891879543258620286e+00, + 0.661147012558241291030415974496e+00, + 0.661147012558241291030415974496e+00, + 0.207802325814891879543258620286e+00, + 0.170779830074134754562030564364e-01, + 0.199604072211367619206090452544e-03, + // weights 9 + 0.396069772632643819045862946425e-04, + 0.494362427553694721722456597763e-02, + 0.884745273943765732879751147476e-01, + 0.432651559002555750199812112956e+00, + 0.720235215606050957124334723389e+00, + 0.432651559002555750199812112956e+00, + 0.884745273943765732879751147476e-01, + 0.494362427553694721722456597763e-02, + 0.396069772632643819045862946425e-04, + // weights 10 + 0.764043285523262062915936785960e-05, + 0.134364574678123269220156558585e-02, + 0.338743944554810631361647312776e-01, + 0.240138611082314686416523295006e+00, + 0.610862633735325798783564990433e+00, + 0.610862633735325798783564990433e+00, + 0.240138611082314686416523295006e+00, + 0.338743944554810631361647312776e-01, + 0.134364574678123269220156558585e-02, + 0.764043285523262062915936785960e-05, + // weights 11 + 0.143956039371425822033088366032e-05, + 0.346819466323345510643413772940e-03, + 0.119113954449115324503874202916e-01, + 0.117227875167708503381788649308e+00, + 0.429359752356125028446073598601e+00, + 0.654759286914591779203940657627e+00, + 0.429359752356125028446073598601e+00, + 0.117227875167708503381788649308e+00, + 0.119113954449115324503874202916e-01, + 0.346819466323345510643413772940e-03, + 0.143956039371425822033088366032e-05, + // weights 12 + 0.265855168435630160602311400877e-06, + 0.857368704358785865456906323153e-04, + 0.390539058462906185999438432620e-02, + 0.516079856158839299918734423606e-01, + 0.260492310264161129233396139765e+00, + 0.570135236262479578347113482275e+00, + 0.570135236262479578347113482275e+00, + 0.260492310264161129233396139765e+00, + 0.516079856158839299918734423606e-01, + 0.390539058462906185999438432620e-02, + 0.857368704358785865456906323153e-04, + 0.265855168435630160602311400877e-06, + // weights 13 + 0.482573185007313108834997332342e-07, + 0.204303604027070731248669432937e-04, + 0.120745999271938594730924899224e-02, + 0.208627752961699392166033805050e-01, + 0.140323320687023437762792268873e+00, + 0.421616296898543221746893558568e+00, + 0.604393187921161642342099068579e+00, + 0.421616296898543221746893558568e+00, + 0.140323320687023437762792268873e+00, + 0.208627752961699392166033805050e-01, + 0.120745999271938594730924899224e-02, + 0.204303604027070731248669432937e-04, + 0.482573185007313108834997332342e-07, + // weights 14 + 0.862859116812515794532041783429e-08, + 0.471648435501891674887688950105e-05, + 0.355092613551923610483661076691e-03, + 0.785005472645794431048644334608e-02, + 0.685055342234652055387163312367e-01, + 0.273105609064246603352569187026e+00, + 0.536405909712090149794921296776e+00, + 0.536405909712090149794921296776e+00, + 0.273105609064246603352569187026e+00, + 0.685055342234652055387163312367e-01, + 0.785005472645794431048644334608e-02, + 0.355092613551923610483661076691e-03, + 0.471648435501891674887688950105e-05, + 0.862859116812515794532041783429e-08, + // weights 15 + 0.152247580425351702016062666965e-08, + 0.105911554771106663577520791055e-05, + 0.100004441232499868127296736177e-03, + 0.277806884291277589607887049229e-02, + 0.307800338725460822286814158758e-01, + 0.158488915795935746883839384960e+00, + 0.412028687498898627025891079568e+00, + 0.564100308726417532852625797340e+00, + 0.412028687498898627025891079568e+00, + 0.158488915795935746883839384960e+00, + 0.307800338725460822286814158758e-01, + 0.277806884291277589607887049229e-02, + 0.100004441232499868127296736177e-03, + 0.105911554771106663577520791055e-05, + 0.152247580425351702016062666965e-08, + // weights 16 + 0.265480747401118224470926366050e-09, + 0.232098084486521065338749423185e-06, + 0.271186009253788151201891432244e-04, + 0.932284008624180529914277305537e-03, + 0.128803115355099736834642999312e-01, + 0.838100413989858294154207349001e-01, + 0.280647458528533675369463335380e+00, + 0.507929479016613741913517341791e+00, + 0.507929479016613741913517341791e+00, + 0.280647458528533675369463335380e+00, + 0.838100413989858294154207349001e-01, + 0.128803115355099736834642999312e-01, + 0.932284008624180529914277305537e-03, + 0.271186009253788151201891432244e-04, + 0.232098084486521065338749423185e-06, + 0.265480747401118224470926366050e-09, + // weights 17 + 0.458057893079863330580889281222e-10, + 0.497707898163079405227863353715e-07, + 0.711228914002130958353327376218e-05, + 0.298643286697753041151336643059e-03, + 0.506734995762753791170069495879e-02, + 0.409200341495762798094994877854e-01, + 0.172648297670097079217645196219e+00, + 0.401826469470411956577635085257e+00, + 0.530917937624863560331883103379e+00, + 0.401826469470411956577635085257e+00, + 0.172648297670097079217645196219e+00, + 0.409200341495762798094994877854e-01, + 0.506734995762753791170069495879e-02, + 0.298643286697753041151336643059e-03, + 0.711228914002130958353327376218e-05, + 0.497707898163079405227863353715e-07, + 0.458057893079863330580889281222e-10, + // weights 18 + 0.782819977211589102925147471012e-11, + 0.104672057957920824443559608435e-07, + 0.181065448109343040959702385911e-05, + 0.918112686792940352914675407371e-04, + 0.188852263026841789438175325426e-02, + 0.186400423875446519219315221973e-01, + 0.973017476413154293308537234155e-01, + 0.284807285669979578595606820713e+00, + 0.483495694725455552876410522141e+00, + 0.483495694725455552876410522141e+00, + 0.284807285669979578595606820713e+00, + 0.973017476413154293308537234155e-01, + 0.186400423875446519219315221973e-01, + 0.188852263026841789438175325426e-02, + 0.918112686792940352914675407371e-04, + 0.181065448109343040959702385911e-05, + 0.104672057957920824443559608435e-07, + 0.782819977211589102925147471012e-11, + // weights 19 + 0.132629709449851575185289154385e-11, + 0.216305100986355475019693077221e-08, + 0.448824314722312295179447915594e-06, + 0.272091977631616257711941025214e-04, + 0.670877521407181106194696282100e-03, + 0.798886677772299020922211491861e-02, + 0.508103869090520673569908110358e-01, + 0.183632701306997074156148485766e+00, + 0.391608988613030244504042313621e+00, + 0.502974888276186530840731361096e+00, + 0.391608988613030244504042313621e+00, + 0.183632701306997074156148485766e+00, + 0.508103869090520673569908110358e-01, + 0.798886677772299020922211491861e-02, + 0.670877521407181106194696282100e-03, + 0.272091977631616257711941025214e-04, + 0.448824314722312295179447915594e-06, + 0.216305100986355475019693077221e-08, + 0.132629709449851575185289154385e-11, + // weights 20 + 0.222939364553415129252250061603e-12, + 0.439934099227318055362885145547e-09, + 0.108606937076928169399952456345e-06, + 0.780255647853206369414599199965e-05, + 0.228338636016353967257145917963e-03, + 0.324377334223786183218324713235e-02, + 0.248105208874636108821649525589e-01, + 0.109017206020023320013755033535e+00, + 0.286675505362834129719659706228e+00, + 0.462243669600610089650328639861e+00, + 0.462243669600610089650328639861e+00, + 0.286675505362834129719659706228e+00, + 0.109017206020023320013755033535e+00, + 0.248105208874636108821649525589e-01, + 0.324377334223786183218324713235e-02, + 0.228338636016353967257145917963e-03, + 0.780255647853206369414599199965e-05, + 0.108606937076928169399952456345e-06, + 0.439934099227318055362885145547e-09, + 0.222939364553415129252250061603e-12, + // weights 30 + 0.290825470013122622941102747365e-20, + 0.281033360275090370876277491534e-16, + 0.287860708054870606219239791142e-13, + 0.810618629746304420399344796173e-11, + 0.917858042437852820850075742492e-09, + 0.510852245077594627738963204403e-07, + 0.157909488732471028834638794022e-05, + 0.293872522892298764150118423412e-04, + 0.348310124318685523420995323183e-03, + 0.273792247306765846298942568953e-02, + 0.147038297048266835152773557787e-01, + 0.551441768702342511680754948183e-01, + 0.146735847540890099751693643152e+00, + 0.280130930839212667413493211293e+00, + 0.386394889541813862555601849165e+00, + 0.386394889541813862555601849165e+00, + 0.280130930839212667413493211293e+00, + 0.146735847540890099751693643152e+00, + 0.551441768702342511680754948183e-01, + 0.147038297048266835152773557787e-01, + 0.273792247306765846298942568953e-02, + 0.348310124318685523420995323183e-03, + 0.293872522892298764150118423412e-04, + 0.157909488732471028834638794022e-05, + 0.510852245077594627738963204403e-07, + 0.917858042437852820850075742492e-09, + 0.810618629746304420399344796173e-11, + 0.287860708054870606219239791142e-13, + 0.281033360275090370876277491534e-16, + 0.290825470013122622941102747365e-20, + // weights 32 + 0.731067642736e-22, + 0.923173653649e-18, + 0.119734401709e-14, + 0.421501021125e-12, + 0.593329146300e-10, + 0.409883216476e-08, + 0.157416779254e-06, + 0.365058512955e-05, + 0.541658406172e-04, + 0.536268365526e-03, + 0.365489032664e-02, + 0.175534288315e-01, + 0.604581309557e-01, + 0.151269734076e+00, + 0.277458142302e+00, + 0.375238352592e+00, + 0.375238352592e+00, + 0.277458142302e+00, + 0.151269734076e+00, + 0.604581309557e-01, + 0.175534288315e-01, + 0.365489032664e-02, + 0.536268365526e-03, + 0.541658406172e-04, + 0.365058512955e-05, + 0.157416779254e-06, + 0.409883216476e-08, + 0.593329146300e-10, + 0.421501021125e-12, + 0.119734401709e-14, + 0.923173653649e-18, + 0.731067642736e-22, + // weights 40 + 0.259104371384e-28, + 0.854405696375e-24, + 0.256759336540e-20, + 0.198918101211e-17, + 0.600835878947e-15, + 0.880570764518e-13, + 0.715652805267e-11, + 0.352562079135e-09, + 0.112123608322e-07, + 0.241114416359e-06, + 0.363157615067e-05, + 0.393693398108e-04, + 0.313853594540e-03, + 0.187149682959e-02, + 0.846088800823e-02, + 0.293125655361e-01, + 0.784746058652e-01, + 0.163378732713e+00, + 0.265728251876e+00, + 0.338643277425e+00, + 0.338643277425e+00, + 0.265728251876e+00, + 0.163378732713e+00, + 0.784746058652e-01, + 0.293125655361e-01, + 0.846088800823e-02, + 0.187149682959e-02, + 0.313853594540e-03, + 0.393693398108e-04, + 0.363157615067e-05, + 0.241114416359e-06, + 0.112123608322e-07, + 0.352562079135e-09, + 0.715652805267e-11, + 0.880570764518e-13, + 0.600835878947e-15, + 0.198918101211e-17, + 0.256759336540e-20, + 0.854405696375e-24, + 0.259104371384e-28, + // weights 50 + 0.183379404857e-36, + 0.167380166790e-31, + 0.121524412340e-27, + 0.213765830835e-24, + 0.141709359957e-21, + 0.447098436530e-19, + 0.774238295702e-17, + 0.809426189344e-15, + 0.546594403180e-13, + 0.250665552389e-11, + 0.811187736448e-10, + 0.190904054379e-08, + 0.334679340401e-07, + 0.445702996680e-06, + 0.458168270794e-05, + 0.368401905377e-04, + 0.234269892109e-03, + 0.118901178175e-02, + 0.485326382616e-02, + 0.160319410684e-01, + 0.430791591566e-01, + 0.945489354768e-01, + 0.170032455676e+00, + 0.251130856331e+00, + 0.305085129203e+00, + 0.305085129203e+00, + 0.251130856331e+00, + 0.170032455676e+00, + 0.945489354768e-01, + 0.430791591566e-01, + 0.160319410684e-01, + 0.485326382616e-02, + 0.118901178175e-02, + 0.234269892109e-03, + 0.368401905377e-04, + 0.458168270794e-05, + 0.445702996680e-06, + 0.334679340401e-07, + 0.190904054379e-08, + 0.811187736448e-10, + 0.250665552389e-11, + 0.546594403180e-13, + 0.809426189344e-15, + 0.774238295702e-17, + 0.447098436530e-19, + 0.141709359957e-21, + 0.213765830835e-24, + 0.121524412340e-27, + 0.167380166790e-31, + 0.183379404857e-36, + // weights 60 + 0.110958724796e-44, + 0.243974758810e-39, + 0.377162672698e-35, + 0.133255961176e-31, + 0.171557314767e-28, + 0.102940599693e-25, + 0.334575695574e-23, + 0.651256725748e-21, + 0.815364047300e-19, + 0.692324790956e-17, + 0.415244410968e-15, + 0.181662457614e-13, + 0.594843051597e-12, + 0.148895734905e-10, + 0.289935901280e-09, + 0.445682277521e-08, + 0.547555461926e-07, + 0.543351613419e-06, + 0.439428693625e-05, + 0.291874190415e-04, + 0.160277334681e-03, + 0.731773556963e-03, + 0.279132482894e-02, + 0.893217836028e-02, + 0.240612727660e-01, + 0.547189709320e-01, + 0.105298763697e+00, + 0.171776156918e+00, + 0.237868904958e+00, + 0.279853117522e+00, + 0.279853117522e+00, + 0.237868904958e+00, + 0.171776156918e+00, + 0.105298763697e+00, + 0.547189709320e-01, + 0.240612727660e-01, + 0.893217836028e-02, + 0.279132482894e-02, + 0.731773556963e-03, + 0.160277334681e-03, + 0.291874190415e-04, + 0.439428693625e-05, + 0.543351613419e-06, + 0.547555461926e-07, + 0.445682277521e-08, + 0.289935901280e-09, + 0.148895734905e-10, + 0.594843051597e-12, + 0.181662457614e-13, + 0.415244410968e-15, + 0.692324790956e-17, + 0.815364047300e-19, + 0.651256725748e-21, + 0.334575695574e-23, + 0.102940599693e-25, + 0.171557314767e-28, + 0.133255961176e-31, + 0.377162672698e-35, + 0.243974758810e-39, + 0.110958724796e-44, + // weights 64 + 0.553570653584e-48, + 0.167974799010e-42, + 0.342113801099e-38, + 0.155739062462e-34, + 0.254966089910e-31, + 0.192910359546e-28, + 0.786179778889e-26, + 0.191170688329e-23, + 0.298286278427e-21, + 0.315225456649e-19, + 0.235188471067e-17, + 0.128009339117e-15, + 0.521862372645e-14, + 0.162834073070e-12, + 0.395917776693e-11, + 0.761521725012e-10, + 0.117361674232e-08, + 0.146512531647e-07, + 0.149553293672e-06, + 0.125834025103e-05, + 0.878849923082e-05, + 0.512592913577e-04, + 0.250983698512e-03, + 0.103632909950e-02, + 0.362258697852e-02, + 0.107560405098e-01, + 0.272031289536e-01, + 0.587399819634e-01, + 0.108498349306e+00, + 0.171685842349e+00, + 0.232994786062e+00, + 0.271377424940e+00, + 0.271377424940e+00, + 0.232994786062e+00, + 0.171685842349e+00, + 0.108498349306e+00, + 0.587399819634e-01, + 0.272031289536e-01, + 0.107560405098e-01, + 0.362258697852e-02, + 0.103632909950e-02, + 0.250983698512e-03, + 0.512592913577e-04, + 0.878849923082e-05, + 0.125834025103e-05, + 0.149553293672e-06, + 0.146512531647e-07, + 0.117361674232e-08, + 0.761521725012e-10, + 0.395917776693e-11, + 0.162834073070e-12, + 0.521862372645e-14, + 0.128009339117e-15, + 0.235188471067e-17, + 0.315225456649e-19, + 0.298286278427e-21, + 0.191170688329e-23, + 0.786179778889e-26, + 0.192910359546e-28, + 0.254966089910e-31, + 0.155739062462e-34, + 0.342113801099e-38, + 0.167974799010e-42, + 0.553570653584e-48 + }; // Points, starting with the first level -static const double gh_points[] = { - // points 1 - 0.0, - // points 2 - -0.707106781186547524400844362105e+00, - 0.707106781186547524400844362105e+00, - // points 3 - -0.122474487139158904909864203735e+01, - 0.0e+00, - 0.122474487139158904909864203735e+01, - // points 4 - -0.165068012388578455588334111112e+01, - -0.524647623275290317884060253835e+00, - 0.524647623275290317884060253835e+00, - 0.165068012388578455588334111112e+01, - // points 5 - -0.202018287045608563292872408814e+01, - -0.958572464613818507112770593893e+00, - 0.0e+00, - 0.958572464613818507112770593893e+00, - 0.202018287045608563292872408814e+01, - // points 6 - -0.235060497367449222283392198706e+01, - -0.133584907401369694971489528297e+01, - -0.436077411927616508679215948251e+00, - 0.436077411927616508679215948251e+00, - 0.133584907401369694971489528297e+01, - 0.235060497367449222283392198706e+01, - // points 7 - -0.265196135683523349244708200652e+01, - -0.167355162876747144503180139830e+01, - -0.816287882858964663038710959027e+00, - 0.0e+00, - 0.816287882858964663038710959027e+00, - 0.167355162876747144503180139830e+01, - 0.265196135683523349244708200652e+01, - // points 8 - -0.293063742025724401922350270524e+01, - -0.198165675669584292585463063977e+01, - -0.115719371244678019472076577906e+01, - -0.381186990207322116854718885584e+00, - 0.381186990207322116854718885584e+00, - 0.115719371244678019472076577906e+01, - 0.198165675669584292585463063977e+01, - 0.293063742025724401922350270524e+01, - // points 9 - -0.319099320178152760723004779538e+01, - -0.226658058453184311180209693284e+01, - -0.146855328921666793166701573925e+01, - -0.723551018752837573322639864579e+00, - 0.0e+00, - 0.723551018752837573322639864579e+00, - 0.146855328921666793166701573925e+01, - 0.226658058453184311180209693284e+01, - 0.319099320178152760723004779538e+01, - // points 10 - -0.343615911883773760332672549432e+01, - -0.253273167423278979640896079775e+01, - -0.175668364929988177345140122011e+01, - -0.103661082978951365417749191676e+01, - -0.342901327223704608789165025557e+00, - 0.342901327223704608789165025557e+00, - 0.103661082978951365417749191676e+01, - 0.175668364929988177345140122011e+01, - 0.253273167423278979640896079775e+01, - 0.343615911883773760332672549432e+01, - // points 11 - -0.366847084655958251845837146485e+01, - -0.278329009978165177083671870152e+01, - -0.202594801582575533516591283121e+01, - -0.132655708449493285594973473558e+01, - -0.656809566882099765024611575383e+00, - 0.0e+00, - 0.656809566882099765024611575383e+00, - 0.132655708449493285594973473558e+01, - 0.202594801582575533516591283121e+01, - 0.278329009978165177083671870152e+01, - 0.366847084655958251845837146485e+01, - // points 12 - -0.388972489786978191927164274724e+01, - -0.302063702512088977171067937518e+01, - -0.227950708050105990018772856942e+01, - -0.159768263515260479670966277090e+01, - -0.947788391240163743704578131060e+00, - -0.314240376254359111276611634095e+00, - 0.314240376254359111276611634095e+00, - 0.947788391240163743704578131060e+00, - 0.159768263515260479670966277090e+01, - 0.227950708050105990018772856942e+01, - 0.302063702512088977171067937518e+01, - 0.388972489786978191927164274724e+01, - // points 13 - -0.410133759617863964117891508007e+01, - -0.324660897837240998812205115236e+01, - -0.251973568567823788343040913628e+01, - -0.185310765160151214200350644316e+01, - -0.122005503659074842622205526637e+01, - -0.605763879171060113080537108602e+00, - 0.0e+00, - 0.605763879171060113080537108602e+00, - 0.122005503659074842622205526637e+01, - 0.185310765160151214200350644316e+01, - 0.251973568567823788343040913628e+01, - 0.324660897837240998812205115236e+01, - 0.410133759617863964117891508007e+01, - // points 14 - -0.430444857047363181262129810037e+01, - -0.346265693360227055020891736115e+01, - -0.274847072498540256862499852415e+01, - -0.209518325850771681573497272630e+01, - -0.147668273114114087058350654421e+01, - -0.878713787329399416114679311861e+00, - -0.291745510672562078446113075799e+00, - 0.291745510672562078446113075799e+00, - 0.878713787329399416114679311861e+00, - 0.147668273114114087058350654421e+01, - 0.209518325850771681573497272630e+01, - 0.274847072498540256862499852415e+01, - 0.346265693360227055020891736115e+01, - 0.430444857047363181262129810037e+01, - // points 15 - -0.449999070730939155366438053053e+01, - -0.366995037340445253472922383312e+01, - -0.296716692790560324848896036355e+01, - -0.232573248617385774545404479449e+01, - -0.171999257518648893241583152515e+01, - -0.113611558521092066631913490556e+01, - -0.565069583255575748526020337198e+00, - 0.0e+00, - 0.565069583255575748526020337198e+00, - 0.113611558521092066631913490556e+01, - 0.171999257518648893241583152515e+01, - 0.232573248617385774545404479449e+01, - 0.296716692790560324848896036355e+01, - 0.366995037340445253472922383312e+01, - 0.449999070730939155366438053053e+01, - // points 16 - -0.468873893930581836468849864875e+01, - -0.386944790486012269871942409801e+01, - -0.317699916197995602681399455926e+01, - -0.254620215784748136215932870545e+01, - -0.195178799091625397743465541496e+01, - -0.138025853919888079637208966969e+01, - -0.822951449144655892582454496734e+00, - -0.273481046138152452158280401965e+00, - 0.273481046138152452158280401965e+00, - 0.822951449144655892582454496734e+00, - 0.138025853919888079637208966969e+01, - 0.195178799091625397743465541496e+01, - 0.254620215784748136215932870545e+01, - 0.317699916197995602681399455926e+01, - 0.386944790486012269871942409801e+01, - 0.468873893930581836468849864875e+01, - // points 17 - -0.487134519367440308834927655662e+01, - -0.406194667587547430689245559698e+01, - -0.337893209114149408338327069289e+01, - -0.275776291570388873092640349574e+01, - -0.217350282666662081927537907149e+01, - -0.161292431422123133311288254454e+01, - -0.106764872574345055363045773799e+01, - -0.531633001342654731349086553718e+00, - 0.0e+00, - 0.531633001342654731349086553718e+00, - 0.106764872574345055363045773799e+01, - 0.161292431422123133311288254454e+01, - 0.217350282666662081927537907149e+01, - 0.275776291570388873092640349574e+01, - 0.337893209114149408338327069289e+01, - 0.406194667587547430689245559698e+01, - 0.487134519367440308834927655662e+01, - // points 18 - -0.504836400887446676837203757885e+01, - -0.424811787356812646302342016090e+01, - -0.357376906848626607950067599377e+01, - -0.296137750553160684477863254906e+01, - -0.238629908916668600026459301424e+01, - -0.183553160426162889225383944409e+01, - -0.130092085838961736566626555439e+01, - -0.776682919267411661316659462284e+00, - -0.258267750519096759258116098711e+00, - 0.258267750519096759258116098711e+00, - 0.776682919267411661316659462284e+00, - 0.130092085838961736566626555439e+01, - 0.183553160426162889225383944409e+01, - 0.238629908916668600026459301424e+01, - 0.296137750553160684477863254906e+01, - 0.357376906848626607950067599377e+01, - 0.424811787356812646302342016090e+01, - 0.504836400887446676837203757885e+01, - // points 19 - -0.522027169053748216460967142500e+01, - -0.442853280660377943723498532226e+01, - -0.376218735196402009751489394104e+01, - -0.315784881834760228184318034120e+01, - -0.259113378979454256492128084112e+01, - -0.204923170985061937575050838669e+01, - -0.152417061939353303183354859367e+01, - -0.101036838713431135136859873726e+01, - -0.503520163423888209373811765050e+00, - 0.0e+00, - 0.503520163423888209373811765050e+00, - 0.101036838713431135136859873726e+01, - 0.152417061939353303183354859367e+01, - 0.204923170985061937575050838669e+01, - 0.259113378979454256492128084112e+01, - 0.315784881834760228184318034120e+01, - 0.376218735196402009751489394104e+01, - 0.442853280660377943723498532226e+01, - 0.522027169053748216460967142500e+01, - // points 20 - -0.538748089001123286201690041068e+01, - -0.460368244955074427307767524898e+01, - -0.394476404011562521037562880052e+01, - -0.334785456738321632691492452300e+01, - -0.278880605842813048052503375640e+01, - -0.225497400208927552308233334473e+01, - -0.173853771211658620678086566214e+01, - -0.123407621539532300788581834696e+01, - -0.737473728545394358705605144252e+00, - -0.245340708300901249903836530634e+00, - 0.245340708300901249903836530634e+00, - 0.737473728545394358705605144252e+00, - 0.123407621539532300788581834696e+01, - 0.173853771211658620678086566214e+01, - 0.225497400208927552308233334473e+01, - 0.278880605842813048052503375640e+01, - 0.334785456738321632691492452300e+01, - 0.394476404011562521037562880052e+01, - 0.460368244955074427307767524898e+01, - 0.538748089001123286201690041068e+01, - // points 30 - -6.86334529352989158106110835756e+00, - -6.13827922012393462039499237854e+00, - -5.53314715156749572511833355558e+00, - -4.98891896858994394448649710633e+00, - -4.48305535709251834188703761971e+00, - -4.00390860386122881522787601332e+00, - -3.54444387315534988692540090217e+00, - -3.09997052958644174868873332237e+00, - -2.66713212453561720057110646422e+00, - -2.24339146776150407247297999483e+00, - -1.82674114360368803883588048351e+00, - -1.41552780019818851194072510555e+00, - -1.00833827104672346180498960870e+00, - -0.603921058625552307778155678757e+00, - -0.201128576548871485545763013244e+00, - 0.201128576548871485545763013244e+00, - 0.603921058625552307778155678757e+00, - 1.00833827104672346180498960870e+00, - 1.41552780019818851194072510555e+00, - 1.82674114360368803883588048351e+00, - 2.24339146776150407247297999483e+00, - 2.66713212453561720057110646422e+00, - 3.09997052958644174868873332237e+00, - 3.54444387315534988692540090217e+00, - 4.00390860386122881522787601332e+00, - 4.48305535709251834188703761971e+00, - 4.98891896858994394448649710633e+00, - 5.53314715156749572511833355558e+00, - 6.13827922012393462039499237854e+00, - 6.86334529352989158106110835756e+00, - // points 32 - -7.12581390983e+00, - -6.40949814927e+00, - -5.81222594952e+00, - -5.27555098652e+00, - -4.77716450350e+00, - -4.30554795335e+00, - -3.85375548547e+00, - -3.41716749282e+00, - -2.99249082500e+00, - -2.57724953773e+00, - -2.16949918361e+00, - -1.76765410946e+00, - -1.37037641095e+00, - -0.976500463590e+00, - -0.584978765436e+00, - -0.194840741569e+00, - 0.194840741569e+00, - 0.584978765436e+00, - 0.976500463590e+00, - 1.37037641095e+00, - 1.76765410946e+00, - 2.16949918361e+00, - 2.57724953773e+00, - 2.99249082500e+00, - 3.41716749282e+00, - 3.85375548547e+00, - 4.30554795335e+00, - 4.77716450350e+00, - 5.27555098652e+00, - 5.81222594952e+00, - 6.40949814927e+00, - 7.12581390983e+00, - // points 40 - -8.09876113925e+00, - -7.41158253149e+00, - -6.84023730525e+00, - -6.32825535122e+00, - -5.85409505603e+00, - -5.40665424797e+00, - -4.97926097855e+00, - -4.56750207284e+00, - -4.16825706683e+00, - -3.77920675344e+00, - -3.39855826586e+00, - -3.02487988390e+00, - -2.65699599844e+00, - -2.29391714188e+00, - -1.93479147228e+00, - -1.57886989493e+00, - -1.22548010905e+00, - -0.874006612357e+00, - -0.523874713832e+00, - -0.174537214598e+00, - 0.174537214598e+00, - 0.523874713832e+00, - 0.874006612357e+00, - 1.22548010905e+00, - 1.57886989493e+00, - 1.93479147228e+00, - 2.29391714188e+00, - 2.65699599844e+00, - 3.02487988390e+00, - 3.39855826586e+00, - 3.77920675344e+00, - 4.16825706683e+00, - 4.56750207284e+00, - 4.97926097855e+00, - 5.40665424797e+00, - 5.85409505603e+00, - 6.32825535122e+00, - 6.84023730525e+00, - 7.41158253149e+00, - 8.09876113925e+00, - // points 50 - -9.18240695813e+00, - -8.52277103092e+00, - -7.97562236821e+00, - -7.48640942986e+00, - -7.03432350977e+00, - -6.60864797386e+00, - -6.20295251927e+00, - -5.81299467542e+00, - -5.43578608722e+00, - -5.06911758492e+00, - -4.71129366617e+00, - -4.36097316045e+00, - -4.01706817286e+00, - -3.67867706252e+00, - -3.34503831394e+00, - -3.01549776957e+00, - -2.68948470227e+00, - -2.36649390430e+00, - -2.04607196869e+00, - -1.72780654752e+00, - -1.41131775490e+00, - -1.09625112896e+00, - -0.782271729555e+00, - -0.469059056678e+00, - -0.156302546889e+00, - 0.156302546889e+00, - 0.469059056678e+00, - 0.782271729555e+00, - 1.09625112896e+00, - 1.41131775490e+00, - 1.72780654752e+00, - 2.04607196869e+00, - 2.36649390430e+00, - 2.68948470227e+00, - 3.01549776957e+00, - 3.34503831394e+00, - 3.67867706252e+00, - 4.01706817286e+00, - 4.36097316045e+00, - 4.71129366617e+00, - 5.06911758492e+00, - 5.43578608722e+00, - 5.81299467542e+00, - 6.20295251927e+00, - 6.60864797386e+00, - 7.03432350977e+00, - 7.48640942986e+00, - 7.97562236821e+00, - 8.52277103092e+00, - 9.18240695813e+00, - // points 60 - -10.1591092462e+00, - -9.52090367701e+00, - -8.99239800140e+00, - -8.52056928412e+00, - -8.08518865425e+00, - -7.67583993750e+00, - -7.28627659440e+00, - -6.91238153219e+00, - -6.55125916706e+00, - -6.20077355799e+00, - -5.85929019639e+00, - -5.52552108614e+00, - -5.19842653458e+00, - -4.87715007747e+00, - -4.56097375794e+00, - -4.24928643596e+00, - -3.94156073393e+00, - -3.63733587617e+00, - -3.33620465355e+00, - -3.03780333823e+00, - -2.74180374807e+00, - -2.44790690231e+00, - -2.15583787123e+00, - -1.86534153123e+00, - -1.57617901198e+00, - -1.28812467487e+00, - -1.00096349956e+00, - -0.714488781673e+00, - -0.428500064221e+00, - -0.142801238703e+00, - 0.142801238703e+00, - 0.428500064221e+00, - 0.714488781673e+00, - 1.00096349956e+00, - 1.28812467487e+00, - 1.57617901198e+00, - 1.86534153123e+00, - 2.15583787123e+00, - 2.44790690231e+00, - 2.74180374807e+00, - 3.03780333823e+00, - 3.33620465355e+00, - 3.63733587617e+00, - 3.94156073393e+00, - 4.24928643596e+00, - 4.56097375794e+00, - 4.87715007747e+00, - 5.19842653458e+00, - 5.52552108614e+00, - 5.85929019639e+00, - 6.20077355799e+00, - 6.55125916706e+00, - 6.91238153219e+00, - 7.28627659440e+00, - 7.67583993750e+00, - 8.08518865425e+00, - 8.52056928412e+00, - 8.99239800140e+00, - 9.52090367701e+00, - 10.1591092462e+00, - // points 64 - -10.5261231680e+00, - -9.89528758683e+00, - -9.37315954965e+00, - -8.90724909996e+00, - -8.47752908338e+00, - -8.07368728501e+00, - -7.68954016404e+00, - -7.32101303278e+00, - -6.96524112055e+00, - -6.62011226264e+00, - -6.28401122877e+00, - -5.95566632680e+00, - -5.63405216435e+00, - -5.31832522463e+00, - -5.00777960220e+00, - -4.70181564741e+00, - -4.39991716823e+00, - -4.10163447457e+00, - -3.80657151395e+00, - -3.51437593574e+00, - -3.22473129199e+00, - -2.93735082300e+00, - -2.65197243543e+00, - -2.36835458863e+00, - -2.08627287988e+00, - -1.80551717147e+00, - -1.52588914021e+00, - -1.24720015694e+00, - -0.969269423071e+00, - -0.691922305810e+00, - -0.414988824121e+00, - -0.138302244987e+00, - 0.138302244987e+00, - 0.414988824121e+00, - 0.691922305810e+00, - 0.969269423071e+00, - 1.24720015694e+00, - 1.52588914021e+00, - 1.80551717147e+00, - 2.08627287988e+00, - 2.36835458863e+00, - 2.65197243543e+00, - 2.93735082300e+00, - 3.22473129199e+00, - 3.51437593574e+00, - 3.80657151395e+00, - 4.10163447457e+00, - 4.39991716823e+00, - 4.70181564741e+00, - 5.00777960220e+00, - 5.31832522463e+00, - 5.63405216435e+00, - 5.95566632680e+00, - 6.28401122877e+00, - 6.62011226264e+00, - 6.96524112055e+00, - 7.32101303278e+00, - 7.68954016404e+00, - 8.07368728501e+00, - 8.47752908338e+00, - 8.90724909996e+00, - 9.37315954965e+00, - 9.89528758683e+00, - 10.5261231680e+00 -}; +static const double gh_points[] = + { + // points 1 + 0.0, + // points 2 + -0.707106781186547524400844362105e+00, + 0.707106781186547524400844362105e+00, + // points 3 + -0.122474487139158904909864203735e+01, + 0.0e+00, + 0.122474487139158904909864203735e+01, + // points 4 + -0.165068012388578455588334111112e+01, + -0.524647623275290317884060253835e+00, + 0.524647623275290317884060253835e+00, + 0.165068012388578455588334111112e+01, + // points 5 + -0.202018287045608563292872408814e+01, + -0.958572464613818507112770593893e+00, + 0.0e+00, + 0.958572464613818507112770593893e+00, + 0.202018287045608563292872408814e+01, + // points 6 + -0.235060497367449222283392198706e+01, + -0.133584907401369694971489528297e+01, + -0.436077411927616508679215948251e+00, + 0.436077411927616508679215948251e+00, + 0.133584907401369694971489528297e+01, + 0.235060497367449222283392198706e+01, + // points 7 + -0.265196135683523349244708200652e+01, + -0.167355162876747144503180139830e+01, + -0.816287882858964663038710959027e+00, + 0.0e+00, + 0.816287882858964663038710959027e+00, + 0.167355162876747144503180139830e+01, + 0.265196135683523349244708200652e+01, + // points 8 + -0.293063742025724401922350270524e+01, + -0.198165675669584292585463063977e+01, + -0.115719371244678019472076577906e+01, + -0.381186990207322116854718885584e+00, + 0.381186990207322116854718885584e+00, + 0.115719371244678019472076577906e+01, + 0.198165675669584292585463063977e+01, + 0.293063742025724401922350270524e+01, + // points 9 + -0.319099320178152760723004779538e+01, + -0.226658058453184311180209693284e+01, + -0.146855328921666793166701573925e+01, + -0.723551018752837573322639864579e+00, + 0.0e+00, + 0.723551018752837573322639864579e+00, + 0.146855328921666793166701573925e+01, + 0.226658058453184311180209693284e+01, + 0.319099320178152760723004779538e+01, + // points 10 + -0.343615911883773760332672549432e+01, + -0.253273167423278979640896079775e+01, + -0.175668364929988177345140122011e+01, + -0.103661082978951365417749191676e+01, + -0.342901327223704608789165025557e+00, + 0.342901327223704608789165025557e+00, + 0.103661082978951365417749191676e+01, + 0.175668364929988177345140122011e+01, + 0.253273167423278979640896079775e+01, + 0.343615911883773760332672549432e+01, + // points 11 + -0.366847084655958251845837146485e+01, + -0.278329009978165177083671870152e+01, + -0.202594801582575533516591283121e+01, + -0.132655708449493285594973473558e+01, + -0.656809566882099765024611575383e+00, + 0.0e+00, + 0.656809566882099765024611575383e+00, + 0.132655708449493285594973473558e+01, + 0.202594801582575533516591283121e+01, + 0.278329009978165177083671870152e+01, + 0.366847084655958251845837146485e+01, + // points 12 + -0.388972489786978191927164274724e+01, + -0.302063702512088977171067937518e+01, + -0.227950708050105990018772856942e+01, + -0.159768263515260479670966277090e+01, + -0.947788391240163743704578131060e+00, + -0.314240376254359111276611634095e+00, + 0.314240376254359111276611634095e+00, + 0.947788391240163743704578131060e+00, + 0.159768263515260479670966277090e+01, + 0.227950708050105990018772856942e+01, + 0.302063702512088977171067937518e+01, + 0.388972489786978191927164274724e+01, + // points 13 + -0.410133759617863964117891508007e+01, + -0.324660897837240998812205115236e+01, + -0.251973568567823788343040913628e+01, + -0.185310765160151214200350644316e+01, + -0.122005503659074842622205526637e+01, + -0.605763879171060113080537108602e+00, + 0.0e+00, + 0.605763879171060113080537108602e+00, + 0.122005503659074842622205526637e+01, + 0.185310765160151214200350644316e+01, + 0.251973568567823788343040913628e+01, + 0.324660897837240998812205115236e+01, + 0.410133759617863964117891508007e+01, + // points 14 + -0.430444857047363181262129810037e+01, + -0.346265693360227055020891736115e+01, + -0.274847072498540256862499852415e+01, + -0.209518325850771681573497272630e+01, + -0.147668273114114087058350654421e+01, + -0.878713787329399416114679311861e+00, + -0.291745510672562078446113075799e+00, + 0.291745510672562078446113075799e+00, + 0.878713787329399416114679311861e+00, + 0.147668273114114087058350654421e+01, + 0.209518325850771681573497272630e+01, + 0.274847072498540256862499852415e+01, + 0.346265693360227055020891736115e+01, + 0.430444857047363181262129810037e+01, + // points 15 + -0.449999070730939155366438053053e+01, + -0.366995037340445253472922383312e+01, + -0.296716692790560324848896036355e+01, + -0.232573248617385774545404479449e+01, + -0.171999257518648893241583152515e+01, + -0.113611558521092066631913490556e+01, + -0.565069583255575748526020337198e+00, + 0.0e+00, + 0.565069583255575748526020337198e+00, + 0.113611558521092066631913490556e+01, + 0.171999257518648893241583152515e+01, + 0.232573248617385774545404479449e+01, + 0.296716692790560324848896036355e+01, + 0.366995037340445253472922383312e+01, + 0.449999070730939155366438053053e+01, + // points 16 + -0.468873893930581836468849864875e+01, + -0.386944790486012269871942409801e+01, + -0.317699916197995602681399455926e+01, + -0.254620215784748136215932870545e+01, + -0.195178799091625397743465541496e+01, + -0.138025853919888079637208966969e+01, + -0.822951449144655892582454496734e+00, + -0.273481046138152452158280401965e+00, + 0.273481046138152452158280401965e+00, + 0.822951449144655892582454496734e+00, + 0.138025853919888079637208966969e+01, + 0.195178799091625397743465541496e+01, + 0.254620215784748136215932870545e+01, + 0.317699916197995602681399455926e+01, + 0.386944790486012269871942409801e+01, + 0.468873893930581836468849864875e+01, + // points 17 + -0.487134519367440308834927655662e+01, + -0.406194667587547430689245559698e+01, + -0.337893209114149408338327069289e+01, + -0.275776291570388873092640349574e+01, + -0.217350282666662081927537907149e+01, + -0.161292431422123133311288254454e+01, + -0.106764872574345055363045773799e+01, + -0.531633001342654731349086553718e+00, + 0.0e+00, + 0.531633001342654731349086553718e+00, + 0.106764872574345055363045773799e+01, + 0.161292431422123133311288254454e+01, + 0.217350282666662081927537907149e+01, + 0.275776291570388873092640349574e+01, + 0.337893209114149408338327069289e+01, + 0.406194667587547430689245559698e+01, + 0.487134519367440308834927655662e+01, + // points 18 + -0.504836400887446676837203757885e+01, + -0.424811787356812646302342016090e+01, + -0.357376906848626607950067599377e+01, + -0.296137750553160684477863254906e+01, + -0.238629908916668600026459301424e+01, + -0.183553160426162889225383944409e+01, + -0.130092085838961736566626555439e+01, + -0.776682919267411661316659462284e+00, + -0.258267750519096759258116098711e+00, + 0.258267750519096759258116098711e+00, + 0.776682919267411661316659462284e+00, + 0.130092085838961736566626555439e+01, + 0.183553160426162889225383944409e+01, + 0.238629908916668600026459301424e+01, + 0.296137750553160684477863254906e+01, + 0.357376906848626607950067599377e+01, + 0.424811787356812646302342016090e+01, + 0.504836400887446676837203757885e+01, + // points 19 + -0.522027169053748216460967142500e+01, + -0.442853280660377943723498532226e+01, + -0.376218735196402009751489394104e+01, + -0.315784881834760228184318034120e+01, + -0.259113378979454256492128084112e+01, + -0.204923170985061937575050838669e+01, + -0.152417061939353303183354859367e+01, + -0.101036838713431135136859873726e+01, + -0.503520163423888209373811765050e+00, + 0.0e+00, + 0.503520163423888209373811765050e+00, + 0.101036838713431135136859873726e+01, + 0.152417061939353303183354859367e+01, + 0.204923170985061937575050838669e+01, + 0.259113378979454256492128084112e+01, + 0.315784881834760228184318034120e+01, + 0.376218735196402009751489394104e+01, + 0.442853280660377943723498532226e+01, + 0.522027169053748216460967142500e+01, + // points 20 + -0.538748089001123286201690041068e+01, + -0.460368244955074427307767524898e+01, + -0.394476404011562521037562880052e+01, + -0.334785456738321632691492452300e+01, + -0.278880605842813048052503375640e+01, + -0.225497400208927552308233334473e+01, + -0.173853771211658620678086566214e+01, + -0.123407621539532300788581834696e+01, + -0.737473728545394358705605144252e+00, + -0.245340708300901249903836530634e+00, + 0.245340708300901249903836530634e+00, + 0.737473728545394358705605144252e+00, + 0.123407621539532300788581834696e+01, + 0.173853771211658620678086566214e+01, + 0.225497400208927552308233334473e+01, + 0.278880605842813048052503375640e+01, + 0.334785456738321632691492452300e+01, + 0.394476404011562521037562880052e+01, + 0.460368244955074427307767524898e+01, + 0.538748089001123286201690041068e+01, + // points 30 + -6.86334529352989158106110835756e+00, + -6.13827922012393462039499237854e+00, + -5.53314715156749572511833355558e+00, + -4.98891896858994394448649710633e+00, + -4.48305535709251834188703761971e+00, + -4.00390860386122881522787601332e+00, + -3.54444387315534988692540090217e+00, + -3.09997052958644174868873332237e+00, + -2.66713212453561720057110646422e+00, + -2.24339146776150407247297999483e+00, + -1.82674114360368803883588048351e+00, + -1.41552780019818851194072510555e+00, + -1.00833827104672346180498960870e+00, + -0.603921058625552307778155678757e+00, + -0.201128576548871485545763013244e+00, + 0.201128576548871485545763013244e+00, + 0.603921058625552307778155678757e+00, + 1.00833827104672346180498960870e+00, + 1.41552780019818851194072510555e+00, + 1.82674114360368803883588048351e+00, + 2.24339146776150407247297999483e+00, + 2.66713212453561720057110646422e+00, + 3.09997052958644174868873332237e+00, + 3.54444387315534988692540090217e+00, + 4.00390860386122881522787601332e+00, + 4.48305535709251834188703761971e+00, + 4.98891896858994394448649710633e+00, + 5.53314715156749572511833355558e+00, + 6.13827922012393462039499237854e+00, + 6.86334529352989158106110835756e+00, + // points 32 + -7.12581390983e+00, + -6.40949814927e+00, + -5.81222594952e+00, + -5.27555098652e+00, + -4.77716450350e+00, + -4.30554795335e+00, + -3.85375548547e+00, + -3.41716749282e+00, + -2.99249082500e+00, + -2.57724953773e+00, + -2.16949918361e+00, + -1.76765410946e+00, + -1.37037641095e+00, + -0.976500463590e+00, + -0.584978765436e+00, + -0.194840741569e+00, + 0.194840741569e+00, + 0.584978765436e+00, + 0.976500463590e+00, + 1.37037641095e+00, + 1.76765410946e+00, + 2.16949918361e+00, + 2.57724953773e+00, + 2.99249082500e+00, + 3.41716749282e+00, + 3.85375548547e+00, + 4.30554795335e+00, + 4.77716450350e+00, + 5.27555098652e+00, + 5.81222594952e+00, + 6.40949814927e+00, + 7.12581390983e+00, + // points 40 + -8.09876113925e+00, + -7.41158253149e+00, + -6.84023730525e+00, + -6.32825535122e+00, + -5.85409505603e+00, + -5.40665424797e+00, + -4.97926097855e+00, + -4.56750207284e+00, + -4.16825706683e+00, + -3.77920675344e+00, + -3.39855826586e+00, + -3.02487988390e+00, + -2.65699599844e+00, + -2.29391714188e+00, + -1.93479147228e+00, + -1.57886989493e+00, + -1.22548010905e+00, + -0.874006612357e+00, + -0.523874713832e+00, + -0.174537214598e+00, + 0.174537214598e+00, + 0.523874713832e+00, + 0.874006612357e+00, + 1.22548010905e+00, + 1.57886989493e+00, + 1.93479147228e+00, + 2.29391714188e+00, + 2.65699599844e+00, + 3.02487988390e+00, + 3.39855826586e+00, + 3.77920675344e+00, + 4.16825706683e+00, + 4.56750207284e+00, + 4.97926097855e+00, + 5.40665424797e+00, + 5.85409505603e+00, + 6.32825535122e+00, + 6.84023730525e+00, + 7.41158253149e+00, + 8.09876113925e+00, + // points 50 + -9.18240695813e+00, + -8.52277103092e+00, + -7.97562236821e+00, + -7.48640942986e+00, + -7.03432350977e+00, + -6.60864797386e+00, + -6.20295251927e+00, + -5.81299467542e+00, + -5.43578608722e+00, + -5.06911758492e+00, + -4.71129366617e+00, + -4.36097316045e+00, + -4.01706817286e+00, + -3.67867706252e+00, + -3.34503831394e+00, + -3.01549776957e+00, + -2.68948470227e+00, + -2.36649390430e+00, + -2.04607196869e+00, + -1.72780654752e+00, + -1.41131775490e+00, + -1.09625112896e+00, + -0.782271729555e+00, + -0.469059056678e+00, + -0.156302546889e+00, + 0.156302546889e+00, + 0.469059056678e+00, + 0.782271729555e+00, + 1.09625112896e+00, + 1.41131775490e+00, + 1.72780654752e+00, + 2.04607196869e+00, + 2.36649390430e+00, + 2.68948470227e+00, + 3.01549776957e+00, + 3.34503831394e+00, + 3.67867706252e+00, + 4.01706817286e+00, + 4.36097316045e+00, + 4.71129366617e+00, + 5.06911758492e+00, + 5.43578608722e+00, + 5.81299467542e+00, + 6.20295251927e+00, + 6.60864797386e+00, + 7.03432350977e+00, + 7.48640942986e+00, + 7.97562236821e+00, + 8.52277103092e+00, + 9.18240695813e+00, + // points 60 + -10.1591092462e+00, + -9.52090367701e+00, + -8.99239800140e+00, + -8.52056928412e+00, + -8.08518865425e+00, + -7.67583993750e+00, + -7.28627659440e+00, + -6.91238153219e+00, + -6.55125916706e+00, + -6.20077355799e+00, + -5.85929019639e+00, + -5.52552108614e+00, + -5.19842653458e+00, + -4.87715007747e+00, + -4.56097375794e+00, + -4.24928643596e+00, + -3.94156073393e+00, + -3.63733587617e+00, + -3.33620465355e+00, + -3.03780333823e+00, + -2.74180374807e+00, + -2.44790690231e+00, + -2.15583787123e+00, + -1.86534153123e+00, + -1.57617901198e+00, + -1.28812467487e+00, + -1.00096349956e+00, + -0.714488781673e+00, + -0.428500064221e+00, + -0.142801238703e+00, + 0.142801238703e+00, + 0.428500064221e+00, + 0.714488781673e+00, + 1.00096349956e+00, + 1.28812467487e+00, + 1.57617901198e+00, + 1.86534153123e+00, + 2.15583787123e+00, + 2.44790690231e+00, + 2.74180374807e+00, + 3.03780333823e+00, + 3.33620465355e+00, + 3.63733587617e+00, + 3.94156073393e+00, + 4.24928643596e+00, + 4.56097375794e+00, + 4.87715007747e+00, + 5.19842653458e+00, + 5.52552108614e+00, + 5.85929019639e+00, + 6.20077355799e+00, + 6.55125916706e+00, + 6.91238153219e+00, + 7.28627659440e+00, + 7.67583993750e+00, + 8.08518865425e+00, + 8.52056928412e+00, + 8.99239800140e+00, + 9.52090367701e+00, + 10.1591092462e+00, + // points 64 + -10.5261231680e+00, + -9.89528758683e+00, + -9.37315954965e+00, + -8.90724909996e+00, + -8.47752908338e+00, + -8.07368728501e+00, + -7.68954016404e+00, + -7.32101303278e+00, + -6.96524112055e+00, + -6.62011226264e+00, + -6.28401122877e+00, + -5.95566632680e+00, + -5.63405216435e+00, + -5.31832522463e+00, + -5.00777960220e+00, + -4.70181564741e+00, + -4.39991716823e+00, + -4.10163447457e+00, + -3.80657151395e+00, + -3.51437593574e+00, + -3.22473129199e+00, + -2.93735082300e+00, + -2.65197243543e+00, + -2.36835458863e+00, + -2.08627287988e+00, + -1.80551717147e+00, + -1.52588914021e+00, + -1.24720015694e+00, + -0.969269423071e+00, + -0.691922305810e+00, + -0.414988824121e+00, + -0.138302244987e+00, + 0.138302244987e+00, + 0.414988824121e+00, + 0.691922305810e+00, + 0.969269423071e+00, + 1.24720015694e+00, + 1.52588914021e+00, + 1.80551717147e+00, + 2.08627287988e+00, + 2.36835458863e+00, + 2.65197243543e+00, + 2.93735082300e+00, + 3.22473129199e+00, + 3.51437593574e+00, + 3.80657151395e+00, + 4.10163447457e+00, + 4.39991716823e+00, + 4.70181564741e+00, + 5.00777960220e+00, + 5.31832522463e+00, + 5.63405216435e+00, + 5.95566632680e+00, + 6.28401122877e+00, + 6.62011226264e+00, + 6.96524112055e+00, + 7.32101303278e+00, + 7.68954016404e+00, + 8.07368728501e+00, + 8.47752908338e+00, + 8.90724909996e+00, + 9.37315954965e+00, + 9.89528758683e+00, + 10.5261231680e+00 + }; // Gauss-Legendre quadrature; prefix gl @@ -1072,671 +1075,674 @@ static const double gh_points[] = { static const int gl_num_levels = 22; // Number of points in each level -static const int gl_num_points[] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 32, 64 -}; +static const int gl_num_points[] = + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 32, 64 + }; // Weights, starting with the first level -static const double gl_weights[] = { - // weight 1 - 2.0e+00, - // weights 2 - 1.0e+00, - 1.0e+00, - // weights 3 - 0.555555555555555555555555555555e+00, - 0.888888888888888888888888888888e+00, - 0.555555555555555555555555555555e+00, - // weights 4 - 0.347854845137453857373063949222e+00, - 0.652145154862546142626936050778e+00, - 0.652145154862546142626936050778e+00, - 0.347854845137453857373063949222e+00, - // weights 5 - 0.236926885056189087514264040720e+00, - 0.478628670499366468041291514836e+00, - 0.568888888888888888888888888889e+00, - 0.478628670499366468041291514836e+00, - 0.236926885056189087514264040720e+00, - // weights 6 - 0.171324492379170345040296142173e+00, - 0.360761573048138607569833513838e+00, - 0.467913934572691047389870343990e+00, - 0.467913934572691047389870343990e+00, - 0.360761573048138607569833513838e+00, - 0.171324492379170345040296142173e+00, - // weights 7 - 0.129484966168869693270611432679e+00, - 0.279705391489276667901467771424e+00, - 0.381830050505118944950369775489e+00, - 0.417959183673469387755102040816e+00, - 0.381830050505118944950369775489e+00, - 0.279705391489276667901467771424e+00, - 0.129484966168869693270611432679e+00, - // weights 8 - 0.101228536290376259152531354310e+00, - 0.222381034453374470544355994426e+00, - 0.313706645877887287337962201987e+00, - 0.362683783378361982965150449277e+00, - 0.362683783378361982965150449277e+00, - 0.313706645877887287337962201987e+00, - 0.222381034453374470544355994426e+00, - 0.101228536290376259152531354310e+00, - // weights 9 - 0.812743883615744119718921581105e-01, - 0.180648160694857404058472031243e+00, - 0.260610696402935462318742869419e+00, - 0.312347077040002840068630406584e+00, - 0.330239355001259763164525069287e+00, - 0.312347077040002840068630406584e+00, - 0.260610696402935462318742869419e+00, - 0.180648160694857404058472031243e+00, - 0.812743883615744119718921581105e-01, - // weights 10 - 0.666713443086881375935688098933e-01, - 0.149451349150580593145776339658e+00, - 0.219086362515982043995534934228e+00, - 0.269266719309996355091226921569e+00, - 0.295524224714752870173892994651e+00, - 0.295524224714752870173892994651e+00, - 0.269266719309996355091226921569e+00, - 0.219086362515982043995534934228e+00, - 0.149451349150580593145776339658e+00, - 0.666713443086881375935688098933e-01, - // weights 11 - 0.556685671161736664827537204425e-01, - 0.125580369464904624634694299224e+00, - 0.186290210927734251426097641432e+00, - 0.233193764591990479918523704843e+00, - 0.262804544510246662180688869891e+00, - 0.272925086777900630714483528336e+00, - 0.262804544510246662180688869891e+00, - 0.233193764591990479918523704843e+00, - 0.186290210927734251426097641432e+00, - 0.125580369464904624634694299224e+00, - 0.556685671161736664827537204425e-01, - // weights 12 - 0.471753363865118271946159614850e-01, - 0.106939325995318430960254718194e+00, - 0.160078328543346226334652529543e+00, - 0.203167426723065921749064455810e+00, - 0.233492536538354808760849898925e+00, - 0.249147045813402785000562436043e+00, - 0.249147045813402785000562436043e+00, - 0.233492536538354808760849898925e+00, - 0.203167426723065921749064455810e+00, - 0.160078328543346226334652529543e+00, - 0.106939325995318430960254718194e+00, - 0.471753363865118271946159614850e-01, - // weights 13 - 0.404840047653158795200215922010e-01, - 0.921214998377284479144217759538e-01, - 0.138873510219787238463601776869e+00, - 0.178145980761945738280046691996e+00, - 0.207816047536888502312523219306e+00, - 0.226283180262897238412090186040e+00, - 0.232551553230873910194589515269e+00, - 0.226283180262897238412090186040e+00, - 0.207816047536888502312523219306e+00, - 0.178145980761945738280046691996e+00, - 0.138873510219787238463601776869e+00, - 0.921214998377284479144217759538e-01, - 0.404840047653158795200215922010e-01, - // weights 14 - 0.351194603317518630318328761382e-01, - 0.801580871597602098056332770629e-01, - 0.121518570687903184689414809072e+00, - 0.157203167158193534569601938624e+00, - 0.185538397477937813741716590125e+00, - 0.205198463721295603965924065661e+00, - 0.215263853463157790195876443316e+00, - 0.215263853463157790195876443316e+00, - 0.205198463721295603965924065661e+00, - 0.185538397477937813741716590125e+00, - 0.157203167158193534569601938624e+00, - 0.121518570687903184689414809072e+00, - 0.801580871597602098056332770629e-01, - 0.351194603317518630318328761382e-01, - // weights 15 - 0.307532419961172683546283935772e-01, - 0.703660474881081247092674164507e-01, - 0.107159220467171935011869546686e+00, - 0.139570677926154314447804794511e+00, - 0.166269205816993933553200860481e+00, - 0.186161000015562211026800561866e+00, - 0.198431485327111576456118326444e+00, - 0.202578241925561272880620199968e+00, - 0.198431485327111576456118326444e+00, - 0.186161000015562211026800561866e+00, - 0.166269205816993933553200860481e+00, - 0.139570677926154314447804794511e+00, - 0.107159220467171935011869546686e+00, - 0.703660474881081247092674164507e-01, - 0.307532419961172683546283935772e-01, - // weights 16 - 0.271524594117540948517805724560e-01, - 0.622535239386478928628438369944e-01, - 0.951585116824927848099251076022e-01, - 0.124628971255533872052476282192e+00, - 0.149595988816576732081501730547e+00, - 0.169156519395002538189312079030e+00, - 0.182603415044923588866763667969e+00, - 0.189450610455068496285396723208e+00, - 0.189450610455068496285396723208e+00, - 0.182603415044923588866763667969e+00, - 0.169156519395002538189312079030e+00, - 0.149595988816576732081501730547e+00, - 0.124628971255533872052476282192e+00, - 0.951585116824927848099251076022e-01, - 0.622535239386478928628438369944e-01, - 0.271524594117540948517805724560e-01, - // weights 17 - 0.241483028685479319601100262876e-01, - 0.554595293739872011294401653582e-01, - 0.850361483171791808835353701911e-01, - 0.111883847193403971094788385626e+00, - 0.135136368468525473286319981702e+00, - 0.154045761076810288081431594802e+00, - 0.168004102156450044509970663788e+00, - 0.176562705366992646325270990113e+00, - 0.179446470356206525458265644262e+00, - 0.176562705366992646325270990113e+00, - 0.168004102156450044509970663788e+00, - 0.154045761076810288081431594802e+00, - 0.135136368468525473286319981702e+00, - 0.111883847193403971094788385626e+00, - 0.850361483171791808835353701911e-01, - 0.554595293739872011294401653582e-01, - 0.241483028685479319601100262876e-01, - // weights 18 - 0.216160135264833103133427102665e-01, - 0.497145488949697964533349462026e-01, - 0.764257302548890565291296776166e-01, - 0.100942044106287165562813984925e+00, - 0.122555206711478460184519126800e+00, - 0.140642914670650651204731303752e+00, - 0.154684675126265244925418003836e+00, - 0.164276483745832722986053776466e+00, - 0.169142382963143591840656470135e+00, - 0.169142382963143591840656470135e+00, - 0.164276483745832722986053776466e+00, - 0.154684675126265244925418003836e+00, - 0.140642914670650651204731303752e+00, - 0.122555206711478460184519126800e+00, - 0.100942044106287165562813984925e+00, - 0.764257302548890565291296776166e-01, - 0.497145488949697964533349462026e-01, - 0.216160135264833103133427102665e-01, - // weights 19 - 0.194617882297264770363120414644e-01, - 0.448142267656996003328381574020e-01, - 0.690445427376412265807082580060e-01, - 0.914900216224499994644620941238e-01, - 0.111566645547333994716023901682e+00, - 0.128753962539336227675515784857e+00, - 0.142606702173606611775746109442e+00, - 0.152766042065859666778855400898e+00, - 0.158968843393954347649956439465e+00, - 0.161054449848783695979163625321e+00, - 0.158968843393954347649956439465e+00, - 0.152766042065859666778855400898e+00, - 0.142606702173606611775746109442e+00, - 0.128753962539336227675515784857e+00, - 0.111566645547333994716023901682e+00, - 0.914900216224499994644620941238e-01, - 0.690445427376412265807082580060e-01, - 0.448142267656996003328381574020e-01, - 0.194617882297264770363120414644e-01, - // weights 20 - 0.176140071391521183118619623519e-01, - 0.406014298003869413310399522749e-01, - 0.626720483341090635695065351870e-01, - 0.832767415767047487247581432220e-01, - 0.101930119817240435036750135480e+00, - 0.118194531961518417312377377711e+00, - 0.131688638449176626898494499748e+00, - 0.142096109318382051329298325067e+00, - 0.149172986472603746787828737002e+00, - 0.152753387130725850698084331955e+00, - 0.152753387130725850698084331955e+00, - 0.149172986472603746787828737002e+00, - 0.142096109318382051329298325067e+00, - 0.131688638449176626898494499748e+00, - 0.118194531961518417312377377711e+00, - 0.101930119817240435036750135480e+00, - 0.832767415767047487247581432220e-01, - 0.626720483341090635695065351870e-01, - 0.406014298003869413310399522749e-01, - 0.176140071391521183118619623519e-01, - // weights 32 - 0.701861000947009660040706373885e-02, - 0.162743947309056706051705622064e-01, - 0.253920653092620594557525897892e-01, - 0.342738629130214331026877322524e-01, - 0.428358980222266806568786466061e-01, - 0.509980592623761761961632446895e-01, - 0.586840934785355471452836373002e-01, - 0.658222227763618468376500637069e-01, - 0.723457941088485062253993564785e-01, - 0.781938957870703064717409188283e-01, - 0.833119242269467552221990746043e-01, - 0.876520930044038111427714627518e-01, - 0.911738786957638847128685771116e-01, - 0.938443990808045656391802376681e-01, - 0.956387200792748594190820022041e-01, - 0.965400885147278005667648300636e-01, - 0.965400885147278005667648300636e-01, - 0.956387200792748594190820022041e-01, - 0.938443990808045656391802376681e-01, - 0.911738786957638847128685771116e-01, - 0.876520930044038111427714627518e-01, - 0.833119242269467552221990746043e-01, - 0.781938957870703064717409188283e-01, - 0.723457941088485062253993564785e-01, - 0.658222227763618468376500637069e-01, - 0.586840934785355471452836373002e-01, - 0.509980592623761761961632446895e-01, - 0.428358980222266806568786466061e-01, - 0.342738629130214331026877322524e-01, - 0.253920653092620594557525897892e-01, - 0.162743947309056706051705622064e-01, - 0.701861000947009660040706373885e-02, - // weights 64 - 0.178328072169643294729607914497e-02, - 0.414703326056246763528753572855e-02, - 0.650445796897836285611736039998e-02, - 0.884675982636394772303091465973e-02, - 0.111681394601311288185904930192e-01, - 0.134630478967186425980607666860e-01, - 0.157260304760247193219659952975e-01, - 0.179517157756973430850453020011e-01, - 0.201348231535302093723403167285e-01, - 0.222701738083832541592983303842e-01, - 0.243527025687108733381775504091e-01, - 0.263774697150546586716917926252e-01, - 0.283396726142594832275113052002e-01, - 0.302346570724024788679740598195e-01, - 0.320579283548515535854675043479e-01, - 0.338051618371416093915654821107e-01, - 0.354722132568823838106931467152e-01, - 0.370551285402400460404151018096e-01, - 0.385501531786156291289624969468e-01, - 0.399537411327203413866569261283e-01, - 0.412625632426235286101562974736e-01, - 0.424735151236535890073397679088e-01, - 0.435837245293234533768278609737e-01, - 0.445905581637565630601347100309e-01, - 0.454916279274181444797709969713e-01, - 0.462847965813144172959532492323e-01, - 0.469681828162100173253262857546e-01, - 0.475401657148303086622822069442e-01, - 0.479993885964583077281261798713e-01, - 0.483447622348029571697695271580e-01, - 0.485754674415034269347990667840e-01, - 0.486909570091397203833653907347e-01, - 0.486909570091397203833653907347e-01, - 0.485754674415034269347990667840e-01, - 0.483447622348029571697695271580e-01, - 0.479993885964583077281261798713e-01, - 0.475401657148303086622822069442e-01, - 0.469681828162100173253262857546e-01, - 0.462847965813144172959532492323e-01, - 0.454916279274181444797709969713e-01, - 0.445905581637565630601347100309e-01, - 0.435837245293234533768278609737e-01, - 0.424735151236535890073397679088e-01, - 0.412625632426235286101562974736e-01, - 0.399537411327203413866569261283e-01, - 0.385501531786156291289624969468e-01, - 0.370551285402400460404151018096e-01, - 0.354722132568823838106931467152e-01, - 0.338051618371416093915654821107e-01, - 0.320579283548515535854675043479e-01, - 0.302346570724024788679740598195e-01, - 0.283396726142594832275113052002e-01, - 0.263774697150546586716917926252e-01, - 0.243527025687108733381775504091e-01, - 0.222701738083832541592983303842e-01, - 0.201348231535302093723403167285e-01, - 0.179517157756973430850453020011e-01, - 0.157260304760247193219659952975e-01, - 0.134630478967186425980607666860e-01, - 0.111681394601311288185904930192e-01, - 0.884675982636394772303091465973e-02, - 0.650445796897836285611736039998e-02, - 0.414703326056246763528753572855e-02, - 0.178328072169643294729607914497e-02 -}; +static const double gl_weights[] = + { + // weight 1 + 2.0e+00, + // weights 2 + 1.0e+00, + 1.0e+00, + // weights 3 + 0.555555555555555555555555555555e+00, + 0.888888888888888888888888888888e+00, + 0.555555555555555555555555555555e+00, + // weights 4 + 0.347854845137453857373063949222e+00, + 0.652145154862546142626936050778e+00, + 0.652145154862546142626936050778e+00, + 0.347854845137453857373063949222e+00, + // weights 5 + 0.236926885056189087514264040720e+00, + 0.478628670499366468041291514836e+00, + 0.568888888888888888888888888889e+00, + 0.478628670499366468041291514836e+00, + 0.236926885056189087514264040720e+00, + // weights 6 + 0.171324492379170345040296142173e+00, + 0.360761573048138607569833513838e+00, + 0.467913934572691047389870343990e+00, + 0.467913934572691047389870343990e+00, + 0.360761573048138607569833513838e+00, + 0.171324492379170345040296142173e+00, + // weights 7 + 0.129484966168869693270611432679e+00, + 0.279705391489276667901467771424e+00, + 0.381830050505118944950369775489e+00, + 0.417959183673469387755102040816e+00, + 0.381830050505118944950369775489e+00, + 0.279705391489276667901467771424e+00, + 0.129484966168869693270611432679e+00, + // weights 8 + 0.101228536290376259152531354310e+00, + 0.222381034453374470544355994426e+00, + 0.313706645877887287337962201987e+00, + 0.362683783378361982965150449277e+00, + 0.362683783378361982965150449277e+00, + 0.313706645877887287337962201987e+00, + 0.222381034453374470544355994426e+00, + 0.101228536290376259152531354310e+00, + // weights 9 + 0.812743883615744119718921581105e-01, + 0.180648160694857404058472031243e+00, + 0.260610696402935462318742869419e+00, + 0.312347077040002840068630406584e+00, + 0.330239355001259763164525069287e+00, + 0.312347077040002840068630406584e+00, + 0.260610696402935462318742869419e+00, + 0.180648160694857404058472031243e+00, + 0.812743883615744119718921581105e-01, + // weights 10 + 0.666713443086881375935688098933e-01, + 0.149451349150580593145776339658e+00, + 0.219086362515982043995534934228e+00, + 0.269266719309996355091226921569e+00, + 0.295524224714752870173892994651e+00, + 0.295524224714752870173892994651e+00, + 0.269266719309996355091226921569e+00, + 0.219086362515982043995534934228e+00, + 0.149451349150580593145776339658e+00, + 0.666713443086881375935688098933e-01, + // weights 11 + 0.556685671161736664827537204425e-01, + 0.125580369464904624634694299224e+00, + 0.186290210927734251426097641432e+00, + 0.233193764591990479918523704843e+00, + 0.262804544510246662180688869891e+00, + 0.272925086777900630714483528336e+00, + 0.262804544510246662180688869891e+00, + 0.233193764591990479918523704843e+00, + 0.186290210927734251426097641432e+00, + 0.125580369464904624634694299224e+00, + 0.556685671161736664827537204425e-01, + // weights 12 + 0.471753363865118271946159614850e-01, + 0.106939325995318430960254718194e+00, + 0.160078328543346226334652529543e+00, + 0.203167426723065921749064455810e+00, + 0.233492536538354808760849898925e+00, + 0.249147045813402785000562436043e+00, + 0.249147045813402785000562436043e+00, + 0.233492536538354808760849898925e+00, + 0.203167426723065921749064455810e+00, + 0.160078328543346226334652529543e+00, + 0.106939325995318430960254718194e+00, + 0.471753363865118271946159614850e-01, + // weights 13 + 0.404840047653158795200215922010e-01, + 0.921214998377284479144217759538e-01, + 0.138873510219787238463601776869e+00, + 0.178145980761945738280046691996e+00, + 0.207816047536888502312523219306e+00, + 0.226283180262897238412090186040e+00, + 0.232551553230873910194589515269e+00, + 0.226283180262897238412090186040e+00, + 0.207816047536888502312523219306e+00, + 0.178145980761945738280046691996e+00, + 0.138873510219787238463601776869e+00, + 0.921214998377284479144217759538e-01, + 0.404840047653158795200215922010e-01, + // weights 14 + 0.351194603317518630318328761382e-01, + 0.801580871597602098056332770629e-01, + 0.121518570687903184689414809072e+00, + 0.157203167158193534569601938624e+00, + 0.185538397477937813741716590125e+00, + 0.205198463721295603965924065661e+00, + 0.215263853463157790195876443316e+00, + 0.215263853463157790195876443316e+00, + 0.205198463721295603965924065661e+00, + 0.185538397477937813741716590125e+00, + 0.157203167158193534569601938624e+00, + 0.121518570687903184689414809072e+00, + 0.801580871597602098056332770629e-01, + 0.351194603317518630318328761382e-01, + // weights 15 + 0.307532419961172683546283935772e-01, + 0.703660474881081247092674164507e-01, + 0.107159220467171935011869546686e+00, + 0.139570677926154314447804794511e+00, + 0.166269205816993933553200860481e+00, + 0.186161000015562211026800561866e+00, + 0.198431485327111576456118326444e+00, + 0.202578241925561272880620199968e+00, + 0.198431485327111576456118326444e+00, + 0.186161000015562211026800561866e+00, + 0.166269205816993933553200860481e+00, + 0.139570677926154314447804794511e+00, + 0.107159220467171935011869546686e+00, + 0.703660474881081247092674164507e-01, + 0.307532419961172683546283935772e-01, + // weights 16 + 0.271524594117540948517805724560e-01, + 0.622535239386478928628438369944e-01, + 0.951585116824927848099251076022e-01, + 0.124628971255533872052476282192e+00, + 0.149595988816576732081501730547e+00, + 0.169156519395002538189312079030e+00, + 0.182603415044923588866763667969e+00, + 0.189450610455068496285396723208e+00, + 0.189450610455068496285396723208e+00, + 0.182603415044923588866763667969e+00, + 0.169156519395002538189312079030e+00, + 0.149595988816576732081501730547e+00, + 0.124628971255533872052476282192e+00, + 0.951585116824927848099251076022e-01, + 0.622535239386478928628438369944e-01, + 0.271524594117540948517805724560e-01, + // weights 17 + 0.241483028685479319601100262876e-01, + 0.554595293739872011294401653582e-01, + 0.850361483171791808835353701911e-01, + 0.111883847193403971094788385626e+00, + 0.135136368468525473286319981702e+00, + 0.154045761076810288081431594802e+00, + 0.168004102156450044509970663788e+00, + 0.176562705366992646325270990113e+00, + 0.179446470356206525458265644262e+00, + 0.176562705366992646325270990113e+00, + 0.168004102156450044509970663788e+00, + 0.154045761076810288081431594802e+00, + 0.135136368468525473286319981702e+00, + 0.111883847193403971094788385626e+00, + 0.850361483171791808835353701911e-01, + 0.554595293739872011294401653582e-01, + 0.241483028685479319601100262876e-01, + // weights 18 + 0.216160135264833103133427102665e-01, + 0.497145488949697964533349462026e-01, + 0.764257302548890565291296776166e-01, + 0.100942044106287165562813984925e+00, + 0.122555206711478460184519126800e+00, + 0.140642914670650651204731303752e+00, + 0.154684675126265244925418003836e+00, + 0.164276483745832722986053776466e+00, + 0.169142382963143591840656470135e+00, + 0.169142382963143591840656470135e+00, + 0.164276483745832722986053776466e+00, + 0.154684675126265244925418003836e+00, + 0.140642914670650651204731303752e+00, + 0.122555206711478460184519126800e+00, + 0.100942044106287165562813984925e+00, + 0.764257302548890565291296776166e-01, + 0.497145488949697964533349462026e-01, + 0.216160135264833103133427102665e-01, + // weights 19 + 0.194617882297264770363120414644e-01, + 0.448142267656996003328381574020e-01, + 0.690445427376412265807082580060e-01, + 0.914900216224499994644620941238e-01, + 0.111566645547333994716023901682e+00, + 0.128753962539336227675515784857e+00, + 0.142606702173606611775746109442e+00, + 0.152766042065859666778855400898e+00, + 0.158968843393954347649956439465e+00, + 0.161054449848783695979163625321e+00, + 0.158968843393954347649956439465e+00, + 0.152766042065859666778855400898e+00, + 0.142606702173606611775746109442e+00, + 0.128753962539336227675515784857e+00, + 0.111566645547333994716023901682e+00, + 0.914900216224499994644620941238e-01, + 0.690445427376412265807082580060e-01, + 0.448142267656996003328381574020e-01, + 0.194617882297264770363120414644e-01, + // weights 20 + 0.176140071391521183118619623519e-01, + 0.406014298003869413310399522749e-01, + 0.626720483341090635695065351870e-01, + 0.832767415767047487247581432220e-01, + 0.101930119817240435036750135480e+00, + 0.118194531961518417312377377711e+00, + 0.131688638449176626898494499748e+00, + 0.142096109318382051329298325067e+00, + 0.149172986472603746787828737002e+00, + 0.152753387130725850698084331955e+00, + 0.152753387130725850698084331955e+00, + 0.149172986472603746787828737002e+00, + 0.142096109318382051329298325067e+00, + 0.131688638449176626898494499748e+00, + 0.118194531961518417312377377711e+00, + 0.101930119817240435036750135480e+00, + 0.832767415767047487247581432220e-01, + 0.626720483341090635695065351870e-01, + 0.406014298003869413310399522749e-01, + 0.176140071391521183118619623519e-01, + // weights 32 + 0.701861000947009660040706373885e-02, + 0.162743947309056706051705622064e-01, + 0.253920653092620594557525897892e-01, + 0.342738629130214331026877322524e-01, + 0.428358980222266806568786466061e-01, + 0.509980592623761761961632446895e-01, + 0.586840934785355471452836373002e-01, + 0.658222227763618468376500637069e-01, + 0.723457941088485062253993564785e-01, + 0.781938957870703064717409188283e-01, + 0.833119242269467552221990746043e-01, + 0.876520930044038111427714627518e-01, + 0.911738786957638847128685771116e-01, + 0.938443990808045656391802376681e-01, + 0.956387200792748594190820022041e-01, + 0.965400885147278005667648300636e-01, + 0.965400885147278005667648300636e-01, + 0.956387200792748594190820022041e-01, + 0.938443990808045656391802376681e-01, + 0.911738786957638847128685771116e-01, + 0.876520930044038111427714627518e-01, + 0.833119242269467552221990746043e-01, + 0.781938957870703064717409188283e-01, + 0.723457941088485062253993564785e-01, + 0.658222227763618468376500637069e-01, + 0.586840934785355471452836373002e-01, + 0.509980592623761761961632446895e-01, + 0.428358980222266806568786466061e-01, + 0.342738629130214331026877322524e-01, + 0.253920653092620594557525897892e-01, + 0.162743947309056706051705622064e-01, + 0.701861000947009660040706373885e-02, + // weights 64 + 0.178328072169643294729607914497e-02, + 0.414703326056246763528753572855e-02, + 0.650445796897836285611736039998e-02, + 0.884675982636394772303091465973e-02, + 0.111681394601311288185904930192e-01, + 0.134630478967186425980607666860e-01, + 0.157260304760247193219659952975e-01, + 0.179517157756973430850453020011e-01, + 0.201348231535302093723403167285e-01, + 0.222701738083832541592983303842e-01, + 0.243527025687108733381775504091e-01, + 0.263774697150546586716917926252e-01, + 0.283396726142594832275113052002e-01, + 0.302346570724024788679740598195e-01, + 0.320579283548515535854675043479e-01, + 0.338051618371416093915654821107e-01, + 0.354722132568823838106931467152e-01, + 0.370551285402400460404151018096e-01, + 0.385501531786156291289624969468e-01, + 0.399537411327203413866569261283e-01, + 0.412625632426235286101562974736e-01, + 0.424735151236535890073397679088e-01, + 0.435837245293234533768278609737e-01, + 0.445905581637565630601347100309e-01, + 0.454916279274181444797709969713e-01, + 0.462847965813144172959532492323e-01, + 0.469681828162100173253262857546e-01, + 0.475401657148303086622822069442e-01, + 0.479993885964583077281261798713e-01, + 0.483447622348029571697695271580e-01, + 0.485754674415034269347990667840e-01, + 0.486909570091397203833653907347e-01, + 0.486909570091397203833653907347e-01, + 0.485754674415034269347990667840e-01, + 0.483447622348029571697695271580e-01, + 0.479993885964583077281261798713e-01, + 0.475401657148303086622822069442e-01, + 0.469681828162100173253262857546e-01, + 0.462847965813144172959532492323e-01, + 0.454916279274181444797709969713e-01, + 0.445905581637565630601347100309e-01, + 0.435837245293234533768278609737e-01, + 0.424735151236535890073397679088e-01, + 0.412625632426235286101562974736e-01, + 0.399537411327203413866569261283e-01, + 0.385501531786156291289624969468e-01, + 0.370551285402400460404151018096e-01, + 0.354722132568823838106931467152e-01, + 0.338051618371416093915654821107e-01, + 0.320579283548515535854675043479e-01, + 0.302346570724024788679740598195e-01, + 0.283396726142594832275113052002e-01, + 0.263774697150546586716917926252e-01, + 0.243527025687108733381775504091e-01, + 0.222701738083832541592983303842e-01, + 0.201348231535302093723403167285e-01, + 0.179517157756973430850453020011e-01, + 0.157260304760247193219659952975e-01, + 0.134630478967186425980607666860e-01, + 0.111681394601311288185904930192e-01, + 0.884675982636394772303091465973e-02, + 0.650445796897836285611736039998e-02, + 0.414703326056246763528753572855e-02, + 0.178328072169643294729607914497e-02 + }; // Points, starting with the first level -static const double gl_points[] = { - // points 1 - 0.0e+00, - // points 2 - -0.577350269189625764509148780502e+00, - 0.577350269189625764509148780502e+00, - // points 3 - -0.774596669241483377035853079956e+00, - 0.0e+00, - 0.774596669241483377035853079956e+00, - // points 4 - -0.861136311594052575223946488893e+00, - -0.339981043584856264802665759103e+00, - 0.339981043584856264802665759103e+00, - 0.861136311594052575223946488893e+00, - // points 5 - -0.906179845938663992797626878299e+00, - -0.538469310105683091036314420700e+00, - 0.0e+00, - 0.538469310105683091036314420700e+00, - 0.906179845938663992797626878299e+00, - // points 6 - -0.932469514203152027812301554494e+00, - -0.661209386466264513661399595020e+00, - -0.238619186083196908630501721681e+00, - 0.238619186083196908630501721681e+00, - 0.661209386466264513661399595020e+00, - 0.932469514203152027812301554494e+00, - // points 7 - -0.949107912342758524526189684048e+00, - -0.741531185599394439863864773281e+00, - -0.405845151377397166906606412077e+00, - 0.0e+00, - 0.405845151377397166906606412077e+00, - 0.741531185599394439863864773281e+00, - 0.949107912342758524526189684048e+00, - // points 8 - -0.960289856497536231683560868569e+00, - -0.796666477413626739591553936476e+00, - -0.525532409916328985817739049189e+00, - -0.183434642495649804939476142360e+00, - 0.183434642495649804939476142360e+00, - 0.525532409916328985817739049189e+00, - 0.796666477413626739591553936476e+00, - 0.960289856497536231683560868569e+00, - // points 9 - -0.968160239507626089835576202904e+00, - -0.836031107326635794299429788070e+00, - -0.613371432700590397308702039341e+00, - -0.324253423403808929038538014643e+00, - 0.0e+00, - 0.324253423403808929038538014643e+00, - 0.613371432700590397308702039341e+00, - 0.836031107326635794299429788070e+00, - 0.968160239507626089835576202904e+00, - // points 10 - -0.973906528517171720077964012084e+00, - -0.865063366688984510732096688423e+00, - -0.679409568299024406234327365115e+00, - -0.433395394129247190799265943166e+00, - -0.148874338981631210884826001130e+00, - 0.148874338981631210884826001130e+00, - 0.433395394129247190799265943166e+00, - 0.679409568299024406234327365115e+00, - 0.865063366688984510732096688423e+00, - 0.973906528517171720077964012084e+00, - // points 11 - -0.978228658146056992803938001123e+00, - -0.887062599768095299075157769304e+00, - -0.730152005574049324093416252031e+00, - -0.519096129206811815925725669459e+00, - -0.269543155952344972331531985401e+00, - 0.0e+00, - 0.269543155952344972331531985401e+00, - 0.519096129206811815925725669459e+00, - 0.730152005574049324093416252031e+00, - 0.887062599768095299075157769304e+00, - 0.978228658146056992803938001123e+00, - // points 12 - -0.981560634246719250690549090149e+00, - -0.904117256370474856678465866119e+00, - -0.769902674194304687036893833213e+00, - -0.587317954286617447296702418941e+00, - -0.367831498998180193752691536644e+00, - -0.125233408511468915472441369464e+00, - 0.125233408511468915472441369464e+00, - 0.367831498998180193752691536644e+00, - 0.587317954286617447296702418941e+00, - 0.769902674194304687036893833213e+00, - 0.904117256370474856678465866119e+00, - 0.981560634246719250690549090149e+00, - // points 13 - -0.984183054718588149472829448807e+00, - -0.917598399222977965206547836501e+00, - -0.801578090733309912794206489583e+00, - -0.642349339440340220643984606996e+00, - -0.448492751036446852877912852128e+00, - -0.230458315955134794065528121098e+00, - 0.0e+00, - 0.230458315955134794065528121098e+00, - 0.448492751036446852877912852128e+00, - 0.642349339440340220643984606996e+00, - 0.801578090733309912794206489583e+00, - 0.917598399222977965206547836501e+00, - 0.984183054718588149472829448807e+00, - // points 14 - -0.986283808696812338841597266704e+00, - -0.928434883663573517336391139378e+00, - -0.827201315069764993189794742650e+00, - -0.687292904811685470148019803019e+00, - -0.515248636358154091965290718551e+00, - -0.319112368927889760435671824168e+00, - -0.108054948707343662066244650220e+00, - 0.108054948707343662066244650220e+00, - 0.319112368927889760435671824168e+00, - 0.515248636358154091965290718551e+00, - 0.687292904811685470148019803019e+00, - 0.827201315069764993189794742650e+00, - 0.928434883663573517336391139378e+00, - 0.986283808696812338841597266704e+00, - // points 15 - -0.987992518020485428489565718587e+00, - -0.937273392400705904307758947710e+00, - -0.848206583410427216200648320774e+00, - -0.724417731360170047416186054614e+00, - -0.570972172608538847537226737254e+00, - -0.394151347077563369897207370981e+00, - -0.201194093997434522300628303395e+00, - 0.0e+00, - 0.201194093997434522300628303395e+00, - 0.394151347077563369897207370981e+00, - 0.570972172608538847537226737254e+00, - 0.724417731360170047416186054614e+00, - 0.848206583410427216200648320774e+00, - 0.937273392400705904307758947710e+00, - 0.987992518020485428489565718587e+00, - // points 16 - -0.989400934991649932596154173450e+00, - -0.944575023073232576077988415535e+00, - -0.865631202387831743880467897712e+00, - -0.755404408355003033895101194847e+00, - -0.617876244402643748446671764049e+00, - -0.458016777657227386342419442984e+00, - -0.281603550779258913230460501460e+00, - -0.950125098376374401853193354250e-01, - 0.950125098376374401853193354250e-01, - 0.281603550779258913230460501460e+00, - 0.458016777657227386342419442984e+00, - 0.617876244402643748446671764049e+00, - 0.755404408355003033895101194847e+00, - 0.865631202387831743880467897712e+00, - 0.944575023073232576077988415535e+00, - 0.989400934991649932596154173450e+00, - // points 17 - -0.990575475314417335675434019941e+00, - -0.950675521768767761222716957896e+00, - -0.880239153726985902122955694488e+00, - -0.781514003896801406925230055520e+00, - -0.657671159216690765850302216643e+00, - -0.512690537086476967886246568630e+00, - -0.351231763453876315297185517095e+00, - -0.178484181495847855850677493654e+00, - 0.0e+00, - 0.178484181495847855850677493654e+00, - 0.351231763453876315297185517095e+00, - 0.512690537086476967886246568630e+00, - 0.657671159216690765850302216643e+00, - 0.781514003896801406925230055520e+00, - 0.880239153726985902122955694488e+00, - 0.950675521768767761222716957896e+00, - 0.990575475314417335675434019941e+00, - // points 18 - -0.991565168420930946730016004706e+00, - -0.955823949571397755181195892930e+00, - -0.892602466497555739206060591127e+00, - -0.803704958972523115682417455015e+00, - -0.691687043060353207874891081289e+00, - -0.559770831073947534607871548525e+00, - -0.411751161462842646035931793833e+00, - -0.251886225691505509588972854878e+00, - -0.847750130417353012422618529358e-01, - 0.847750130417353012422618529358e-01, - 0.251886225691505509588972854878e+00, - 0.411751161462842646035931793833e+00, - 0.559770831073947534607871548525e+00, - 0.691687043060353207874891081289e+00, - 0.803704958972523115682417455015e+00, - 0.892602466497555739206060591127e+00, - 0.955823949571397755181195892930e+00, - 0.991565168420930946730016004706e+00, - // points 19 - -0.992406843843584403189017670253e+00, - -0.960208152134830030852778840688e+00, - -0.903155903614817901642660928532e+00, - -0.822714656537142824978922486713e+00, - -0.720966177335229378617095860824e+00, - -0.600545304661681023469638164946e+00, - -0.464570741375960945717267148104e+00, - -0.316564099963629831990117328850e+00, - -0.160358645640225375868096115741e+00, - 0.0e+00, - 0.160358645640225375868096115741e+00, - 0.316564099963629831990117328850e+00, - 0.464570741375960945717267148104e+00, - 0.600545304661681023469638164946e+00, - 0.720966177335229378617095860824e+00, - 0.822714656537142824978922486713e+00, - 0.903155903614817901642660928532e+00, - 0.960208152134830030852778840688e+00, - 0.992406843843584403189017670253e+00, - // points 20 - -0.993128599185094924786122388471e+00, - -0.963971927277913791267666131197e+00, - -0.912234428251325905867752441203e+00, - -0.839116971822218823394529061702e+00, - -0.746331906460150792614305070356e+00, - -0.636053680726515025452836696226e+00, - -0.510867001950827098004364050955e+00, - -0.373706088715419560672548177025e+00, - -0.227785851141645078080496195369e+00, - -0.765265211334973337546404093988e-01, - 0.765265211334973337546404093988e-01, - 0.227785851141645078080496195369e+00, - 0.373706088715419560672548177025e+00, - 0.510867001950827098004364050955e+00, - 0.636053680726515025452836696226e+00, - 0.746331906460150792614305070356e+00, - 0.839116971822218823394529061702e+00, - 0.912234428251325905867752441203e+00, - 0.963971927277913791267666131197e+00, - 0.993128599185094924786122388471e+00, - // points 32 - -0.997263861849481563544981128665e+00, - -0.985611511545268335400175044631e+00, - -0.964762255587506430773811928118e+00, - -0.934906075937739689170919134835e+00, - -0.896321155766052123965307243719e+00, - -0.849367613732569970133693004968e+00, - -0.794483795967942406963097298970e+00, - -0.732182118740289680387426665091e+00, - -0.663044266930215200975115168663e+00, - -0.587715757240762329040745476402e+00, - -0.506899908932229390023747474378e+00, - -0.421351276130635345364119436172e+00, - -0.331868602282127649779916805730e+00, - -0.239287362252137074544603209166e+00, - -0.144471961582796493485186373599e+00, - -0.483076656877383162348125704405e-01, - 0.483076656877383162348125704405e-01, - 0.144471961582796493485186373599e+00, - 0.239287362252137074544603209166e+00, - 0.331868602282127649779916805730e+00, - 0.421351276130635345364119436172e+00, - 0.506899908932229390023747474378e+00, - 0.587715757240762329040745476402e+00, - 0.663044266930215200975115168663e+00, - 0.732182118740289680387426665091e+00, - 0.794483795967942406963097298970e+00, - 0.849367613732569970133693004968e+00, - 0.896321155766052123965307243719e+00, - 0.934906075937739689170919134835e+00, - 0.964762255587506430773811928118e+00, - 0.985611511545268335400175044631e+00, - 0.997263861849481563544981128665e+00, - // points 64 - -0.999305041735772139456905624346e+00, - -0.996340116771955279346924500676e+00, - -0.991013371476744320739382383443e+00, - -0.983336253884625956931299302157e+00, - -0.973326827789910963741853507352e+00, - -0.961008799652053718918614121897e+00, - -0.946411374858402816062481491347e+00, - -0.929569172131939575821490154559e+00, - -0.910522137078502805756380668008e+00, - -0.889315445995114105853404038273e+00, - -0.865999398154092819760783385070e+00, - -0.840629296252580362751691544696e+00, - -0.813265315122797559741923338086e+00, - -0.783972358943341407610220525214e+00, - -0.752819907260531896611863774886e+00, - -0.719881850171610826848940217832e+00, - -0.685236313054233242563558371031e+00, - -0.648965471254657339857761231993e+00, - -0.611155355172393250248852971019e+00, - -0.571895646202634034283878116659e+00, - -0.531279464019894545658013903544e+00, - -0.489403145707052957478526307022e+00, - -0.446366017253464087984947714759e+00, - -0.402270157963991603695766771260e+00, - -0.357220158337668115950442615046e+00, - -0.311322871990210956157512698560e+00, - -0.264687162208767416373964172510e+00, - -0.217423643740007084149648748989e+00, - -0.169644420423992818037313629748e+00, - -0.121462819296120554470376463492e+00, - -0.729931217877990394495429419403e-01, - -0.243502926634244325089558428537e-01, - 0.243502926634244325089558428537e-01, - 0.729931217877990394495429419403e-01, - 0.121462819296120554470376463492e+00, - 0.169644420423992818037313629748e+00, - 0.217423643740007084149648748989e+00, - 0.264687162208767416373964172510e+00, - 0.311322871990210956157512698560e+00, - 0.357220158337668115950442615046e+00, - 0.402270157963991603695766771260e+00, - 0.446366017253464087984947714759e+00, - 0.489403145707052957478526307022e+00, - 0.531279464019894545658013903544e+00, - 0.571895646202634034283878116659e+00, - 0.611155355172393250248852971019e+00, - 0.648965471254657339857761231993e+00, - 0.685236313054233242563558371031e+00, - 0.719881850171610826848940217832e+00, - 0.752819907260531896611863774886e+00, - 0.783972358943341407610220525214e+00, - 0.813265315122797559741923338086e+00, - 0.840629296252580362751691544696e+00, - 0.865999398154092819760783385070e+00, - 0.889315445995114105853404038273e+00, - 0.910522137078502805756380668008e+00, - 0.929569172131939575821490154559e+00, - 0.946411374858402816062481491347e+00, - 0.961008799652053718918614121897e+00, - 0.973326827789910963741853507352e+00, - 0.983336253884625956931299302157e+00, - 0.991013371476744320739382383443e+00, - 0.996340116771955279346924500676e+00, - 0.999305041735772139456905624346e+00 -}; +static const double gl_points[] = + { + // points 1 + 0.0e+00, + // points 2 + -0.577350269189625764509148780502e+00, + 0.577350269189625764509148780502e+00, + // points 3 + -0.774596669241483377035853079956e+00, + 0.0e+00, + 0.774596669241483377035853079956e+00, + // points 4 + -0.861136311594052575223946488893e+00, + -0.339981043584856264802665759103e+00, + 0.339981043584856264802665759103e+00, + 0.861136311594052575223946488893e+00, + // points 5 + -0.906179845938663992797626878299e+00, + -0.538469310105683091036314420700e+00, + 0.0e+00, + 0.538469310105683091036314420700e+00, + 0.906179845938663992797626878299e+00, + // points 6 + -0.932469514203152027812301554494e+00, + -0.661209386466264513661399595020e+00, + -0.238619186083196908630501721681e+00, + 0.238619186083196908630501721681e+00, + 0.661209386466264513661399595020e+00, + 0.932469514203152027812301554494e+00, + // points 7 + -0.949107912342758524526189684048e+00, + -0.741531185599394439863864773281e+00, + -0.405845151377397166906606412077e+00, + 0.0e+00, + 0.405845151377397166906606412077e+00, + 0.741531185599394439863864773281e+00, + 0.949107912342758524526189684048e+00, + // points 8 + -0.960289856497536231683560868569e+00, + -0.796666477413626739591553936476e+00, + -0.525532409916328985817739049189e+00, + -0.183434642495649804939476142360e+00, + 0.183434642495649804939476142360e+00, + 0.525532409916328985817739049189e+00, + 0.796666477413626739591553936476e+00, + 0.960289856497536231683560868569e+00, + // points 9 + -0.968160239507626089835576202904e+00, + -0.836031107326635794299429788070e+00, + -0.613371432700590397308702039341e+00, + -0.324253423403808929038538014643e+00, + 0.0e+00, + 0.324253423403808929038538014643e+00, + 0.613371432700590397308702039341e+00, + 0.836031107326635794299429788070e+00, + 0.968160239507626089835576202904e+00, + // points 10 + -0.973906528517171720077964012084e+00, + -0.865063366688984510732096688423e+00, + -0.679409568299024406234327365115e+00, + -0.433395394129247190799265943166e+00, + -0.148874338981631210884826001130e+00, + 0.148874338981631210884826001130e+00, + 0.433395394129247190799265943166e+00, + 0.679409568299024406234327365115e+00, + 0.865063366688984510732096688423e+00, + 0.973906528517171720077964012084e+00, + // points 11 + -0.978228658146056992803938001123e+00, + -0.887062599768095299075157769304e+00, + -0.730152005574049324093416252031e+00, + -0.519096129206811815925725669459e+00, + -0.269543155952344972331531985401e+00, + 0.0e+00, + 0.269543155952344972331531985401e+00, + 0.519096129206811815925725669459e+00, + 0.730152005574049324093416252031e+00, + 0.887062599768095299075157769304e+00, + 0.978228658146056992803938001123e+00, + // points 12 + -0.981560634246719250690549090149e+00, + -0.904117256370474856678465866119e+00, + -0.769902674194304687036893833213e+00, + -0.587317954286617447296702418941e+00, + -0.367831498998180193752691536644e+00, + -0.125233408511468915472441369464e+00, + 0.125233408511468915472441369464e+00, + 0.367831498998180193752691536644e+00, + 0.587317954286617447296702418941e+00, + 0.769902674194304687036893833213e+00, + 0.904117256370474856678465866119e+00, + 0.981560634246719250690549090149e+00, + // points 13 + -0.984183054718588149472829448807e+00, + -0.917598399222977965206547836501e+00, + -0.801578090733309912794206489583e+00, + -0.642349339440340220643984606996e+00, + -0.448492751036446852877912852128e+00, + -0.230458315955134794065528121098e+00, + 0.0e+00, + 0.230458315955134794065528121098e+00, + 0.448492751036446852877912852128e+00, + 0.642349339440340220643984606996e+00, + 0.801578090733309912794206489583e+00, + 0.917598399222977965206547836501e+00, + 0.984183054718588149472829448807e+00, + // points 14 + -0.986283808696812338841597266704e+00, + -0.928434883663573517336391139378e+00, + -0.827201315069764993189794742650e+00, + -0.687292904811685470148019803019e+00, + -0.515248636358154091965290718551e+00, + -0.319112368927889760435671824168e+00, + -0.108054948707343662066244650220e+00, + 0.108054948707343662066244650220e+00, + 0.319112368927889760435671824168e+00, + 0.515248636358154091965290718551e+00, + 0.687292904811685470148019803019e+00, + 0.827201315069764993189794742650e+00, + 0.928434883663573517336391139378e+00, + 0.986283808696812338841597266704e+00, + // points 15 + -0.987992518020485428489565718587e+00, + -0.937273392400705904307758947710e+00, + -0.848206583410427216200648320774e+00, + -0.724417731360170047416186054614e+00, + -0.570972172608538847537226737254e+00, + -0.394151347077563369897207370981e+00, + -0.201194093997434522300628303395e+00, + 0.0e+00, + 0.201194093997434522300628303395e+00, + 0.394151347077563369897207370981e+00, + 0.570972172608538847537226737254e+00, + 0.724417731360170047416186054614e+00, + 0.848206583410427216200648320774e+00, + 0.937273392400705904307758947710e+00, + 0.987992518020485428489565718587e+00, + // points 16 + -0.989400934991649932596154173450e+00, + -0.944575023073232576077988415535e+00, + -0.865631202387831743880467897712e+00, + -0.755404408355003033895101194847e+00, + -0.617876244402643748446671764049e+00, + -0.458016777657227386342419442984e+00, + -0.281603550779258913230460501460e+00, + -0.950125098376374401853193354250e-01, + 0.950125098376374401853193354250e-01, + 0.281603550779258913230460501460e+00, + 0.458016777657227386342419442984e+00, + 0.617876244402643748446671764049e+00, + 0.755404408355003033895101194847e+00, + 0.865631202387831743880467897712e+00, + 0.944575023073232576077988415535e+00, + 0.989400934991649932596154173450e+00, + // points 17 + -0.990575475314417335675434019941e+00, + -0.950675521768767761222716957896e+00, + -0.880239153726985902122955694488e+00, + -0.781514003896801406925230055520e+00, + -0.657671159216690765850302216643e+00, + -0.512690537086476967886246568630e+00, + -0.351231763453876315297185517095e+00, + -0.178484181495847855850677493654e+00, + 0.0e+00, + 0.178484181495847855850677493654e+00, + 0.351231763453876315297185517095e+00, + 0.512690537086476967886246568630e+00, + 0.657671159216690765850302216643e+00, + 0.781514003896801406925230055520e+00, + 0.880239153726985902122955694488e+00, + 0.950675521768767761222716957896e+00, + 0.990575475314417335675434019941e+00, + // points 18 + -0.991565168420930946730016004706e+00, + -0.955823949571397755181195892930e+00, + -0.892602466497555739206060591127e+00, + -0.803704958972523115682417455015e+00, + -0.691687043060353207874891081289e+00, + -0.559770831073947534607871548525e+00, + -0.411751161462842646035931793833e+00, + -0.251886225691505509588972854878e+00, + -0.847750130417353012422618529358e-01, + 0.847750130417353012422618529358e-01, + 0.251886225691505509588972854878e+00, + 0.411751161462842646035931793833e+00, + 0.559770831073947534607871548525e+00, + 0.691687043060353207874891081289e+00, + 0.803704958972523115682417455015e+00, + 0.892602466497555739206060591127e+00, + 0.955823949571397755181195892930e+00, + 0.991565168420930946730016004706e+00, + // points 19 + -0.992406843843584403189017670253e+00, + -0.960208152134830030852778840688e+00, + -0.903155903614817901642660928532e+00, + -0.822714656537142824978922486713e+00, + -0.720966177335229378617095860824e+00, + -0.600545304661681023469638164946e+00, + -0.464570741375960945717267148104e+00, + -0.316564099963629831990117328850e+00, + -0.160358645640225375868096115741e+00, + 0.0e+00, + 0.160358645640225375868096115741e+00, + 0.316564099963629831990117328850e+00, + 0.464570741375960945717267148104e+00, + 0.600545304661681023469638164946e+00, + 0.720966177335229378617095860824e+00, + 0.822714656537142824978922486713e+00, + 0.903155903614817901642660928532e+00, + 0.960208152134830030852778840688e+00, + 0.992406843843584403189017670253e+00, + // points 20 + -0.993128599185094924786122388471e+00, + -0.963971927277913791267666131197e+00, + -0.912234428251325905867752441203e+00, + -0.839116971822218823394529061702e+00, + -0.746331906460150792614305070356e+00, + -0.636053680726515025452836696226e+00, + -0.510867001950827098004364050955e+00, + -0.373706088715419560672548177025e+00, + -0.227785851141645078080496195369e+00, + -0.765265211334973337546404093988e-01, + 0.765265211334973337546404093988e-01, + 0.227785851141645078080496195369e+00, + 0.373706088715419560672548177025e+00, + 0.510867001950827098004364050955e+00, + 0.636053680726515025452836696226e+00, + 0.746331906460150792614305070356e+00, + 0.839116971822218823394529061702e+00, + 0.912234428251325905867752441203e+00, + 0.963971927277913791267666131197e+00, + 0.993128599185094924786122388471e+00, + // points 32 + -0.997263861849481563544981128665e+00, + -0.985611511545268335400175044631e+00, + -0.964762255587506430773811928118e+00, + -0.934906075937739689170919134835e+00, + -0.896321155766052123965307243719e+00, + -0.849367613732569970133693004968e+00, + -0.794483795967942406963097298970e+00, + -0.732182118740289680387426665091e+00, + -0.663044266930215200975115168663e+00, + -0.587715757240762329040745476402e+00, + -0.506899908932229390023747474378e+00, + -0.421351276130635345364119436172e+00, + -0.331868602282127649779916805730e+00, + -0.239287362252137074544603209166e+00, + -0.144471961582796493485186373599e+00, + -0.483076656877383162348125704405e-01, + 0.483076656877383162348125704405e-01, + 0.144471961582796493485186373599e+00, + 0.239287362252137074544603209166e+00, + 0.331868602282127649779916805730e+00, + 0.421351276130635345364119436172e+00, + 0.506899908932229390023747474378e+00, + 0.587715757240762329040745476402e+00, + 0.663044266930215200975115168663e+00, + 0.732182118740289680387426665091e+00, + 0.794483795967942406963097298970e+00, + 0.849367613732569970133693004968e+00, + 0.896321155766052123965307243719e+00, + 0.934906075937739689170919134835e+00, + 0.964762255587506430773811928118e+00, + 0.985611511545268335400175044631e+00, + 0.997263861849481563544981128665e+00, + // points 64 + -0.999305041735772139456905624346e+00, + -0.996340116771955279346924500676e+00, + -0.991013371476744320739382383443e+00, + -0.983336253884625956931299302157e+00, + -0.973326827789910963741853507352e+00, + -0.961008799652053718918614121897e+00, + -0.946411374858402816062481491347e+00, + -0.929569172131939575821490154559e+00, + -0.910522137078502805756380668008e+00, + -0.889315445995114105853404038273e+00, + -0.865999398154092819760783385070e+00, + -0.840629296252580362751691544696e+00, + -0.813265315122797559741923338086e+00, + -0.783972358943341407610220525214e+00, + -0.752819907260531896611863774886e+00, + -0.719881850171610826848940217832e+00, + -0.685236313054233242563558371031e+00, + -0.648965471254657339857761231993e+00, + -0.611155355172393250248852971019e+00, + -0.571895646202634034283878116659e+00, + -0.531279464019894545658013903544e+00, + -0.489403145707052957478526307022e+00, + -0.446366017253464087984947714759e+00, + -0.402270157963991603695766771260e+00, + -0.357220158337668115950442615046e+00, + -0.311322871990210956157512698560e+00, + -0.264687162208767416373964172510e+00, + -0.217423643740007084149648748989e+00, + -0.169644420423992818037313629748e+00, + -0.121462819296120554470376463492e+00, + -0.729931217877990394495429419403e-01, + -0.243502926634244325089558428537e-01, + 0.243502926634244325089558428537e-01, + 0.729931217877990394495429419403e-01, + 0.121462819296120554470376463492e+00, + 0.169644420423992818037313629748e+00, + 0.217423643740007084149648748989e+00, + 0.264687162208767416373964172510e+00, + 0.311322871990210956157512698560e+00, + 0.357220158337668115950442615046e+00, + 0.402270157963991603695766771260e+00, + 0.446366017253464087984947714759e+00, + 0.489403145707052957478526307022e+00, + 0.531279464019894545658013903544e+00, + 0.571895646202634034283878116659e+00, + 0.611155355172393250248852971019e+00, + 0.648965471254657339857761231993e+00, + 0.685236313054233242563558371031e+00, + 0.719881850171610826848940217832e+00, + 0.752819907260531896611863774886e+00, + 0.783972358943341407610220525214e+00, + 0.813265315122797559741923338086e+00, + 0.840629296252580362751691544696e+00, + 0.865999398154092819760783385070e+00, + 0.889315445995114105853404038273e+00, + 0.910522137078502805756380668008e+00, + 0.929569172131939575821490154559e+00, + 0.946411374858402816062481491347e+00, + 0.961008799652053718918614121897e+00, + 0.973326827789910963741853507352e+00, + 0.983336253884625956931299302157e+00, + 0.991013371476744320739382383443e+00, + 0.996340116771955279346924500676e+00, + 0.999305041735772139456905624346e+00 + }; diff --git a/dynare++/integ/cc/quadrature.hh b/dynare++/integ/cc/quadrature.hh index 7c6cb8e2c..501713cfc 100644 --- a/dynare++/integ/cc/quadrature.hh +++ b/dynare++/integ/cc/quadrature.hh @@ -109,10 +109,10 @@ public: See QuadratureImpl class declaration for details. */ -template +template class QuadratureImpl; -template +template class IntegrationWorker : public sthread::detach_thread { const QuadratureImpl<_Tpit> &quad; @@ -168,7 +168,7 @@ public: In addition, we define a method which saves all the points to a given file. Only for debugging purposes. */ -template +template class QuadratureImpl : public Quadrature { friend class IntegrationWorker<_Tpit>; @@ -257,7 +257,7 @@ class OneDPrecalcQuadrature : public OneDQuadrature public: OneDPrecalcQuadrature(int nlevels, const int *npoints, const double *wts, const double *pts) - : num_levels(nlevels), num_points(npoints), + : num_levels(nlevels), num_points(npoints), weights(wts), points(pts), offsets(num_levels) { calcOffsets(); diff --git a/dynare++/integ/cc/quasi_mcarlo.cc b/dynare++/integ/cc/quasi_mcarlo.cc index fef6bfdf1..80c5740f6 100644 --- a/dynare++/integ/cc/quasi_mcarlo.cc +++ b/dynare++/integ/cc/quasi_mcarlo.cc @@ -106,25 +106,26 @@ RadicalInverse::print() const /* Here we have the first 170 primes. This means that we are not able to integrate dimensions greater than 170. */ -std::array HaltonSequence::primes = { - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, - 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, - 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, - 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, - 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, - 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, - 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, - 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, - 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, - 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, - 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, - 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, - 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, - 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, - 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, - 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, - 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013 -}; +std::array HaltonSequence::primes = + { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, + 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, + 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, + 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, + 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, + 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, + 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, + 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, + 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, + 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013 + }; /* This takes first ‘dim’ primes and constructs ‘dim’ radical inverses and calls eval(). */ @@ -145,7 +146,7 @@ HaltonSequence::HaltonSequence(int n, int mxn, int dim, const PermutationScheme void HaltonSequence::increase() { - for (auto & i : ri) + for (auto &i : ri) i.increase(); num++; if (num <= maxn) @@ -165,7 +166,7 @@ void HaltonSequence::print() const { auto ff = std::cout.flags(); - for (const auto & i : ri) + for (const auto &i : ri) i.print(); std::cout << "point=[ " << std::fixed << std::setprecision(6); diff --git a/dynare++/integ/cc/vector_function.cc b/dynare++/integ/cc/vector_function.cc index bca1b1afa..c541ba0f2 100644 --- a/dynare++/integ/cc/vector_function.cc +++ b/dynare++/integ/cc/vector_function.cc @@ -70,7 +70,6 @@ VectorFunctionSet::VectorFunctionSet(VectorFunction &f, int n) } } - /* Here we construct the object from the given function f and given variance-covariance matrix Σ=vcov. The matrix A is calculated as lower triangular and yields Σ=AAᵀ. */ diff --git a/dynare++/integ/src/quadrature-points.cc b/dynare++/integ/src/quadrature-points.cc index 0e62fef04..2973a222f 100644 --- a/dynare++/integ/src/quadrature-points.cc +++ b/dynare++/integ/src/quadrature-points.cc @@ -47,7 +47,7 @@ struct QuadParams QuadParams(int argc, char **argv); void check_consistency() const; private: - enum class opt {max_level, discard_weight, vcov}; + enum class opt { max_level, discard_weight, vcov }; }; QuadParams::QuadParams(int argc, char **argv) @@ -62,11 +62,11 @@ QuadParams::QuadParams(int argc, char **argv) outname = argv[argc-1]; argc--; - struct option const opts [] = { - {"max-level", required_argument, nullptr, static_cast(opt::max_level)}, - {"discard-weight", required_argument, nullptr, static_cast(opt::discard_weight)}, - {"vcov", required_argument, nullptr, static_cast(opt::vcov)}, - {nullptr, 0, nullptr, 0} + struct option const opts[] = { + {"max-level", required_argument, nullptr, static_cast(opt::max_level)}, + {"discard-weight", required_argument, nullptr, static_cast(opt::discard_weight)}, + {"vcov", required_argument, nullptr, static_cast(opt::vcov)}, + {nullptr, 0, nullptr, 0} }; int ret; @@ -188,7 +188,7 @@ main(int argc, char **argv) // Calculate weights and mass double mass = 0.0; std::vector weights; - for (auto & point : points) + for (auto &point : points) { weights.push_back(std::exp(-point->dot(*point))); mass += weights.back(); diff --git a/dynare++/integ/testing/tests.cc b/dynare++/integ/testing/tests.cc index 030fe5b1a..9143ddac1 100644 --- a/dynare++/integ/testing/tests.cc +++ b/dynare++/integ/testing/tests.cc @@ -177,7 +177,7 @@ Function1Trans::eval(const Vector &point, const ParameterSignal &sig, Vector &ou } /* WallTimer class. Constructor saves the wall time, destructor cancels the - current time from the saved, and prints the message with time information */ + current time from the saved, and prints the message with time information */ class WallTimer { std::string mes; diff --git a/dynare++/kord/approximation.cc b/dynare++/kord/approximation.cc index 2c97471da..045753d2d 100644 --- a/dynare++/kord/approximation.cc +++ b/dynare++/kord/approximation.cc @@ -51,7 +51,7 @@ Approximation::Approximation(DynamicModel &m, Journal &j, int ns, bool dr_centr, : model(m), journal(j), ypart(model.nstat(), model.npred(), model.nboth(), model.nforw()), mom(UNormalMoments(model.order(), model.getVcov())), - nvs{ypart.nys(), model.nexog(), model.nexog(), 1 }, + nvs{ypart.nys(), model.nexog(), model.nexog(), 1}, steps(ns), dr_centralize(dr_centr), qz_criterium(qz_crit), ss(ypart.ny(), steps+1) { @@ -184,7 +184,7 @@ Approximation::walkStochSteady() dy.add(-1.0, last_steady); StochForwardDerivs hh(ypart, model.nexog(), *rule_ders_ss, mom, dy, - dsigma, sigma_so_far); + dsigma, sigma_so_far); JournalRecord rec1(journal); rec1 << "Calculation of g** expectations done" << endrec; diff --git a/dynare++/kord/decision_rule.cc b/dynare++/kord/decision_rule.cc index f9e86a685..5d0a624f4 100644 --- a/dynare++/kord/decision_rule.cc +++ b/dynare++/kord/decision_rule.cc @@ -34,7 +34,7 @@ // FoldDecisionRule conversion from UnfoldDecisionRule FoldDecisionRule::FoldDecisionRule(const UnfoldDecisionRule &udr) : DecisionRuleImpl(ctraits::Tpol(udr.nrows(), udr.nvars()), - udr.ypart, udr.nu, udr.ysteady) + udr.ypart, udr.nu, udr.ysteady) { for (const auto &it : udr) insert(std::make_unique::Ttensym>(*(it.second))); @@ -43,7 +43,7 @@ FoldDecisionRule::FoldDecisionRule(const UnfoldDecisionRule &udr) // UnfoldDecisionRule conversion from FoldDecisionRule UnfoldDecisionRule::UnfoldDecisionRule(const FoldDecisionRule &fdr) : DecisionRuleImpl(ctraits::Tpol(fdr.nrows(), fdr.nvars()), - fdr.ypart, fdr.nu, fdr.ysteady) + fdr.ypart, fdr.nu, fdr.ysteady) { for (const auto &it : fdr) insert(std::make_unique::Ttensym>(*(it.second))); diff --git a/dynare++/kord/decision_rule.hh b/dynare++/kord/decision_rule.hh index 1d70ff99a..6bf3e9834 100644 --- a/dynare++/kord/decision_rule.hh +++ b/dynare++/kord/decision_rule.hh @@ -75,7 +75,7 @@ public: virtual void eval(emethod em, Vector &out, const ConstVector &v) const = 0; /* makes only one step of simulation (in terms of absolute values, not - deviations) */ + deviations) */ virtual void evaluate(emethod em, Vector &out, const ConstVector &ys, const ConstVector &u) const = 0; @@ -120,7 +120,7 @@ public: Storage::unfold. So, there are two implementations of the DecisionRule interface. */ -template +template class DecisionRuleImpl : public ctraits::Tpol, public DecisionRule { protected: @@ -180,6 +180,7 @@ public: protected: void fillTensors(const _Tg &g, double sigma); void centralize(const DecisionRuleImpl &dr); +public: void eval(emethod em, Vector &out, const ConstVector &v) const override; }; @@ -219,7 +220,7 @@ protected: So we go through i+j=d=0…q and in each loop we form the fully symmetric tensor [g_(yu)ᵈ] and insert it to the container. */ -template +template void DecisionRuleImpl::fillTensors(const _Tg &g, double sigma) { @@ -276,7 +277,7 @@ DecisionRuleImpl::fillTensors(const _Tg &g, double sigma) where ȳ is the steady state of the original rule ‘dr’. */ -template +template void DecisionRuleImpl::centralize(const DecisionRuleImpl &dr) { @@ -309,7 +310,7 @@ DecisionRuleImpl::centralize(const DecisionRuleImpl &dr) canceled from ‘ystart’, we simulate, and at the end ‘ysteady’ is added to all columns of the result. */ -template +template TwoDMatrix DecisionRuleImpl::simulate(emethod em, int np, const ConstVector &ystart, ShockRealization &sr) const @@ -377,7 +378,7 @@ DecisionRuleImpl::simulate(emethod em, int np, const ConstVector &ystart, steady state (fix point) is cancelled and added once. Hence we have two special methods. */ -template +template void DecisionRuleImpl::evaluate(emethod em, Vector &out, const ConstVector &ys, const ConstVector &u) const @@ -400,7 +401,7 @@ DecisionRuleImpl::evaluate(emethod em, Vector &out, const ConstVector &ys, /* This is easy. We just return the newly created copy using the centralized constructor. */ -template +template std::unique_ptr DecisionRuleImpl::centralizedClone(const Vector &fixpoint) const { @@ -410,7 +411,7 @@ DecisionRuleImpl::centralizedClone(const Vector &fixpoint) const /* Here we only encapsulate two implementations to one, deciding according to the parameter. */ -template +template void DecisionRuleImpl::eval(emethod em, Vector &out, const ConstVector &v) const { @@ -422,7 +423,7 @@ DecisionRuleImpl::eval(emethod em, Vector &out, const ConstVector &v) const /* Write the decision rule and steady state to the MAT file. */ -template +template void DecisionRuleImpl::writeMat(mat_t *fd, const std::string &prefix) const { @@ -505,7 +506,7 @@ public: F is given by its derivatives ‘bigf’. The Jacobian of the solved system is given by derivatives stored in ‘bigfder’. */ -template +template class DRFixPoint : public ctraits::Tpol { using _Tpol = typename ctraits::Tpol; @@ -556,7 +557,7 @@ private: first derivative (Symmetry{1}). Then the derivative of the F polynomial is calculated. */ -template +template DRFixPoint::DRFixPoint(const _Tg &g, const PartitionY &yp, const Vector &ys, double sigma) : ctraits::Tpol(yp.ny(), yp.nys()), @@ -576,7 +577,7 @@ DRFixPoint::DRFixPoint(const _Tg &g, const PartitionY &yp, such that ‘d+k’ is between the maximum dimension and ‘d’, and add σᵏ/(d!k!)[g_yᵈσᵏ] to the tensor [g_yᵈ]. */ -template +template void DRFixPoint::fillTensors(const _Tg &g, double sigma) { @@ -611,7 +612,7 @@ DRFixPoint::fillTensors(const _Tg &g, double sigma) underrelaxation parameter ‘urelax’, which improves the residual. If ‘urelax’ is less that ‘urelax_threshold’, we stop searching and stop the Newton. */ -template +template bool DRFixPoint::solveNewton(Vector &y) { @@ -665,7 +666,7 @@ DRFixPoint::solveNewton(Vector &y) flastnorm = fnorm; } while (!converged && newton_iter_last < max_newton_iter - &&urelax > urelax_threshold); + && urelax > urelax_threshold); newton_iter_total += newton_iter_last; if (!converged) @@ -687,7 +688,7 @@ DRFixPoint::solveNewton(Vector &y) The ‘out’ vector is not touched if the algorithm has not convered. */ -template +template bool DRFixPoint::calcFixPoint(emethod em, Vector &out) { diff --git a/dynare++/kord/dynamic_model.hh b/dynare++/kord/dynamic_model.hh index ef9464339..cd129ccdd 100644 --- a/dynare++/kord/dynamic_model.hh +++ b/dynare++/kord/dynamic_model.hh @@ -18,7 +18,6 @@ * along with Dynare. If not, see . */ - // Dynamic model abstraction /* This file only defines a generic interface to a DSGE model. The model diff --git a/dynare++/kord/faa_di_bruno.hh b/dynare++/kord/faa_di_bruno.hh index 4442ba7c5..8ccbaf4bc 100644 --- a/dynare++/kord/faa_di_bruno.hh +++ b/dynare++/kord/faa_di_bruno.hh @@ -57,7 +57,7 @@ public: void calculate(const UnfoldedStackContainer &cont, const UGSContainer &g, UGSTensor &out); protected: - std::tuple estimRefinement(const TensorDimens &tdims, int nr, int l); + std::tuple estimRefinement(const TensorDimens &tdims, int nr, int l); // See FaaDiBruno::calculate() folded sparse code for why we have magic_mult constexpr static double magic_mult = 1.5; diff --git a/dynare++/kord/first_order.cc b/dynare++/kord/first_order.cc index 6d473d765..96508183c 100644 --- a/dynare++/kord/first_order.cc +++ b/dynare++/kord/first_order.cc @@ -178,9 +178,9 @@ FirstOrder::solve(const TwoDMatrix &fd) std::lock_guard lk{mut}; qz_criterium_global = qz_criterium; dgges("N", "V", "S", order_eigs, &n, matE.getData().base(), &lda, - matD.getData().base(), &ldb, &sdim2, alphar.base(), alphai.base(), - beta.base(), vsl.getData().base(), &ldvsl, vsr.getData().base(), &ldvsr, - work.base(), &lwork, bwork.get(), &info); + matD.getData().base(), &ldb, &sdim2, alphar.base(), alphai.base(), + beta.base(), vsl.getData().base(), &ldvsl, vsr.getData().base(), &ldvsr, + work.base(), &lwork, bwork.get(), &info); } if (info) throw KordException(__FILE__, __LINE__, diff --git a/dynare++/kord/first_order.hh b/dynare++/kord/first_order.hh index 044f7a4b1..6d3c35b01 100644 --- a/dynare++/kord/first_order.hh +++ b/dynare++/kord/first_order.hh @@ -31,7 +31,7 @@ template class FirstOrderDerivs; class FirstOrder { - template + template friend class FirstOrderDerivs; PartitionY ypart; int nu; @@ -89,7 +89,7 @@ protected: /* This class only converts the derivatives g_y* and gᵤ to a folded or unfolded container. */ -template +template class FirstOrderDerivs : public ctraits::Tg { public: diff --git a/dynare++/kord/global_check.hh b/dynare++/kord/global_check.hh index df7f913a8..8e7b35714 100644 --- a/dynare++/kord/global_check.hh +++ b/dynare++/kord/global_check.hh @@ -90,7 +90,7 @@ protected: public: ResidFunction(const Approximation &app); ResidFunction(const ResidFunction &rf); - + std::unique_ptr clone() const override { diff --git a/dynare++/kord/journal.cc b/dynare++/kord/journal.cc index e06d35beb..b8eaabd47 100644 --- a/dynare++/kord/journal.cc +++ b/dynare++/kord/journal.cc @@ -145,7 +145,7 @@ JournalRecord::writePrefix(const SystemResources &f) std::ostringstream s; s << std::setfill('0'); writeFloatTabular(s, f.elapsed, 7); - s << u8"│" << recChar << std::setw(5) << ord << u8"│"; + s << u8"│" << recChar << std::setw(5) << ord << u8"│"; writeFloatTabular(s, f.load_avg, 3); s << u8"│"; writeFloatTabular(s, f.mem_avail/mb, 5); diff --git a/dynare++/kord/kord_exception.hh b/dynare++/kord/kord_exception.hh index bd7febba8..f5777241e 100644 --- a/dynare++/kord/kord_exception.hh +++ b/dynare++/kord/kord_exception.hh @@ -26,18 +26,18 @@ #include #ifndef KORD_EXCEPTION_H -#define KORD_EXCEPTION_H +# define KORD_EXCEPTION_H -#define KORD_RAISE(mes) \ +# define KORD_RAISE(mes) \ throw KordException(__FILE__, __LINE__, mes); -#define KORD_RAISE_IF(expr, mes) \ +# define KORD_RAISE_IF(expr, mes) \ if (expr) throw KordException(__FILE__, __LINE__, mes); -#define KORD_RAISE_X(mes, c) \ +# define KORD_RAISE_X(mes, c) \ throw KordException(__FILE__, __LINE__, mes, c); -#define KORD_RAISE_IF_X(expr, mes, c) \ +# define KORD_RAISE_IF_X(expr, mes, c) \ if (expr) throw KordException(__FILE__, __LINE__, mes, c); class KordException diff --git a/dynare++/kord/korder.cc b/dynare++/kord/korder.cc index 0c0c265b0..3ba9425b5 100644 --- a/dynare++/kord/korder.cc +++ b/dynare++/kord/korder.cc @@ -112,117 +112,173 @@ MatrixS::MatrixS(const FSSparseTensor &f, const IntSequence &ss, interesting here. */ template<> -ctraits::Tg& KOrder::g() +ctraits::Tg & +KOrder::g() { return _ug; } template<> -const ctraits::Tg& KOrder::g() const -{ return _ug;} +const ctraits::Tg & +KOrder::g() const +{ + return _ug; +} template<> -ctraits::Tg& KOrder::g() +ctraits::Tg & +KOrder::g() { return _fg; } template<> -const ctraits::Tg& KOrder::g() const -{ return _fg;} +const ctraits::Tg & +KOrder::g() const +{ + return _fg; +} template<> -ctraits::Tgs& KOrder::gs() +ctraits::Tgs & +KOrder::gs() { return _ugs; } template<> -const ctraits::Tgs& KOrder::gs() const -{ return _ugs;} +const ctraits::Tgs & +KOrder::gs() const +{ + return _ugs; +} template<> -ctraits::Tgs& KOrder::gs() +ctraits::Tgs & +KOrder::gs() { return _fgs; } template<> -const ctraits::Tgs& KOrder::gs() const -{ return _fgs;} +const ctraits::Tgs & +KOrder::gs() const +{ + return _fgs; +} template<> -ctraits::Tgss& KOrder::gss() +ctraits::Tgss & +KOrder::gss() { return _ugss; } template<> -const ctraits::Tgss& KOrder::gss() const -{ return _ugss;} +const ctraits::Tgss & +KOrder::gss() const +{ + return _ugss; +} template<> -ctraits::Tgss& KOrder::gss() +ctraits::Tgss & +KOrder::gss() { return _fgss; } template<> -const ctraits::Tgss& KOrder::gss() const -{ return _fgss;} +const ctraits::Tgss & +KOrder::gss() const +{ + return _fgss; +} template<> -ctraits::TG& KOrder::G() +ctraits::TG & +KOrder::G() { return _uG; } template<> -const ctraits::TG& KOrder::G() const -{ return _uG;} +const ctraits::TG & +KOrder::G() const +{ + return _uG; +} template<> -ctraits::TG& KOrder::G() +ctraits::TG & +KOrder::G() { return _fG; } template<> -const ctraits::TG& KOrder::G() const -{ return _fG;} +const ctraits::TG & +KOrder::G() const +{ + return _fG; +} template<> -ctraits::TZstack& KOrder::Zstack() +ctraits::TZstack & +KOrder::Zstack() { return _uZstack; } template<> -const ctraits::TZstack& KOrder::Zstack() const -{ return _uZstack;} +const ctraits::TZstack & +KOrder::Zstack() const +{ + return _uZstack; +} template<> -ctraits::TZstack& KOrder::Zstack() +ctraits::TZstack & +KOrder::Zstack() { return _fZstack; } template<> -const ctraits::TZstack& KOrder::Zstack() const -{ return _fZstack;} +const ctraits::TZstack & +KOrder::Zstack() const +{ + return _fZstack; +} template<> -ctraits::TGstack& KOrder::Gstack() +ctraits::TGstack & +KOrder::Gstack() { return _uGstack; } template<> -const ctraits::TGstack& KOrder::Gstack() const -{ return _uGstack;} +const ctraits::TGstack & +KOrder::Gstack() const +{ + return _uGstack; +} template<> -ctraits::TGstack& KOrder::Gstack() +ctraits::TGstack & +KOrder::Gstack() { return _fGstack; } template<> -const ctraits::TGstack& KOrder::Gstack() const -{ return _fGstack;} +const ctraits::TGstack & +KOrder::Gstack() const +{ + return _fGstack; +} template<> -ctraits::Tm& KOrder::m() +ctraits::Tm & +KOrder::m() { return _um; } template<> -const ctraits::Tm& KOrder::m() const -{ return _um;} +const ctraits::Tm & +KOrder::m() const +{ + return _um; +} template<> -ctraits::Tm& KOrder::m() +ctraits::Tm & +KOrder::m() { return _fm; } template<> -const ctraits::Tm& KOrder::m() const -{ return _fm;} +const ctraits::Tm & +KOrder::m() const +{ + return _fm; +} /* Here is the constructor of the KOrder class. We pass what we have to. The partitioning of the y vector, a sparse container with model derivatives, diff --git a/dynare++/kord/korder.hh b/dynare++/kord/korder.hh index beb423ba5..1eb67130c 100644 --- a/dynare++/kord/korder.hh +++ b/dynare++/kord/korder.hh @@ -72,7 +72,7 @@ class UnfoldedZXContainer; class FoldedGXContainer; class UnfoldedGXContainer; -template +template class ctraits { public: @@ -296,15 +296,15 @@ public: /* Performs k-order step provided that k=2 or the k−1-th step has been run, this is the core method */ - template + template void performStep(int order); /* Calculates residuals of all solved equations for k-order and reports their sizes, it is runnable after k-order performStep() has been run */ - template + template double check(int dim) const; - template + template Vector calcStochShift(int order, double sigma) const; void switchToFolded(); const PartitionY & @@ -330,7 +330,7 @@ public: protected: /* Inserts a g derivative to the g container and also creates subtensors and insert them to g_y* and g_y** containers */ - template + template void insertDerivative(std::unique_ptr::Ttensor> der); /* Solves the sylvester equation (templated fold, and unfold) */ @@ -339,27 +339,27 @@ protected: /* Calculates derivatives of F by Faà Di Bruno for the sparse container of system derivatives and Z stack container */ - template + template std::unique_ptr::Ttensor> faaDiBrunoZ(const Symmetry &sym) const; /* Calculates derivatives of G by Faà Di Bruno for the dense container g** and G stack */ - template + template std::unique_ptr::Ttensor> faaDiBrunoG(const Symmetry &sym) const; // Recovers g_y*ⁱ template void recover_y(int i); // Recovers g_y*ⁱuʲ - template + template void recover_yu(int i, int j); // Recovers g_y*ⁱσʲ - template + template void recover_ys(int i, int j); // Recovers g_y*ⁱuʲσᵏ - template + template void recover_yus(int i, int j, int k); - template + template // Recovers g_σⁱ void recover_s(int i); // Calculates specified derivatives of G and inserts them to the container @@ -367,26 +367,26 @@ protected: void fillG(int i, int j, int k); // Calculates Dᵢⱼₖ - template + template typename ctraits::Ttensor calcD_ijk(int i, int j, int k) const; - template + template typename ctraits::Ttensor calcD_ik(int i, int k) const; - template + template typename ctraits::Ttensor calcD_k(int k) const; // Calculates Eᵢⱼₖ - template + template typename ctraits::Ttensor calcE_ijk(int i, int j, int k) const; - template + template typename ctraits::Ttensor calcE_ik(int i, int k) const; - template + template typename ctraits::Ttensor calcE_k(int k) const; }; /* Here we insert the result to the container. Along the insertion, we also create subtensors and insert as well. */ -template +template void KOrder::insertDerivative(std::unique_ptr::Ttensor> der) { @@ -405,7 +405,7 @@ KOrder::insertDerivative(std::unique_ptr::Ttensor> der) where s is a given outer symmetry and k is the dimension of the symmetry. */ -template +template std::unique_ptr::Ttensor> KOrder::faaDiBrunoZ(const Symmetry &sym) const { @@ -419,7 +419,7 @@ KOrder::faaDiBrunoZ(const Symmetry &sym) const /* The same as KOrder::faaDiBrunoZ(), but for g** and G stack. */ -template +template std::unique_ptr::Ttensor> KOrder::faaDiBrunoG(const Symmetry &sym) const { @@ -441,7 +441,7 @@ KOrder::faaDiBrunoG(const Symmetry &sym) const Requires: everything at order ≤ i−1 Provides: g_yⁱ and G_yⁱ - */ +*/ template void KOrder::recover_y(int i) @@ -475,8 +475,8 @@ KOrder::recover_y(int i) Requires: everything at order ≤ i+j−1, G_yⁱ⁺ʲ and g_yⁱ⁺ʲ. Provides: g_yⁱuʲ and G_yⁱuʲ - */ -template +*/ +template void KOrder::recover_yu(int i, int j) { @@ -508,8 +508,8 @@ KOrder::recover_yu(int i, int j) Provides: g_yⁱσʲ and G_yⁱσʲ, and finally G_yⁱu′ᵐσʲ⁻ᵐ for m=1,…,j. The latter is calculated by fillG() before the actual calculation. - */ -template +*/ +template void KOrder::recover_ys(int i, int j) { @@ -561,8 +561,8 @@ KOrder::recover_ys(int i, int j) through Eᵢⱼₖ. Provides: g_yⁱuʲσᵏ, G_yⁱuʲσᵏ, and G_yⁱuʲu′ᵐσᵏ⁻ᵐ for m=1,…,k - */ -template +*/ +template void KOrder::recover_yus(int i, int j, int k) { @@ -619,8 +619,8 @@ KOrder::recover_yus(int i, int j, int k) F_u′ᵏ, and g_yᵐuʲσᵏ for j=1,…,i−1 and m+j+k=i through F_u′ʲσⁱ⁻ʲ. Provides: g_σⁱ, G_σⁱ, and G_u′ᵐσⁱ⁻ᵐ for m=1,…,i - */ -template +*/ +template void KOrder::recover_s(int i) { @@ -680,7 +680,7 @@ KOrder::fillG(int i, int j, int k) So it is non zero only for even k. */ -template +template typename ctraits::Ttensor KOrder::calcD_ijk(int i, int j, int k) const { @@ -700,7 +700,7 @@ KOrder::calcD_ijk(int i, int j, int k) const ᵐ⁼¹ The sum can sum only for even m. */ -template +template typename ctraits::Ttensor KOrder::calcE_ijk(int i, int j, int k) const { @@ -715,28 +715,28 @@ KOrder::calcE_ijk(int i, int j, int k) const return res; } -template +template typename ctraits::Ttensor KOrder::calcD_ik(int i, int k) const { return calcD_ijk(i, 0, k); } -template +template typename ctraits::Ttensor KOrder::calcD_k(int k) const { return calcD_ijk(0, 0, k); } -template +template typename ctraits::Ttensor KOrder::calcE_ik(int i, int k) const { return calcE_ijk(i, 0, k); } -template +template typename ctraits::Ttensor KOrder::calcE_k(int k) const { @@ -763,7 +763,7 @@ KOrder::calcE_k(int k) const all the recovering methods, he should find out that also all G are provided. */ -template +template void KOrder::performStep(int order) { @@ -794,7 +794,7 @@ KOrder::performStep(int order) The method returns the largest residual size. Each check simply evaluates the equation. */ -template +template double KOrder::check(int dim) const { @@ -808,7 +808,7 @@ KOrder::check(int dim) const // Check for F_yⁱuʲ=0 for (int i = 0; i <= dim; i++) { - Symmetry sym{dim-i, i, 0, 0}; + Symmetry sym{dim-i, i, 0, 0}; auto r = faaDiBrunoZ(sym); double err = r->getData().getMax(); JournalRecord(journal) << "\terror for symmetry " << sym << "\tis " << err << endrec; @@ -849,7 +849,7 @@ KOrder::check(int dim) const return maxerror; } -template +template Vector KOrder::calcStochShift(int order, double sigma) const { diff --git a/dynare++/kord/korder_stoch.cc b/dynare++/kord/korder_stoch.cc index 807476d07..397dac59a 100644 --- a/dynare++/kord/korder_stoch.cc +++ b/dynare++/kord/korder_stoch.cc @@ -77,112 +77,134 @@ KOrderStoch::KOrderStoch(const PartitionY &yp, int nu, // KOrderStoch convenience method specializations template<> -ctraits::Tg &KOrderStoch::g() +ctraits::Tg & +KOrderStoch::g() { return _ug; } template<> -const ctraits::Tg &KOrderStoch::g() const +const ctraits::Tg & +KOrderStoch::g() const { return _ug; } template<> -ctraits::Tg &KOrderStoch::g() +ctraits::Tg & +KOrderStoch::g() { return _fg; } template<> -const ctraits::Tg &KOrderStoch::g() const +const ctraits::Tg & +KOrderStoch::g() const { return _fg; } template<> -ctraits::Tgs &KOrderStoch::gs() +ctraits::Tgs & +KOrderStoch::gs() { return _ugs; } template<> -const ctraits::Tgs &KOrderStoch::gs() const +const ctraits::Tgs & +KOrderStoch::gs() const { return _ugs; } template<> -ctraits::Tgs &KOrderStoch::gs() +ctraits::Tgs & +KOrderStoch::gs() { return _fgs; } template<> -const ctraits::Tgs &KOrderStoch::gs() const +const ctraits::Tgs & +KOrderStoch::gs() const { return _fgs; } template<> -const ctraits::Tgss &KOrderStoch::h() const +const ctraits::Tgss & +KOrderStoch::h() const { return *_uh; } template<> -const ctraits::Tgss &KOrderStoch::h() const +const ctraits::Tgss & +KOrderStoch::h() const { return *_fh; } template<> -ctraits::TG &KOrderStoch::G() +ctraits::TG & +KOrderStoch::G() { return _uG; } template<> -const ctraits::TG &KOrderStoch::G() const +const ctraits::TG & +KOrderStoch::G() const { return _uG; } template<> -ctraits::TG &KOrderStoch::G() +ctraits::TG & +KOrderStoch::G() { return _fG; } template<> -const ctraits::TG& KOrderStoch::G() const +const ctraits::TG & +KOrderStoch::G() const { return _fG; } template<> -ctraits::TZXstack &KOrderStoch::Zstack() +ctraits::TZXstack & +KOrderStoch::Zstack() { return _uZstack; } template<> -const ctraits::TZXstack &KOrderStoch::Zstack() const +const ctraits::TZXstack & +KOrderStoch::Zstack() const { return _uZstack; } template<> -ctraits::TZXstack &KOrderStoch::Zstack() +ctraits::TZXstack & +KOrderStoch::Zstack() { return _fZstack; } template<> -const ctraits::TZXstack &KOrderStoch::Zstack() const +const ctraits::TZXstack & +KOrderStoch::Zstack() const { return _fZstack; } template<> -ctraits::TGXstack &KOrderStoch::Gstack() +ctraits::TGXstack & +KOrderStoch::Gstack() { return _uGstack; } template<> -const ctraits::TGXstack &KOrderStoch::Gstack() const +const ctraits::TGXstack & +KOrderStoch::Gstack() const { return _uGstack; } template<> -ctraits::TGXstack &KOrderStoch::Gstack() +ctraits::TGXstack & +KOrderStoch::Gstack() { return _fGstack; } template<> -const ctraits::TGXstack &KOrderStoch::Gstack() const +const ctraits::TGXstack & +KOrderStoch::Gstack() const { return _fGstack; } diff --git a/dynare++/kord/korder_stoch.hh b/dynare++/kord/korder_stoch.hh index 5860809d3..a450f2bda 100644 --- a/dynare++/kord/korder_stoch.hh +++ b/dynare++/kord/korder_stoch.hh @@ -36,7 +36,7 @@ containers corresponding to f(h(g*(y*,u,σ),σ),g(y,u,σ),y,u). Further, we declare IntegDerivs and StochForwardDerivs classes which basically calculate h as an extrapolation based on an approximation to g at lower σ. - */ +*/ #include @@ -48,7 +48,7 @@ /* This class is a container, which has a specialized constructor integrating the policy rule at given σ. */ -template +template class IntegDerivs : public ctraits::Tgss { public: @@ -100,8 +100,8 @@ public: ⁿ⁺ᵏ⁼ᵖ and this is exactly what the code does. - */ -template +*/ +template IntegDerivs::IntegDerivs(int r, const IntSequence &nvs, const typename ctraits::Tgss &g, const typename ctraits::Tm &mom, double at_sigma) : ctraits::Tgss(4) @@ -156,7 +156,7 @@ IntegDerivs::IntegDerivs(int r, const IntSequence &nvs, const typename ctrait The class calculates derivatives of E[g(y*,u,σ)] at (ȳ*,σ¯). The derivatives are extrapolated based on derivatives at (ỹ*,σ~). */ -template +template class StochForwardDerivs : public ctraits::Tgss { public: @@ -180,7 +180,7 @@ public: — Centralize this polynomial about (ȳ,σ¯) — Recover general symmetry tensors from the (full symmetric) polynomial */ -template +template StochForwardDerivs::StochForwardDerivs(const PartitionY &ypart, int nu, const typename ctraits::Tgss &g, const typename ctraits::Tm &m, @@ -260,7 +260,7 @@ StochForwardDerivs::StochForwardDerivs(const PartitionY &ypart, int nu, the σ as a second argument to h will be its fourth variable in symmetry, so we have to do four member stack having the second and third stack dummy. */ -template +template class GXContainer : public GContainer<_Ttype> { public: @@ -279,8 +279,8 @@ public: ⎢ dummy ⎥ ⎢ dummy ⎥ ⎣ σ ⎦ - */ -template +*/ +template typename GXContainer<_Ttype>::itype GXContainer<_Ttype>::getType(int i, const Symmetry &s) const { @@ -306,7 +306,7 @@ GXContainer<_Ttype>::getType(int i, const Symmetry &s) const the size (number of rows) as g**. Since it is very simmilar to ZContainer, we inherit form it and override only getType() method. */ -template +template class ZXContainer : public ZContainer<_Ttype> { public: @@ -326,7 +326,7 @@ public: ⎢ y ⎥ ⎣ u ⎦ */ -template +template typename ZXContainer<_Ttype>::itype ZXContainer<_Ttype>::getType(int i, const Symmetry &s) const { @@ -446,7 +446,7 @@ public: const FGSContainer &hh, Journal &jr); KOrderStoch(const PartitionY &ypart, int nu, const TensorContainer &fcont, const UGSContainer &hh, Journal &jr); - template + template void performStep(int order); const FGSContainer & getFoldDers() const @@ -459,9 +459,9 @@ public: return _ug; } protected: - template + template std::unique_ptr::Ttensor> faaDiBrunoZ(const Symmetry &sym) const; - template + template std::unique_ptr::Ttensor> faaDiBrunoG(const Symmetry &sym) const; // Convenience access methods @@ -497,7 +497,7 @@ protected: /* This calculates a derivative of f(G(y,u,σ),g(y,u,σ),y,u) of a given symmetry. */ -template +template std::unique_ptr::Ttensor> KOrderStoch::faaDiBrunoZ(const Symmetry &sym) const { @@ -512,7 +512,7 @@ KOrderStoch::faaDiBrunoZ(const Symmetry &sym) const /* This calculates a derivative of G(y,u,σ)=h(g*(y,u,σ),σ) of a given symmetry. */ -template +template std::unique_ptr::Ttensor> KOrderStoch::faaDiBrunoG(const Symmetry &sym) const { @@ -535,7 +535,7 @@ KOrderStoch::faaDiBrunoG(const Symmetry &sym) const as gₛ=-matA⁻¹·RHS. Finally we have to update Gₛ by calling Gstack().multAndAdd(1, h(), *G_sym_ptr). */ -template +template void KOrderStoch::performStep(int order) { diff --git a/dynare++/kord/tests.cc b/dynare++/kord/tests.cc index 1cadbe3b9..9827eba95 100644 --- a/dynare++/kord/tests.cc +++ b/dynare++/kord/tests.cc @@ -116,141 +116,147 @@ SparseGenerator::fillContainer(TensorContainer &c, } } -const double vdata [] = { // 3x3 - 0.1307870268, 0.1241940078, 0.1356703123, - 0.1241940078, 0.1986920419, 0.2010160581, - 0.1356703123, 0.2010160581, 0.2160336975 -}; +const double vdata[] = + { // 3x3 + 0.1307870268, 0.1241940078, 0.1356703123, + 0.1241940078, 0.1986920419, 0.2010160581, + 0.1356703123, 0.2010160581, 0.2160336975 + }; -const double gy_data [] = { // 8x4 - 0.3985178619, -0.5688233582, 0.9572900437, -0.6606847776, 0.1453004017, - 0.3025310675, -0.8627437750, -0.6903410191, 0.4751910580, -0.7270018589, - -0.0939612498, -0.1463831989, 0.6742110220, 0.6046671043, 0.5215893126, - -1.0412969986, -0.3524898417, -1.0986703430, 0.8006531522, 0.8879776376, - -0.1037608317, -0.5587378073, -0.1010366945, 0.9462411248, -0.2439199881, - 1.3420621236, -0.7820285935, 0.3205293447, 0.3606124791, 0.2975422208, - -0.5452861965, 1.6320340279 -}; +const double gy_data[] = + { // 8x4 + 0.3985178619, -0.5688233582, 0.9572900437, -0.6606847776, 0.1453004017, + 0.3025310675, -0.8627437750, -0.6903410191, 0.4751910580, -0.7270018589, + -0.0939612498, -0.1463831989, 0.6742110220, 0.6046671043, 0.5215893126, + -1.0412969986, -0.3524898417, -1.0986703430, 0.8006531522, 0.8879776376, + -0.1037608317, -0.5587378073, -0.1010366945, 0.9462411248, -0.2439199881, + 1.3420621236, -0.7820285935, 0.3205293447, 0.3606124791, 0.2975422208, + -0.5452861965, 1.6320340279 + }; -const double gu_data [] = { // just some numbers, no structure - 1.8415286914, -0.2638743845, 1.7690713274, 0.9668585956, 0.2303143646, - -0.2229624279, -0.4381991822, 1.0082401405, -0.3186555860, -0.0624691529, - -0.5189085756, 1.4269672156, 0.1163282969, 1.4020183445, -0.0952660426, - 0.2099097124, 0.6912400502, -0.5180935114, 0.5288316624, 0.2188053448, - 0.5715516767, 0.7813893410, -0.6385073106, 0.8335131513, 0.3605202168, - -1.1167944865, -1.2263750934, 0.6113636081, 0.6964915482, -0.6451217688, - 0.4062810500, -2.0552251116, -1.6383406284, 0.0198915095, 0.0111014458, - -1.2421792262, -1.0724161722, -0.4276904972, 0.1801494950, -2.0716473264 -}; +const double gu_data[] = + { // just some numbers, no structure + 1.8415286914, -0.2638743845, 1.7690713274, 0.9668585956, 0.2303143646, + -0.2229624279, -0.4381991822, 1.0082401405, -0.3186555860, -0.0624691529, + -0.5189085756, 1.4269672156, 0.1163282969, 1.4020183445, -0.0952660426, + 0.2099097124, 0.6912400502, -0.5180935114, 0.5288316624, 0.2188053448, + 0.5715516767, 0.7813893410, -0.6385073106, 0.8335131513, 0.3605202168, + -1.1167944865, -1.2263750934, 0.6113636081, 0.6964915482, -0.6451217688, + 0.4062810500, -2.0552251116, -1.6383406284, 0.0198915095, 0.0111014458, + -1.2421792262, -1.0724161722, -0.4276904972, 0.1801494950, -2.0716473264 + }; -const double vdata2 [] = { // 10×10 positive definite - 0.79666, -0.15536, 0.05667, -0.21026, 0.20262, 0.28505, 0.60341, -0.09703, 0.32363, 0.13299, - -0.15536, 0.64380, -0.01131, 0.00980, 0.03755, 0.43791, 0.21784, -0.31755, -0.55911, -0.29655, - 0.05667, -0.01131, 0.56165, -0.34357, -0.40584, 0.20990, 0.28348, 0.20398, -0.19856, 0.35820, - -0.21026, 0.00980, -0.34357, 0.56147, 0.10972, -0.34146, -0.49906, -0.19685, 0.21088, -0.31560, - 0.20262, 0.03755, -0.40584, 0.10972, 0.72278, 0.02155, 0.04089, -0.19696, 0.03446, -0.12919, - 0.28505, 0.43791, 0.20990, -0.34146, 0.02155, 0.75867, 0.77699, -0.31125, -0.55141, -0.02155, - 0.60341, 0.21784, 0.28348, -0.49906, 0.04089, 0.77699, 1.34553, -0.18613, -0.25811, -0.19016, - -0.09703, -0.31755, 0.20398, -0.19685, -0.19696, -0.31125, -0.18613, 0.59470, 0.08386, 0.41750, - 0.32363, -0.55911, -0.19856, 0.21088, 0.03446, -0.55141, -0.25811, 0.08386, 0.98917, -0.12992, - 0.13299, -0.29655, 0.35820, -0.31560, -0.12919, -0.02155, -0.19016, 0.41750, -0.12992, 0.89608 -}; +const double vdata2[] = + { // 10×10 positive definite + 0.79666, -0.15536, 0.05667, -0.21026, 0.20262, 0.28505, 0.60341, -0.09703, 0.32363, 0.13299, + -0.15536, 0.64380, -0.01131, 0.00980, 0.03755, 0.43791, 0.21784, -0.31755, -0.55911, -0.29655, + 0.05667, -0.01131, 0.56165, -0.34357, -0.40584, 0.20990, 0.28348, 0.20398, -0.19856, 0.35820, + -0.21026, 0.00980, -0.34357, 0.56147, 0.10972, -0.34146, -0.49906, -0.19685, 0.21088, -0.31560, + 0.20262, 0.03755, -0.40584, 0.10972, 0.72278, 0.02155, 0.04089, -0.19696, 0.03446, -0.12919, + 0.28505, 0.43791, 0.20990, -0.34146, 0.02155, 0.75867, 0.77699, -0.31125, -0.55141, -0.02155, + 0.60341, 0.21784, 0.28348, -0.49906, 0.04089, 0.77699, 1.34553, -0.18613, -0.25811, -0.19016, + -0.09703, -0.31755, 0.20398, -0.19685, -0.19696, -0.31125, -0.18613, 0.59470, 0.08386, 0.41750, + 0.32363, -0.55911, -0.19856, 0.21088, 0.03446, -0.55141, -0.25811, 0.08386, 0.98917, -0.12992, + 0.13299, -0.29655, 0.35820, -0.31560, -0.12919, -0.02155, -0.19016, 0.41750, -0.12992, 0.89608 + }; -const double gy_data2 [] = { // 600 items make gy 30×20, whose gy(6:25,:) has spectrum within unit - 0.39414, -0.29766, 0.08948, -0.19204, -0.00750, 0.21159, 0.05494, 0.06225, 0.01771, 0.21913, - -0.01373, 0.20086, -0.06086, -0.10955, 0.14424, -0.08390, 0.03948, -0.14713, 0.11674, 0.05091, - 0.24039, 0.28307, -0.11835, 0.13030, 0.11682, -0.27444, -0.19311, -0.16654, 0.12867, 0.25116, - -0.19781, 0.45242, -0.15862, 0.24428, -0.11966, 0.11483, -0.32279, 0.29727, 0.20934, -0.18190, - -0.15080, -0.09477, -0.30551, -0.02672, -0.26919, 0.11165, -0.06390, 0.03449, -0.26622, 0.22197, - 0.45141, -0.41683, 0.09760, 0.31094, -0.01652, 0.05809, -0.04514, -0.05645, 0.00554, 0.47980, - 0.11726, 0.42459, -0.13136, -0.30902, -0.14648, 0.11455, 0.02947, -0.03835, -0.04044, 0.03559, - -0.26575, -0.01783, 0.31243, -0.14412, -0.13218, -0.05080, 0.18576, 0.13840, -0.05560, 0.35530, - -0.25573, -0.11560, 0.15187, -0.18431, 0.08193, -0.32278, 0.17560, -0.05529, -0.10020, -0.23088, - -0.20979, -0.49245, 0.09915, -0.16909, -0.03443, 0.19497, 0.18473, 0.25662, 0.29605, -0.20531, - -0.39244, -0.43369, 0.05588, 0.24823, -0.14236, -0.08311, 0.16371, -0.19975, 0.30605, -0.17087, - -0.01270, 0.00123, -0.22426, -0.13810, 0.05079, 0.06971, 0.01922, -0.09952, -0.23177, -0.41962, - -0.41991, 0.41430, -0.04247, -0.13706, -0.12048, -0.28906, -0.22813, -0.25057, -0.18579, -0.20642, - -0.47976, 0.25490, -0.05138, -0.30794, 0.31651, 0.02034, 0.12954, -0.20110, 0.13336, -0.40775, - -0.30195, -0.13704, 0.12396, 0.28152, 0.02986, 0.27669, 0.24623, 0.08635, -0.11956, -0.02949, - 0.37401, 0.20838, 0.24801, -0.26872, 0.11195, 0.00315, -0.19069, 0.12839, -0.23036, -0.48228, - 0.08434, -0.39872, -0.28896, -0.28754, 0.24668, 0.23285, 0.25437, 0.10456, -0.14124, 0.20483, - -0.19117, -0.33836, -0.24875, 0.08207, -0.03930, 0.20364, 0.15384, -0.15270, 0.24372, -0.11199, - -0.46591, 0.30319, 0.05745, 0.09084, 0.06058, 0.31884, 0.05071, -0.28899, -0.30793, -0.03566, - 0.02286, 0.28178, 0.00736, -0.31378, -0.18144, -0.22346, -0.27239, 0.31043, -0.26228, 0.22181, - -0.15096, -0.36953, -0.06032, 0.21496, 0.29545, -0.13112, 0.16420, -0.07573, -0.43111, -0.43057, - 0.26716, -0.31209, -0.05866, -0.29101, -0.27437, -0.18727, 0.28732, -0.19014, 0.08837, 0.30405, - 0.06103, -0.35612, 0.00173, 0.25134, -0.08987, -0.22766, -0.03254, -0.18662, -0.08491, 0.49401, - -0.12145, -0.02961, -0.03668, -0.30043, -0.08555, 0.01701, -0.12544, 0.10969, -0.48202, 0.07245, - 0.20673, 0.11408, 0.04343, -0.01815, -0.31594, -0.23632, -0.06258, -0.27474, 0.12180, 0.16613, - -0.37931, 0.30219, 0.15765, 0.25489, 0.17529, -0.17020, -0.30060, 0.22058, -0.02450, -0.42143, - 0.49642, 0.46899, -0.28552, -0.22549, -0.01333, 0.21567, 0.22251, 0.21639, -0.19194, -0.19140, - -0.24106, 0.10952, -0.11019, 0.29763, -0.02039, -0.25748, 0.23169, 0.01357, 0.09802, -0.19022, - 0.37604, -0.40777, 0.18131, -0.10258, 0.29573, -0.31773, 0.09069, -0.02198, -0.26594, 0.48302, - -0.10041, 0.20210, -0.05609, -0.01169, -0.17339, 0.17862, -0.22502, 0.29009, -0.45160, 0.19771, - 0.27634, 0.31695, -0.09993, 0.17167, 0.12394, 0.28088, -0.12502, -0.16967, -0.06296, -0.17036, - 0.27320, 0.01595, 0.16955, 0.30146, -0.15173, -0.29807, 0.08178, -0.06811, 0.21655, 0.26348, - 0.06316, 0.45661, -0.29756, -0.05742, -0.14715, -0.03037, -0.16656, -0.08768, 0.38078, 0.40679, - -0.32779, -0.09106, 0.16107, -0.07301, 0.07700, -0.22694, -0.15692, -0.02548, 0.38749, -0.12203, - -0.02980, -0.22067, 0.00680, -0.23058, -0.29112, 0.23032, -0.16026, 0.23392, -0.09990, 0.03628, - -0.42592, -0.33474, -0.09499, -0.17442, -0.20110, 0.24618, -0.06418, -0.06715, 0.40754, 0.29377, - 0.29543, -0.16832, -0.08468, 0.06491, -0.01410, 0.19988, 0.24950, 0.14626, -0.27851, 0.06079, - 0.48134, -0.13475, 0.25398, 0.11738, 0.23369, -0.00661, -0.16811, -0.04557, -0.12030, -0.39527, - -0.35760, 0.01840, -0.15941, 0.03290, 0.09988, -0.08307, 0.06644, -0.24637, 0.34112, -0.08026, - 0.00951, 0.27656, 0.16247, 0.28217, 0.17198, -0.16389, -0.03835, -0.02675, -0.08032, -0.21045, - -0.38946, 0.23207, 0.10987, -0.31674, -0.28653, -0.27430, -0.29109, -0.00648, 0.38431, -0.38478, - -0.41195, -0.19364, -0.20977, -0.05524, 0.05558, -0.20109, 0.11803, -0.19884, 0.43318, -0.39255, - 0.26612, -0.21771, 0.12471, 0.12856, -0.15104, -0.11676, 0.17582, -0.25330, 0.00298, -0.31712, - 0.21532, -0.20319, 0.14507, -0.04588, -0.22995, -0.06470, 0.18849, -0.13444, 0.37107, 0.07387, - -0.14008, 0.09896, 0.13727, -0.28417, -0.09461, -0.18703, 0.04080, 0.02343, -0.49988, 0.17993, - 0.23189, -0.30581, -0.18334, -0.09667, -0.27699, -0.05998, 0.09118, -0.32453, 0.46251, 0.41500, - -0.45314, -0.00544, 0.08529, 0.29099, -0.00937, -0.31650, 0.26163, 0.14506, 0.37498, -0.16454, - 0.35215, 0.31642, -0.09161, -0.31452, -0.04792, -0.04677, -0.19523, 0.27998, 0.05491, 0.44461, - -0.01258, -0.27887, 0.18361, -0.04539, -0.02977, 0.30821, 0.29454, -0.17932, 0.16193, 0.23934, - 0.47923, 0.25373, 0.23258, 0.31484, -0.17958, -0.01136, 0.17681, 0.12869, 0.03235, 0.43762, - 0.13734, -0.09433, -0.03735, 0.17949, 0.14122, -0.17814, 0.06359, 0.16044, 0.12249, -0.22314, - 0.40775, 0.05147, 0.12389, 0.04290, -0.01642, 0.00082, -0.18056, 0.02875, 0.32690, 0.17712, - 0.34001, -0.21581, -0.01086, -0.18180, 0.17480, -0.17774, -0.07503, 0.28438, -0.19747, 0.29595, - -0.28002, -0.02073, -0.16522, -0.18234, -0.20565, 0.29620, 0.07502, 0.01429, -0.31418, 0.43693, - -0.12212, 0.11178, -0.28503, 0.04683, 0.00072, 0.05566, 0.18857, 0.26101, -0.38891, -0.21216, - -0.21850, -0.15147, -0.30749, -0.23762, 0.14984, 0.03535, -0.02862, -0.00105, -0.39907, -0.06909, - -0.36094, 0.21717, 0.15930, -0.18924, 0.13741, 0.01039, 0.13613, 0.00659, 0.07676, -0.13711, - 0.24285, -0.07564, -0.28349, -0.15658, 0.03135, -0.30909, -0.22534, 0.17363, -0.19376, 0.26038, - 0.05546, -0.22607, 0.32420, -0.02552, -0.05400, 0.13388, 0.04643, -0.31535, -0.06181, 0.30237, - -0.04680, -0.29441, 0.12231, 0.03960, -0.01188, 0.01406, 0.25402, 0.03315, 0.25026, -0.10922 -}; +const double gy_data2[] = + { // 600 items make gy 30×20, whose gy(6:25,:) has spectrum within unit + 0.39414, -0.29766, 0.08948, -0.19204, -0.00750, 0.21159, 0.05494, 0.06225, 0.01771, 0.21913, + -0.01373, 0.20086, -0.06086, -0.10955, 0.14424, -0.08390, 0.03948, -0.14713, 0.11674, 0.05091, + 0.24039, 0.28307, -0.11835, 0.13030, 0.11682, -0.27444, -0.19311, -0.16654, 0.12867, 0.25116, + -0.19781, 0.45242, -0.15862, 0.24428, -0.11966, 0.11483, -0.32279, 0.29727, 0.20934, -0.18190, + -0.15080, -0.09477, -0.30551, -0.02672, -0.26919, 0.11165, -0.06390, 0.03449, -0.26622, 0.22197, + 0.45141, -0.41683, 0.09760, 0.31094, -0.01652, 0.05809, -0.04514, -0.05645, 0.00554, 0.47980, + 0.11726, 0.42459, -0.13136, -0.30902, -0.14648, 0.11455, 0.02947, -0.03835, -0.04044, 0.03559, + -0.26575, -0.01783, 0.31243, -0.14412, -0.13218, -0.05080, 0.18576, 0.13840, -0.05560, 0.35530, + -0.25573, -0.11560, 0.15187, -0.18431, 0.08193, -0.32278, 0.17560, -0.05529, -0.10020, -0.23088, + -0.20979, -0.49245, 0.09915, -0.16909, -0.03443, 0.19497, 0.18473, 0.25662, 0.29605, -0.20531, + -0.39244, -0.43369, 0.05588, 0.24823, -0.14236, -0.08311, 0.16371, -0.19975, 0.30605, -0.17087, + -0.01270, 0.00123, -0.22426, -0.13810, 0.05079, 0.06971, 0.01922, -0.09952, -0.23177, -0.41962, + -0.41991, 0.41430, -0.04247, -0.13706, -0.12048, -0.28906, -0.22813, -0.25057, -0.18579, -0.20642, + -0.47976, 0.25490, -0.05138, -0.30794, 0.31651, 0.02034, 0.12954, -0.20110, 0.13336, -0.40775, + -0.30195, -0.13704, 0.12396, 0.28152, 0.02986, 0.27669, 0.24623, 0.08635, -0.11956, -0.02949, + 0.37401, 0.20838, 0.24801, -0.26872, 0.11195, 0.00315, -0.19069, 0.12839, -0.23036, -0.48228, + 0.08434, -0.39872, -0.28896, -0.28754, 0.24668, 0.23285, 0.25437, 0.10456, -0.14124, 0.20483, + -0.19117, -0.33836, -0.24875, 0.08207, -0.03930, 0.20364, 0.15384, -0.15270, 0.24372, -0.11199, + -0.46591, 0.30319, 0.05745, 0.09084, 0.06058, 0.31884, 0.05071, -0.28899, -0.30793, -0.03566, + 0.02286, 0.28178, 0.00736, -0.31378, -0.18144, -0.22346, -0.27239, 0.31043, -0.26228, 0.22181, + -0.15096, -0.36953, -0.06032, 0.21496, 0.29545, -0.13112, 0.16420, -0.07573, -0.43111, -0.43057, + 0.26716, -0.31209, -0.05866, -0.29101, -0.27437, -0.18727, 0.28732, -0.19014, 0.08837, 0.30405, + 0.06103, -0.35612, 0.00173, 0.25134, -0.08987, -0.22766, -0.03254, -0.18662, -0.08491, 0.49401, + -0.12145, -0.02961, -0.03668, -0.30043, -0.08555, 0.01701, -0.12544, 0.10969, -0.48202, 0.07245, + 0.20673, 0.11408, 0.04343, -0.01815, -0.31594, -0.23632, -0.06258, -0.27474, 0.12180, 0.16613, + -0.37931, 0.30219, 0.15765, 0.25489, 0.17529, -0.17020, -0.30060, 0.22058, -0.02450, -0.42143, + 0.49642, 0.46899, -0.28552, -0.22549, -0.01333, 0.21567, 0.22251, 0.21639, -0.19194, -0.19140, + -0.24106, 0.10952, -0.11019, 0.29763, -0.02039, -0.25748, 0.23169, 0.01357, 0.09802, -0.19022, + 0.37604, -0.40777, 0.18131, -0.10258, 0.29573, -0.31773, 0.09069, -0.02198, -0.26594, 0.48302, + -0.10041, 0.20210, -0.05609, -0.01169, -0.17339, 0.17862, -0.22502, 0.29009, -0.45160, 0.19771, + 0.27634, 0.31695, -0.09993, 0.17167, 0.12394, 0.28088, -0.12502, -0.16967, -0.06296, -0.17036, + 0.27320, 0.01595, 0.16955, 0.30146, -0.15173, -0.29807, 0.08178, -0.06811, 0.21655, 0.26348, + 0.06316, 0.45661, -0.29756, -0.05742, -0.14715, -0.03037, -0.16656, -0.08768, 0.38078, 0.40679, + -0.32779, -0.09106, 0.16107, -0.07301, 0.07700, -0.22694, -0.15692, -0.02548, 0.38749, -0.12203, + -0.02980, -0.22067, 0.00680, -0.23058, -0.29112, 0.23032, -0.16026, 0.23392, -0.09990, 0.03628, + -0.42592, -0.33474, -0.09499, -0.17442, -0.20110, 0.24618, -0.06418, -0.06715, 0.40754, 0.29377, + 0.29543, -0.16832, -0.08468, 0.06491, -0.01410, 0.19988, 0.24950, 0.14626, -0.27851, 0.06079, + 0.48134, -0.13475, 0.25398, 0.11738, 0.23369, -0.00661, -0.16811, -0.04557, -0.12030, -0.39527, + -0.35760, 0.01840, -0.15941, 0.03290, 0.09988, -0.08307, 0.06644, -0.24637, 0.34112, -0.08026, + 0.00951, 0.27656, 0.16247, 0.28217, 0.17198, -0.16389, -0.03835, -0.02675, -0.08032, -0.21045, + -0.38946, 0.23207, 0.10987, -0.31674, -0.28653, -0.27430, -0.29109, -0.00648, 0.38431, -0.38478, + -0.41195, -0.19364, -0.20977, -0.05524, 0.05558, -0.20109, 0.11803, -0.19884, 0.43318, -0.39255, + 0.26612, -0.21771, 0.12471, 0.12856, -0.15104, -0.11676, 0.17582, -0.25330, 0.00298, -0.31712, + 0.21532, -0.20319, 0.14507, -0.04588, -0.22995, -0.06470, 0.18849, -0.13444, 0.37107, 0.07387, + -0.14008, 0.09896, 0.13727, -0.28417, -0.09461, -0.18703, 0.04080, 0.02343, -0.49988, 0.17993, + 0.23189, -0.30581, -0.18334, -0.09667, -0.27699, -0.05998, 0.09118, -0.32453, 0.46251, 0.41500, + -0.45314, -0.00544, 0.08529, 0.29099, -0.00937, -0.31650, 0.26163, 0.14506, 0.37498, -0.16454, + 0.35215, 0.31642, -0.09161, -0.31452, -0.04792, -0.04677, -0.19523, 0.27998, 0.05491, 0.44461, + -0.01258, -0.27887, 0.18361, -0.04539, -0.02977, 0.30821, 0.29454, -0.17932, 0.16193, 0.23934, + 0.47923, 0.25373, 0.23258, 0.31484, -0.17958, -0.01136, 0.17681, 0.12869, 0.03235, 0.43762, + 0.13734, -0.09433, -0.03735, 0.17949, 0.14122, -0.17814, 0.06359, 0.16044, 0.12249, -0.22314, + 0.40775, 0.05147, 0.12389, 0.04290, -0.01642, 0.00082, -0.18056, 0.02875, 0.32690, 0.17712, + 0.34001, -0.21581, -0.01086, -0.18180, 0.17480, -0.17774, -0.07503, 0.28438, -0.19747, 0.29595, + -0.28002, -0.02073, -0.16522, -0.18234, -0.20565, 0.29620, 0.07502, 0.01429, -0.31418, 0.43693, + -0.12212, 0.11178, -0.28503, 0.04683, 0.00072, 0.05566, 0.18857, 0.26101, -0.38891, -0.21216, + -0.21850, -0.15147, -0.30749, -0.23762, 0.14984, 0.03535, -0.02862, -0.00105, -0.39907, -0.06909, + -0.36094, 0.21717, 0.15930, -0.18924, 0.13741, 0.01039, 0.13613, 0.00659, 0.07676, -0.13711, + 0.24285, -0.07564, -0.28349, -0.15658, 0.03135, -0.30909, -0.22534, 0.17363, -0.19376, 0.26038, + 0.05546, -0.22607, 0.32420, -0.02552, -0.05400, 0.13388, 0.04643, -0.31535, -0.06181, 0.30237, + -0.04680, -0.29441, 0.12231, 0.03960, -0.01188, 0.01406, 0.25402, 0.03315, 0.25026, -0.10922 + }; -const double gu_data2 [] = { // raw data 300 items - 0.26599, 0.41329, 0.31846, 0.92590, 0.43050, 0.17466, 0.02322, 0.72621, 0.37921, 0.70597, - 0.97098, 0.14023, 0.57619, 0.09938, 0.02281, 0.92341, 0.72654, 0.71000, 0.76687, 0.70182, - 0.88752, 0.49524, 0.42549, 0.42806, 0.57615, 0.76051, 0.15341, 0.47457, 0.60066, 0.40880, - 0.20668, 0.41949, 0.97620, 0.94318, 0.71491, 0.56402, 0.23553, 0.94387, 0.78567, 0.06362, - 0.85252, 0.86262, 0.25190, 0.03274, 0.93216, 0.37971, 0.08797, 0.14596, 0.73871, 0.06574, - 0.67447, 0.28575, 0.43911, 0.92133, 0.12327, 0.87762, 0.71060, 0.07141, 0.55443, 0.53310, - 0.91529, 0.25121, 0.07593, 0.94490, 0.28656, 0.82174, 0.68887, 0.67337, 0.99291, 0.03316, - 0.02849, 0.33891, 0.25594, 0.90071, 0.01248, 0.67871, 0.65953, 0.65369, 0.97574, 0.31578, - 0.23678, 0.39220, 0.06706, 0.80943, 0.57694, 0.08220, 0.18151, 0.19969, 0.37096, 0.37858, - 0.70153, 0.46816, 0.76511, 0.02520, 0.39387, 0.25527, 0.39050, 0.60141, 0.30322, 0.46195, - 0.12025, 0.33616, 0.04174, 0.00196, 0.68886, 0.74445, 0.15869, 0.18994, 0.95195, 0.62874, - 0.82874, 0.53369, 0.34383, 0.50752, 0.97023, 0.22695, 0.62407, 0.25840, 0.71279, 0.28785, - 0.31611, 0.20391, 0.19702, 0.40760, 0.85158, 0.68369, 0.63760, 0.09879, 0.11924, 0.32920, - 0.53052, 0.15900, 0.21229, 0.84080, 0.33933, 0.93651, 0.42705, 0.06199, 0.50092, 0.47192, - 0.57152, 0.01818, 0.31404, 0.50173, 0.87725, 0.50530, 0.10717, 0.04035, 0.32901, 0.33538, - 0.04780, 0.40984, 0.78216, 0.91288, 0.11314, 0.25248, 0.23823, 0.74001, 0.48089, 0.55531, - 0.82486, 0.01058, 0.05409, 0.44357, 0.52641, 0.68188, 0.94629, 0.61627, 0.33037, 0.11961, - 0.57988, 0.19653, 0.91902, 0.59838, 0.52974, 0.28364, 0.45767, 0.65836, 0.63045, 0.76140, - 0.27918, 0.27256, 0.46035, 0.77418, 0.92918, 0.14095, 0.89645, 0.25146, 0.21172, 0.47910, - 0.95451, 0.34377, 0.29927, 0.79220, 0.97654, 0.67591, 0.44385, 0.38434, 0.44860, 0.28170, - 0.90712, 0.20337, 0.00292, 0.55046, 0.62255, 0.45127, 0.80896, 0.43965, 0.59145, 0.23801, - 0.33601, 0.30119, 0.89935, 0.40850, 0.98226, 0.75430, 0.68318, 0.65407, 0.68067, 0.32942, - 0.11756, 0.27626, 0.83879, 0.72174, 0.75430, 0.13702, 0.03402, 0.58781, 0.07393, 0.23067, - 0.92537, 0.29445, 0.43437, 0.47685, 0.54548, 0.66082, 0.23805, 0.60208, 0.94337, 0.21363, - 0.72637, 0.57181, 0.77679, 0.63931, 0.72860, 0.38901, 0.94920, 0.04535, 0.12863, 0.40550, - 0.90095, 0.21418, 0.13953, 0.99639, 0.02526, 0.70018, 0.21828, 0.20294, 0.20191, 0.30954, - 0.39490, 0.68955, 0.11506, 0.15748, 0.40252, 0.91680, 0.61547, 0.78443, 0.19693, 0.67630, - 0.56552, 0.58556, 0.53554, 0.53507, 0.09831, 0.21229, 0.83135, 0.26375, 0.89287, 0.97069, - 0.70615, 0.42041, 0.43117, 0.21291, 0.26086, 0.26978, 0.77340, 0.43833, 0.46179, 0.54418, - 0.67878, 0.42776, 0.61454, 0.55915, 0.36363, 0.31999, 0.42442, 0.86649, 0.62513, 0.02047 -}; +const double gu_data2[] = + { // raw data 300 items + 0.26599, 0.41329, 0.31846, 0.92590, 0.43050, 0.17466, 0.02322, 0.72621, 0.37921, 0.70597, + 0.97098, 0.14023, 0.57619, 0.09938, 0.02281, 0.92341, 0.72654, 0.71000, 0.76687, 0.70182, + 0.88752, 0.49524, 0.42549, 0.42806, 0.57615, 0.76051, 0.15341, 0.47457, 0.60066, 0.40880, + 0.20668, 0.41949, 0.97620, 0.94318, 0.71491, 0.56402, 0.23553, 0.94387, 0.78567, 0.06362, + 0.85252, 0.86262, 0.25190, 0.03274, 0.93216, 0.37971, 0.08797, 0.14596, 0.73871, 0.06574, + 0.67447, 0.28575, 0.43911, 0.92133, 0.12327, 0.87762, 0.71060, 0.07141, 0.55443, 0.53310, + 0.91529, 0.25121, 0.07593, 0.94490, 0.28656, 0.82174, 0.68887, 0.67337, 0.99291, 0.03316, + 0.02849, 0.33891, 0.25594, 0.90071, 0.01248, 0.67871, 0.65953, 0.65369, 0.97574, 0.31578, + 0.23678, 0.39220, 0.06706, 0.80943, 0.57694, 0.08220, 0.18151, 0.19969, 0.37096, 0.37858, + 0.70153, 0.46816, 0.76511, 0.02520, 0.39387, 0.25527, 0.39050, 0.60141, 0.30322, 0.46195, + 0.12025, 0.33616, 0.04174, 0.00196, 0.68886, 0.74445, 0.15869, 0.18994, 0.95195, 0.62874, + 0.82874, 0.53369, 0.34383, 0.50752, 0.97023, 0.22695, 0.62407, 0.25840, 0.71279, 0.28785, + 0.31611, 0.20391, 0.19702, 0.40760, 0.85158, 0.68369, 0.63760, 0.09879, 0.11924, 0.32920, + 0.53052, 0.15900, 0.21229, 0.84080, 0.33933, 0.93651, 0.42705, 0.06199, 0.50092, 0.47192, + 0.57152, 0.01818, 0.31404, 0.50173, 0.87725, 0.50530, 0.10717, 0.04035, 0.32901, 0.33538, + 0.04780, 0.40984, 0.78216, 0.91288, 0.11314, 0.25248, 0.23823, 0.74001, 0.48089, 0.55531, + 0.82486, 0.01058, 0.05409, 0.44357, 0.52641, 0.68188, 0.94629, 0.61627, 0.33037, 0.11961, + 0.57988, 0.19653, 0.91902, 0.59838, 0.52974, 0.28364, 0.45767, 0.65836, 0.63045, 0.76140, + 0.27918, 0.27256, 0.46035, 0.77418, 0.92918, 0.14095, 0.89645, 0.25146, 0.21172, 0.47910, + 0.95451, 0.34377, 0.29927, 0.79220, 0.97654, 0.67591, 0.44385, 0.38434, 0.44860, 0.28170, + 0.90712, 0.20337, 0.00292, 0.55046, 0.62255, 0.45127, 0.80896, 0.43965, 0.59145, 0.23801, + 0.33601, 0.30119, 0.89935, 0.40850, 0.98226, 0.75430, 0.68318, 0.65407, 0.68067, 0.32942, + 0.11756, 0.27626, 0.83879, 0.72174, 0.75430, 0.13702, 0.03402, 0.58781, 0.07393, 0.23067, + 0.92537, 0.29445, 0.43437, 0.47685, 0.54548, 0.66082, 0.23805, 0.60208, 0.94337, 0.21363, + 0.72637, 0.57181, 0.77679, 0.63931, 0.72860, 0.38901, 0.94920, 0.04535, 0.12863, 0.40550, + 0.90095, 0.21418, 0.13953, 0.99639, 0.02526, 0.70018, 0.21828, 0.20294, 0.20191, 0.30954, + 0.39490, 0.68955, 0.11506, 0.15748, 0.40252, 0.91680, 0.61547, 0.78443, 0.19693, 0.67630, + 0.56552, 0.58556, 0.53554, 0.53507, 0.09831, 0.21229, 0.83135, 0.26375, 0.89287, 0.97069, + 0.70615, 0.42041, 0.43117, 0.21291, 0.26086, 0.26978, 0.77340, 0.43833, 0.46179, 0.54418, + 0.67878, 0.42776, 0.61454, 0.55915, 0.36363, 0.31999, 0.42442, 0.86649, 0.62513, 0.02047 + }; class TestRunnable { diff --git a/dynare++/parser/cc/atom_assignings.cc b/dynare++/parser/cc/atom_assignings.cc index 2a5cb493a..e49839b49 100644 --- a/dynare++/parser/cc/atom_assignings.cc +++ b/dynare++/parser/cc/atom_assignings.cc @@ -158,7 +158,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm) { // go through all old variables and see what are their derived new // variables - for (const auto & it : mm) + for (const auto &it : mm) { const string &oldname = it.first; const AtomSubstitutions::Tshiftnameset &sset = it.second; @@ -175,7 +175,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm) order.push_back(-1); // now go through all new names derived from the old name and // reference to the newly added formula - for (const auto & itt : sset) + for (const auto &itt : sset) { const string &newname = itt.first; left_names.insert(newname); diff --git a/dynare++/parser/cc/atom_substitutions.cc b/dynare++/parser/cc/atom_substitutions.cc index f0a8f8481..840c240f6 100644 --- a/dynare++/parser/cc/atom_substitutions.cc +++ b/dynare++/parser/cc/atom_substitutions.cc @@ -62,7 +62,7 @@ AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot) // add all new names derived from the old name auto it = old2new.find(oname); if (it != old2new.end()) - for (const auto & itt : it->second) + for (const auto &itt : it->second) na_ext.push_back(itt.first); } @@ -77,7 +77,7 @@ AtomSubstitutions::get_new4old(const string &oldname, int tshift) const if (it != old2new.end()) { const Tshiftnameset &sset = it->second; - for (const auto & itt : sset) + for (const auto &itt : sset) if (itt.second == -tshift) return itt.first; } @@ -88,12 +88,12 @@ void AtomSubstitutions::print() const { std::cout << u8"Atom Substitutions:\nOld ⇒ New:\n"; - for (const auto & it : old2new) + for (const auto &it : old2new) for (const auto &itt : it.second) std::cout << " " << it.first << u8" ⇒ [" << itt.first << ", " << itt.second << "]\n"; std::cout << u8"Old ⇐ New:\n"; - for (const auto & it : new2old) + for (const auto &it : new2old) std::cout << " [" << it.second.first << ", " << it.second.second << "] ⇐ " << it.first << '\n'; } diff --git a/dynare++/parser/cc/dynamic_atoms.cc b/dynare++/parser/cc/dynamic_atoms.cc index 4ec1707ea..d1773fe1c 100644 --- a/dynare++/parser/cc/dynamic_atoms.cc +++ b/dynare++/parser/cc/dynamic_atoms.cc @@ -55,7 +55,7 @@ Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap void Constants::setValues(EvalTree &et) const { - for (const auto & it : cmap) + for (const auto &it : cmap) et.set_nulary(it.first, it.second); } @@ -250,7 +250,7 @@ vector DynamicAtoms::variables() const { vector res; - for (const auto & var : vars) + for (const auto &var : vars) { const Tlagmap &lmap = var.second; for (auto itt : lmap) @@ -372,7 +372,7 @@ DynamicAtoms::print() const std::cout << "constants:\n"; Constants::print(); std::cout << "variables:\n"; - for (const auto & var : vars) + for (const auto &var : vars) { const Tlagmap &lmap = var.second; for (auto itt : lmap) @@ -501,7 +501,7 @@ VarOrdering::do_general(ord_type ordering) // make der_atoms and positions int off = 0; - for (auto & ord : ords) + for (auto &ord : ords) for (unsigned int j = 0; j < ord->size(); j++, off++) if ((*ord)[j] != -1) { diff --git a/dynare++/parser/cc/dynamic_atoms.hh b/dynare++/parser/cc/dynamic_atoms.hh index f963a099a..2efab3781 100644 --- a/dynare++/parser/cc/dynamic_atoms.hh +++ b/dynare++/parser/cc/dynamic_atoms.hh @@ -347,7 +347,7 @@ namespace ogp public: /** This is an enum type for an ordering type implemented by * do_general. */ - enum ord_type {pbspbfbf, bfspbfpb}; + enum ord_type { pbspbfbf, bfspbfpb }; /** Construct the ordering of the variables given by the names * with their dynamic occurrences defined by the atoms. It * calls the virtual method do_ordering which can be diff --git a/dynare++/parser/cc/fine_atoms.hh b/dynare++/parser/cc/fine_atoms.hh index 010f5baf0..61e4fd1d7 100644 --- a/dynare++/parser/cc/fine_atoms.hh +++ b/dynare++/parser/cc/fine_atoms.hh @@ -339,20 +339,20 @@ namespace ogp int get_pos_of_all(int t) const; /** Return the mapping from endogenous at time t to outer * ordering of endogenous. */ - const vector&y2outer_endo() const; + const vector &y2outer_endo() const; /** Return the mapping from the outer ordering of endogenous to endogenous * at time t. */ - const vector&outer2y_endo() const; + const vector &outer2y_endo() const; /** Return the mapping from exogenous at time t to outer * ordering of exogenous. */ - const vector&y2outer_exo() const; + const vector &y2outer_exo() const; /** Return the mapping from the outer ordering of exogenous to exogenous * at time t. */ - const vector&outer2y_exo() const; + const vector &outer2y_exo() const; /** Return the endo_atoms_map. */ - const vector&get_endo_atoms_map() const; + const vector &get_endo_atoms_map() const; /** Return the exo_atoms_map. */ - const vector&get_exo_atoms_map() const; + const vector &get_exo_atoms_map() const; /** Return an index in the outer ordering of a given * parameter. An exception is thrown if the name is not a * parameter. */ diff --git a/dynare++/parser/cc/formula_parser.cc b/dynare++/parser/cc/formula_parser.cc index 76eb29040..1c37b3618 100644 --- a/dynare++/parser/cc/formula_parser.cc +++ b/dynare++/parser/cc/formula_parser.cc @@ -271,7 +271,7 @@ FormulaDerivatives::derivative(const FoldMultiIndex &mi) const void FormulaDerivatives::print(const OperationTree &otree) const { - for (const auto & it : ind2der) + for (const auto &it : ind2der) { std::cout << "derivative "; it.first.print(); diff --git a/dynare++/parser/cc/formula_parser.hh b/dynare++/parser/cc/formula_parser.hh index 44fbcbdfc..fde8eff81 100644 --- a/dynare++/parser/cc/formula_parser.hh +++ b/dynare++/parser/cc/formula_parser.hh @@ -256,7 +256,7 @@ namespace ogp * different order). */ void differentiate(int max_order); /** Return i-th formula derivatives. */ - const FormulaDerivatives&derivatives(int i) const; + const FormulaDerivatives &derivatives(int i) const; /** This returns a maximum index of zero derivative formulas * including all nulary terms. This is a mimumum length of the diff --git a/dynare++/parser/cc/location.hh b/dynare++/parser/cc/location.hh index 8614c8188..43a2839ce 100644 --- a/dynare++/parser/cc/location.hh +++ b/dynare++/parser/cc/location.hh @@ -29,12 +29,12 @@ namespace ogp }; // set current off to the first off and add all lengths -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - { \ - (Current).off = (Rhs)[1].off; \ - (Current).ll = 0; \ - for (int i = 1; i <= N; i++) \ - (Current).ll += (Rhs)[i].ll; \ +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + { \ + (Current).off = (Rhs)[1].off; \ + (Current).ll = 0; \ + for (int i = 1; i <= N; i++) \ + (Current).ll += (Rhs)[i].ll; \ } #define SET_LLOC(prefix) (prefix ## lloc.off += prefix ## lloc.ll, prefix ## lloc.ll = prefix ## leng) diff --git a/dynare++/parser/cc/matrix_parser.cc b/dynare++/parser/cc/matrix_parser.cc index f0f29a8d6..46e64ff6e 100644 --- a/dynare++/parser/cc/matrix_parser.cc +++ b/dynare++/parser/cc/matrix_parser.cc @@ -100,12 +100,12 @@ MatrixParser::end() const } MPIterator::MPIterator(const MatrixParser &mp) - : p(&mp), i(0), r(mp.find_first_non_empty_row()) + : p(&mp), i(0), r(mp.find_first_non_empty_row()) { } MPIterator::MPIterator(const MatrixParser &mp, const char *dummy) - : p(&mp), i(mp.data.size()), r(mp.row_lengths.size()) + : p(&mp), i(mp.data.size()), r(mp.row_lengths.size()) { } diff --git a/dynare++/parser/cc/static_fine_atoms.cc b/dynare++/parser/cc/static_fine_atoms.cc index b4b7487b2..ea34f1373 100644 --- a/dynare++/parser/cc/static_fine_atoms.cc +++ b/dynare++/parser/cc/static_fine_atoms.cc @@ -96,7 +96,7 @@ StaticFineAtoms::parsing_finished() // go through all endo and exo insert tree indices, ignore names // whose tree index is -1 (those which are not referenced) - for (auto & endovar : endovars) + for (auto &endovar : endovars) { int t = index(endovar); if (t != -1) @@ -105,7 +105,7 @@ StaticFineAtoms::parsing_finished() der_atoms.push_back(t); } } - for (auto & exovar : exovars) + for (auto &exovar : exovars) { int t = index(exovar); if (t != -1) diff --git a/dynare++/parser/cc/tree.cc b/dynare++/parser/cc/tree.cc index 3ba9b8351..bc8d7b780 100644 --- a/dynare++/parser/cc/tree.cc +++ b/dynare++/parser/cc/tree.cc @@ -287,7 +287,7 @@ OperationTree::add_derivative(int t, int v) int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp2 = add_derivative(terms[t].getOp2(), v); int res1 = add_binary(code_t::TIMES, terms[t].getOp1(), tmp2); - int res2 = add_binary(code_t::TIMES, tmp1, terms[t].getOp2()); + int res2 = add_binary(code_t::TIMES, tmp1, terms[t].getOp2()); res = add_binary(code_t::PLUS, res1, res2); break; } @@ -477,7 +477,7 @@ OperationTree::select_terms_inv(int t, const opselector &sel, unordered_set void OperationTree::forget_derivative_maps() { - for (auto & derivative : derivatives) + for (auto &derivative : derivatives) derivative.clear(); } diff --git a/dynare++/parser/cc/tree.hh b/dynare++/parser/cc/tree.hh index 5e14c8bf2..b5041cca5 100644 --- a/dynare++/parser/cc/tree.hh +++ b/dynare++/parser/cc/tree.hh @@ -42,8 +42,8 @@ namespace ogp * codes, he should update the code of #OperationTree::add_unary, * #OperationTree::add_binary, and of course * #OperationTree::add_derivative. */ - enum class code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF, - ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER}; + enum class code_t { NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF, + ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER }; /** Class representing a nulary, unary, or binary operation. */ class Operation @@ -64,7 +64,7 @@ namespace ogp } /** Constructs a unary operation. */ Operation(code_t cd, int oper1) - : code(cd), op1(oper1) + : code(cd), op1(oper1) { } /** Constructs a nulary operation. */ @@ -218,7 +218,7 @@ namespace ogp * 2/pi. These will be always first four terms having indices * zero, one and two, three. If adding anything to this * enumeration, make sure ‘num_constants’ remains the last one.*/ - enum {zero, one, nan, two_over_pi, num_constants}; + enum { zero, one, nan, two_over_pi, num_constants }; /** The unique constructor which initializes the object to * contain only zero, one and nan and two_over_pi.*/ diff --git a/dynare++/src/dynare3.hh b/dynare++/src/dynare3.hh index 4990a91f3..f31946f11 100644 --- a/dynare++/src/dynare3.hh +++ b/dynare++/src/dynare3.hh @@ -129,7 +129,7 @@ public: { return std::make_unique(*this); } - + ~Dynare() override = default; int nstat() const override diff --git a/dynare++/src/dynare_atoms.cc b/dynare++/src/dynare_atoms.cc index 0ca99840f..3360fc4e3 100644 --- a/dynare++/src/dynare_atoms.cc +++ b/dynare++/src/dynare_atoms.cc @@ -186,7 +186,7 @@ DynareAtomValues::setValues(ogp::EvalTree &et) const for (auto it : lmap) { int ll = it.first; - if (ll == 0) // this is always true because of checks + if (ll == 0) // this is always true because of checks { int t = it.second; int i = atoms.outer2y_exo()[outer_i]; diff --git a/dynare++/src/dynare_atoms.hh b/dynare++/src/dynare_atoms.hh index c9639be18..54a34c426 100644 --- a/dynare++/src/dynare_atoms.hh +++ b/dynare++/src/dynare_atoms.hh @@ -64,7 +64,7 @@ namespace ogdyn class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor { public: - enum class atype {endovar, exovar, param}; + enum class atype { endovar, exovar, param }; protected: using Tatypemap = map; /* The map assigining a type to each name. */ diff --git a/dynare++/src/dynare_exception.hh b/dynare++/src/dynare_exception.hh index 99eff6ad9..1112a37c6 100644 --- a/dynare++/src/dynare_exception.hh +++ b/dynare++/src/dynare_exception.hh @@ -29,8 +29,8 @@ class DynareException std::string mes; public: DynareException(const std::string &m, const std::string &fname, int line, int col) - : mes{"Parse error at " + fname + ", line " + std::to_string(line) + ", column " + - std::to_string(col) + ": " + m} + : mes{"Parse error at " + fname + ", line " + std::to_string(line) + ", column " + + std::to_string(col) + ": " + m} { } DynareException(const std::string &fname, int line, const std::string &m) diff --git a/dynare++/src/dynare_model.cc b/dynare++/src/dynare_model.cc index d7d8abb6a..683e7f8a4 100644 --- a/dynare++/src/dynare_model.cc +++ b/dynare++/src/dynare_model.cc @@ -45,7 +45,7 @@ ParsedMatrix::ParsedMatrix(const ogp::MatrixParser &mp) } DynareModel::DynareModel() - : atoms(), eqs(atoms) + : atoms(), eqs(atoms) { } diff --git a/dynare++/src/dynare_model.hh b/dynare++/src/dynare_model.hh index 18c428df0..6c9a2f231 100644 --- a/dynare++/src/dynare_model.hh +++ b/dynare++/src/dynare_model.hh @@ -404,8 +404,8 @@ namespace ogdyn in the subclass. */ void write_der0(std::ostream &os); /* This writes the evaluation of the first order derivative of the system. - It calls pure virtual methods for writing a preamble, assignment, and - assignemnt of the resulting objects. */ + It calls pure virtual methods for writing a preamble, assignment, and + assignemnt of the resulting objects. */ void write_der1(std::ostream &os); protected: virtual void write_der0_preamble(std::ostream &os) const = 0; diff --git a/dynare++/src/dynare_params.cc b/dynare++/src/dynare_params.cc index a2a989a69..81b8064a4 100644 --- a/dynare++/src/dynare_params.cc +++ b/dynare++/src/dynare_params.cc @@ -51,39 +51,40 @@ DynareParams::DynareParams(int argc, char **argv) modname = argv[argc-1]; argc--; - struct option const opts [] = { - {"periods", required_argument, nullptr, static_cast(opt::per)}, - {"per", required_argument, nullptr, static_cast(opt::per)}, - {"burn", required_argument, nullptr, static_cast(opt::burn)}, - {"simulations", required_argument, nullptr, static_cast(opt::sim)}, - {"sim", required_argument, nullptr, static_cast(opt::sim)}, - {"rtperiods", required_argument, nullptr, static_cast(opt::rtper)}, - {"rtper", required_argument, nullptr, static_cast(opt::rtper)}, - {"rtsimulations", required_argument, nullptr, static_cast(opt::rtsim)}, - {"rtsim", required_argument, nullptr, static_cast(opt::rtsim)}, - {"condperiods", required_argument, nullptr, static_cast(opt::condper)}, - {"condper", required_argument, nullptr, static_cast(opt::condper)}, - {"condsimulations", required_argument, nullptr, static_cast(opt::condsim)}, - {"condsim", required_argument, nullptr, static_cast(opt::condsim)}, - {"prefix", required_argument, nullptr, static_cast(opt::prefix)}, - {"threads", required_argument, nullptr, static_cast(opt::threads)}, - {"steps", required_argument, nullptr, static_cast(opt::steps)}, - {"seed", required_argument, nullptr, static_cast(opt::seed)}, - {"order", required_argument, nullptr, static_cast(opt::order)}, - {"ss-tol", required_argument, nullptr, static_cast(opt::ss_tol)}, - {"check", required_argument, nullptr, static_cast(opt::check)}, - {"check-scale", required_argument, nullptr, static_cast(opt::check_scale)}, - {"check-evals", required_argument, nullptr, static_cast(opt::check_evals)}, - {"check-num", required_argument, nullptr, static_cast(opt::check_num)}, - {"qz-criterium", required_argument, nullptr, static_cast(opt::qz_criterium)}, - {"no-irfs", no_argument, nullptr, static_cast(opt::noirfs)}, - {"irfs", no_argument, nullptr, static_cast(opt::irfs)}, - {"centralize", no_argument, nullptr, static_cast(opt::centralize)}, - {"no-centralize", no_argument, nullptr, static_cast(opt::no_centralize)}, - {"help", no_argument, nullptr, static_cast(opt::help)}, - {"version", no_argument, nullptr, static_cast(opt::version)}, - {nullptr, 0, nullptr, 0} - }; + struct option const opts[] = + { + {"periods", required_argument, nullptr, static_cast(opt::per)}, + {"per", required_argument, nullptr, static_cast(opt::per)}, + {"burn", required_argument, nullptr, static_cast(opt::burn)}, + {"simulations", required_argument, nullptr, static_cast(opt::sim)}, + {"sim", required_argument, nullptr, static_cast(opt::sim)}, + {"rtperiods", required_argument, nullptr, static_cast(opt::rtper)}, + {"rtper", required_argument, nullptr, static_cast(opt::rtper)}, + {"rtsimulations", required_argument, nullptr, static_cast(opt::rtsim)}, + {"rtsim", required_argument, nullptr, static_cast(opt::rtsim)}, + {"condperiods", required_argument, nullptr, static_cast(opt::condper)}, + {"condper", required_argument, nullptr, static_cast(opt::condper)}, + {"condsimulations", required_argument, nullptr, static_cast(opt::condsim)}, + {"condsim", required_argument, nullptr, static_cast(opt::condsim)}, + {"prefix", required_argument, nullptr, static_cast(opt::prefix)}, + {"threads", required_argument, nullptr, static_cast(opt::threads)}, + {"steps", required_argument, nullptr, static_cast(opt::steps)}, + {"seed", required_argument, nullptr, static_cast(opt::seed)}, + {"order", required_argument, nullptr, static_cast(opt::order)}, + {"ss-tol", required_argument, nullptr, static_cast(opt::ss_tol)}, + {"check", required_argument, nullptr, static_cast(opt::check)}, + {"check-scale", required_argument, nullptr, static_cast(opt::check_scale)}, + {"check-evals", required_argument, nullptr, static_cast(opt::check_evals)}, + {"check-num", required_argument, nullptr, static_cast(opt::check_num)}, + {"qz-criterium", required_argument, nullptr, static_cast(opt::qz_criterium)}, + {"no-irfs", no_argument, nullptr, static_cast(opt::noirfs)}, + {"irfs", no_argument, nullptr, static_cast(opt::irfs)}, + {"centralize", no_argument, nullptr, static_cast(opt::centralize)}, + {"no-centralize", no_argument, nullptr, static_cast(opt::no_centralize)}, + {"help", no_argument, nullptr, static_cast(opt::help)}, + {"version", no_argument, nullptr, static_cast(opt::version)}, + {nullptr, 0, nullptr, 0} + }; int ret; int index; diff --git a/dynare++/src/dynare_params.hh b/dynare++/src/dynare_params.hh index 79e8a1ea0..3139bf8e9 100644 --- a/dynare++/src/dynare_params.hh +++ b/dynare++/src/dynare_params.hh @@ -89,11 +89,11 @@ struct DynareParams return 10*check_num; } private: - enum class opt {per, burn, sim, rtper, rtsim, condper, condsim, - prefix, threads, - steps, seed, order, ss_tol, check, - check_evals, check_scale, check_num, noirfs, irfs, - help, version, centralize, no_centralize, qz_criterium}; + enum class opt { per, burn, sim, rtper, rtsim, condper, condsim, + prefix, threads, + steps, seed, order, ss_tol, check, + check_evals, check_scale, check_num, noirfs, irfs, + help, version, centralize, no_centralize, qz_criterium }; void processCheckFlags(const std::string &flags); /* This gathers strings from argv[optind] and on not starting with '-' to the irf_list. It stops one item before the end, since this is the model diff --git a/dynare++/src/forw_subst_builder.cc b/dynare++/src/forw_subst_builder.cc index e4e4f4cf2..fc713e1f4 100644 --- a/dynare++/src/forw_subst_builder.cc +++ b/dynare++/src/forw_subst_builder.cc @@ -70,7 +70,7 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j) // first make lagsubst be substitution setting f(x(+4)) to f(x(+1)) // this is lag = -3 (1-mlead) map lagsubst; - unordered_set nult = model.eqs.nulary_of_term(t);// make copy of nult! + unordered_set nult = model.eqs.nulary_of_term(t); // make copy of nult! model.variable_shift_map(nult, 1-mlead, lagsubst); int lagt = model.eqs.add_substitution(t, lagsubst); diff --git a/dynare++/src/planner_builder.cc b/dynare++/src/planner_builder.cc index 90a15516b..0fb3202e0 100644 --- a/dynare++/src/planner_builder.cc +++ b/dynare++/src/planner_builder.cc @@ -87,7 +87,6 @@ PlannerBuilder::PlannerBuilder(const PlannerBuilder &pb, ogdyn::DynareModel &m) diff_b_static(pb.diff_b_static), diff_f_static(pb.diff_f_static), aux_map(), static_aux_map() - { fill_yset(m.atoms.get_name_storage(), pb.yset); fill_aux_map(m.atoms.get_name_storage(), pb.aux_map, pb.static_aux_map); @@ -244,7 +243,7 @@ PlannerBuilder::make_static_version() for (int yi = 0; yi < diff_b.nrows(); yi++) diff_b_static(yi, ll-minlag) = static_tree.add_substitution(diff_b(yi, ll-minlag), - tmap, model.eqs.getTree()); + tmap, model.eqs.getTree()); // go through diff_f and fill diff_f_static for (int ll = minlag; ll <= maxlead; ll++) @@ -384,7 +383,7 @@ MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy if (it != old2new.end()) { const ogp::AtomSubstitutions::Tshiftnameset &sset = it->second; - for (const auto & itt : sset) + for (const auto &itt : sset) { const std::string &newname = itt.first; int iouter = builder.model.atoms.name2outer_endo(newname); diff --git a/dynare++/sylv/cc/BlockDiagonal.cc b/dynare++/sylv/cc/BlockDiagonal.cc index eb8d4d119..aec1a6a2b 100644 --- a/dynare++/sylv/cc/BlockDiagonal.cc +++ b/dynare++/sylv/cc/BlockDiagonal.cc @@ -65,7 +65,7 @@ BlockDiagonal::setZerosToRU(diag_iter edge) of the right-most non-zero element of i-th row from the left, and col_len[j] is distance of top-most non-zero element of j-th column to the top. (First element has distance 1). - */ +*/ void BlockDiagonal::setZeroBlockEdge(diag_iter edge) { diff --git a/dynare++/sylv/cc/GeneralMatrix.hh b/dynare++/sylv/cc/GeneralMatrix.hh index 383cf0cda..e49e221c3 100644 --- a/dynare++/sylv/cc/GeneralMatrix.hh +++ b/dynare++/sylv/cc/GeneralMatrix.hh @@ -42,7 +42,9 @@ class TransposedMatrix private: T &orig; public: - TransposedMatrix(T &orig_arg) : orig{orig_arg} {}; + TransposedMatrix(T &orig_arg) : orig{orig_arg} + { + }; }; // Syntactic sugar for representing a transposed matrix diff --git a/dynare++/sylv/cc/IterativeSylvester.cc b/dynare++/sylv/cc/IterativeSylvester.cc index 5c81d60fa..bca1d058f 100644 --- a/dynare++/sylv/cc/IterativeSylvester.cc +++ b/dynare++/sylv/cc/IterativeSylvester.cc @@ -31,7 +31,7 @@ IterativeSylvester::solve(SylvParams &pars, KronVector &x) const auto kpow = matrixK->clone(); auto fpow = matrixF->clone(); - while (steps < max_steps &&norm > max_norm) + while (steps < max_steps && norm > max_norm) { kpow->multRight(SqSylvMatrix(*kpow)); // be careful to make copy fpow->multRight(SqSylvMatrix(*fpow)); // also here diff --git a/dynare++/sylv/cc/QuasiTriangular.cc b/dynare++/sylv/cc/QuasiTriangular.cc index 581427352..cdf3ea1eb 100644 --- a/dynare++/sylv/cc/QuasiTriangular.cc +++ b/dynare++/sylv/cc/QuasiTriangular.cc @@ -148,7 +148,7 @@ void Diagonal::changeBase(double *p) { int d_size = getSize(); - for (auto & it : *this) + for (auto &it : *this) { const DiagonalBlock &b = it; int jbar = b.getIndex(); @@ -179,7 +179,7 @@ Diagonal::getEigenValues(Vector &eig) const << ", should be=" << 2*d_size << '.' << std::endl; throw SYLV_MES_EXCEPTION(mes.str()); } - for (const auto & b : *this) + for (const auto &b : *this) { int ind = b.getIndex(); eig[2*ind] = *(b.getAlpha()); @@ -303,7 +303,7 @@ Diagonal::print() const auto ff = std::cout.flags(); std::cout << "Num real: " << getNumReal() << ", num complex: " << getNumComplex() << std::endl << std::fixed; - for (const auto & it : *this) + for (const auto &it : *this) if (it.isReal()) std::cout << "real: jbar=" << it.getIndex() << ", alpha=" << *(it.getAlpha()) << std::endl; else diff --git a/dynare++/sylv/cc/QuasiTriangular.hh b/dynare++/sylv/cc/QuasiTriangular.hh index b7e52787d..ed1fab7e4 100644 --- a/dynare++/sylv/cc/QuasiTriangular.hh +++ b/dynare++/sylv/cc/QuasiTriangular.hh @@ -222,7 +222,7 @@ private: static bool isZero(double p); }; -template +template struct _matrix_iter { using _Self = _matrix_iter<_TRef, _TPtr>; @@ -260,7 +260,7 @@ public: virtual _Self &operator++() = 0; }; -template +template class _column_iter : public _matrix_iter<_TRef, _TPtr> { using _Tparent = _matrix_iter<_TRef, _TPtr>; @@ -293,7 +293,7 @@ public: } }; -template +template class _row_iter : public _matrix_iter<_TRef, _TPtr> { using _Tparent = _matrix_iter<_TRef, _TPtr>; @@ -358,7 +358,7 @@ public: explicit QuasiTriangular(const SchurDecomp &decomp); explicit QuasiTriangular(const SchurDecompZero &decomp); QuasiTriangular(const QuasiTriangular &t); - + ~QuasiTriangular() override = default; const Diagonal & getDiagonal() const diff --git a/dynare++/sylv/cc/SchurDecomp.cc b/dynare++/sylv/cc/SchurDecomp.cc index b4b1eb6cf..01c146011 100644 --- a/dynare++/sylv/cc/SchurDecomp.cc +++ b/dynare++/sylv/cc/SchurDecomp.cc @@ -31,10 +31,10 @@ SchurDecomp::SchurDecomp(const SqSylvMatrix &m) SqSylvMatrix auxt(m); lapack_int lda = auxt.getLD(), ldvs = q.getLD(); lapack_int sdim; - auto wr = std::make_unique(rows); - auto wi = std::make_unique(rows); + auto wr = std::make_unique(rows); + auto wi = std::make_unique(rows); lapack_int lwork = 6*rows; - auto work = std::make_unique(lwork); + auto work = std::make_unique(lwork); lapack_int info; dgees("V", "N", nullptr, &rows, auxt.base(), &lda, &sdim, wr.get(), wi.get(), q.base(), &ldvs, diff --git a/dynare++/sylv/cc/SchurDecompEig.cc b/dynare++/sylv/cc/SchurDecompEig.cc index edc78e725..babab598d 100644 --- a/dynare++/sylv/cc/SchurDecompEig.cc +++ b/dynare++/sylv/cc/SchurDecompEig.cc @@ -30,7 +30,7 @@ neighbour is bubbled also in front. The method returns a new position ‘to’, where the original block pointed by ‘to’ happens to appear at the end. ‘from’ must be greater than ‘to’. - */ +*/ SchurDecompEig::diag_iter SchurDecompEig::bubbleEigen(diag_iter from, diag_iter to) { @@ -65,7 +65,7 @@ SchurDecompEig::bubbleEigen(diag_iter from, diag_iter to) resolve eigenvalues from ‘itadd’ to ‘it’, before the ‘it’ can be resolved. The success is signaled by returned true. - */ +*/ bool SchurDecompEig::tryToSwap(diag_iter &it, diag_iter &itadd) { diff --git a/dynare++/sylv/cc/SimilarityDecomp.cc b/dynare++/sylv/cc/SimilarityDecomp.cc index 64690aa4d..773c5623b 100644 --- a/dynare++/sylv/cc/SimilarityDecomp.cc +++ b/dynare++/sylv/cc/SimilarityDecomp.cc @@ -52,7 +52,7 @@ SimilarityDecomp::getXDim(diag_iter start, diag_iter end, /* Find solution of X for diagonal block given by start(incl.) and end(excl.). If the solution cannot be found, or it is greater than norm, X is not changed and flase is returned. - */ +*/ bool SimilarityDecomp::solveX(diag_iter start, diag_iter end, GeneralMatrix &X, double norm) const diff --git a/dynare++/sylv/cc/SylvParams.cc b/dynare++/sylv/cc/SylvParams.cc index f3e70d7b3..cae41ad40 100644 --- a/dynare++/sylv/cc/SylvParams.cc +++ b/dynare++/sylv/cc/SylvParams.cc @@ -133,11 +133,11 @@ mxArray * SylvParams::IntParamItem::createMatlabArray() const { mxArray *res = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL); -#if MX_HAS_INTERLEAVED_COMPLEX +# if MX_HAS_INTERLEAVED_COMPLEX *mxGetInt32s(res) = value; -#else +# else *static_cast(mxGetData(res)) = value; -#endif +# endif return res; } diff --git a/dynare++/sylv/cc/SylvParams.hh b/dynare++/sylv/cc/SylvParams.hh index 29b141c06..a068ecacd 100644 --- a/dynare++/sylv/cc/SylvParams.hh +++ b/dynare++/sylv/cc/SylvParams.hh @@ -28,9 +28,9 @@ # include #endif -enum class status {def, changed, undef}; +enum class status { def, changed, undef }; -template +template struct ParamItem { protected: @@ -81,7 +81,7 @@ public: class SylvParams { public: - enum class solve_method {iter, recurse}; + enum class solve_method { iter, recurse }; protected: class DoubleParamItem : public ParamItem diff --git a/dynare++/sylv/cc/TriangularSylvester.hh b/dynare++/sylv/cc/TriangularSylvester.hh index 8abe68ac3..ecfa87d07 100644 --- a/dynare++/sylv/cc/TriangularSylvester.hh +++ b/dynare++/sylv/cc/TriangularSylvester.hh @@ -37,7 +37,7 @@ public: TriangularSylvester(const QuasiTriangular &k, const QuasiTriangular &f); TriangularSylvester(const SchurDecompZero &kdecomp, const SchurDecomp &fdecomp); TriangularSylvester(const SchurDecompZero &kdecomp, const SimilarityDecomp &fdecomp); - + ~TriangularSylvester() override = default; void print() const; void solve(SylvParams &pars, KronVector &d) const override; diff --git a/dynare++/sylv/testing/tests.cc b/dynare++/sylv/testing/tests.cc index eaf80833d..1bcfa70dc 100644 --- a/dynare++/sylv/testing/tests.cc +++ b/dynare++/sylv/testing/tests.cc @@ -398,7 +398,7 @@ TestRunnable::gen_sylv(const std::string &aname, const std::string &bname, const if (m != mmc.row() || m != mmc.col() || n != mma.row() || n != mma.col() - || n != mmb.row() || n < mmb.col() + || n != mmb.row() || n < mmb.col() || n != mmd.row() || power(m, order) != mmd.col()) { std::cout << " Incompatible sizes for gen_sylv.\n"; @@ -447,10 +447,10 @@ TestRunnable::eig_bubble(const std::string &aname, int from, int to) double normInf = check.getNormInf(); double onorm1 = orig.getNorm1(); double onormInf = orig.getNormInf(); - std:: cout << "\tabs. error1 = " << norm1 << std::endl - << u8"\tabs. error∞ = " << normInf << std::endl - << "\trel. error1 = " << norm1/onorm1 << std::endl - << u8"\trel. error∞ = " << normInf/onormInf << std::endl; + std::cout << "\tabs. error1 = " << norm1 << std::endl + << u8"\tabs. error∞ = " << normInf << std::endl + << "\trel. error1 = " << norm1/onorm1 << std::endl + << u8"\trel. error∞ = " << normInf/onormInf << std::endl; return (norm1 < eps_norm*onorm1 && normInf < eps_norm*onormInf); } diff --git a/dynare++/tl/cc/fine_container.hh b/dynare++/tl/cc/fine_container.hh index 70b6843f0..38bec75d7 100644 --- a/dynare++/tl/cc/fine_container.hh +++ b/dynare++/tl/cc/fine_container.hh @@ -90,7 +90,7 @@ public: method, which returns a type for a given stack as the type of the corresponding (old) stack of the former stack container. */ -template +template class FineContainer : public SizeRefinement, public StackContainer<_Ttype> { protected: @@ -117,8 +117,8 @@ public: FineContainer(const _Stype &sc, int max) : SizeRefinement(sc.getStackSizes(), sc.numConts(), max), StackContainer<_Ttype>(numRefinements(), getNC()), - ref_conts(getNC()), - stack_cont(sc) + ref_conts(getNC()), + stack_cont(sc) { for (int i = 0; i < numRefinements(); i++) _Stype::stack_sizes[i] = getRefSize(i); diff --git a/dynare++/tl/cc/fs_tensor.cc b/dynare++/tl/cc/fs_tensor.cc index 7d77dcebc..9330044a0 100644 --- a/dynare++/tl/cc/fs_tensor.cc +++ b/dynare++/tl/cc/fs_tensor.cc @@ -59,7 +59,7 @@ FFSTensor::FFSTensor(const FFSTensor &t, const ConstVector &x) symmetry. Let n be a number of variables and d the ⎛n+d-1⎞ dimension dim. Then the number of indices is ⎝ d ⎠. - */ +*/ int FFSTensor::calcMaxOffset(int nvar, int d) @@ -79,7 +79,7 @@ FFSTensor::FFSTensor(const FSSparseTensor &t) nv(t.nvar()) { zeros(); - for (const auto & it : t.getMap()) + for (const auto &it : t.getMap()) { index ind(*this, it.first); get(it.second.first, *ind) = it.second.second; diff --git a/dynare++/tl/cc/gs_tensor.hh b/dynare++/tl/cc/gs_tensor.hh index 19168d2c2..a16fe1f1b 100644 --- a/dynare++/tl/cc/gs_tensor.hh +++ b/dynare++/tl/cc/gs_tensor.hh @@ -215,7 +215,7 @@ public: UGSTensor(UGSTensor &&) = default; UGSTensor(int first_row, int num, UGSTensor &t) - : UTensor(first_row, num, t), tdims(t.tdims) + : UTensor(first_row, num, t), tdims(t.tdims) { } diff --git a/dynare++/tl/cc/int_sequence.cc b/dynare++/tl/cc/int_sequence.cc index 8cba193ad..f5a50a775 100644 --- a/dynare++/tl/cc/int_sequence.cc +++ b/dynare++/tl/cc/int_sequence.cc @@ -284,7 +284,7 @@ IntSequence::print() const we want to compute the number of permutations of the word ‘yyyyuuvvv’. ⎛ 9 ⎞ This is equal to the multinomial coefficient ⎝4,2,3⎠. - */ +*/ int IntSequence::noverseq() { diff --git a/dynare++/tl/cc/normal_moments.cc b/dynare++/tl/cc/normal_moments.cc index e0931cb2b..ff8468b73 100644 --- a/dynare++/tl/cc/normal_moments.cc +++ b/dynare++/tl/cc/normal_moments.cc @@ -37,7 +37,7 @@ UNormalMoments::UNormalMoments(int maxdim, const TwoDMatrix &v) equal to 2n. See the header file for proof and details. Here we sequentially construct the Kronecker power ⊗ⁿv and apply Fₙ. - */ +*/ void UNormalMoments::generateMoments(int maxdim, const TwoDMatrix &v) { diff --git a/dynare++/tl/cc/permutation.hh b/dynare++/tl/cc/permutation.hh index 32e1045b0..1986c0c33 100644 --- a/dynare++/tl/cc/permutation.hh +++ b/dynare++/tl/cc/permutation.hh @@ -43,7 +43,7 @@ Also, we need PermutationSet class which contains all permutations of an n-element set, and a bundle of permutations PermutationBundle which contains all permutation sets up to a given number. - */ +*/ #ifndef PERMUTATION_H #define PERMUTATION_H @@ -63,7 +63,7 @@ indices which yield identity. Also we have a constructor calculating map, which corresponds to permutation in sort. This is, we want (sorted s)∘m = s. - */ +*/ class Permutation { diff --git a/dynare++/tl/cc/ps_tensor.hh b/dynare++/tl/cc/ps_tensor.hh index 3acfd236e..a5b3f0654 100644 --- a/dynare++/tl/cc/ps_tensor.hh +++ b/dynare++/tl/cc/ps_tensor.hh @@ -86,7 +86,8 @@ class PerTensorDimens : public TensorDimens { private: - static IntSequence sortIntSequence(IntSequence s) + static IntSequence + sortIntSequence(IntSequence s) { s.sort(); return s; @@ -221,7 +222,7 @@ public: void addTo(FGSTensor &out) const; void addTo(UGSTensor &out) const; - enum class fill_method {first, second}; + enum class fill_method { first, second }; static fill_method decideFillMethod(const FSSparseTensor &t); private: int tailIdentitySize() const; diff --git a/dynare++/tl/cc/pyramid_prod.cc b/dynare++/tl/cc/pyramid_prod.cc index 0bfb156ad..8e2a4cfef 100644 --- a/dynare++/tl/cc/pyramid_prod.cc +++ b/dynare++/tl/cc/pyramid_prod.cc @@ -43,7 +43,7 @@ USubTensor::USubTensor(const TensorDimens &bdims, "Tensor has not full symmetry in USubTensor()"); const EquivalenceSet &eset = TLStatic::getEquiv(bdims.dimen()); zeros(); - for (const auto & it : eset) + for (const auto &it : eset) { if (it.numClasses() == hdims.dimen()) { diff --git a/dynare++/tl/cc/stack_container.cc b/dynare++/tl/cc/stack_container.cc index 291d3af7d..71144fe88 100644 --- a/dynare++/tl/cc/stack_container.cc +++ b/dynare++/tl/cc/stack_container.cc @@ -119,7 +119,7 @@ WorkerFoldMAASparse1::operator()(std::mutex &mut) const Permutation &per = pset.get(iper); IntSequence percoor(coor.size()); per.apply(coor, percoor); - for (const auto & it : eset) + for (const auto &it : eset) { if (it.numClasses() == t.dimen()) { @@ -163,7 +163,7 @@ FoldedStackContainer::multAndAddSparse2(const FSSparseTensor &t, sthread::detach_thread_group gr; FFSTensor dummy_f(0, numStacks(), t.dimen()); for (Tensor::index fi = dummy_f.begin(); fi != dummy_f.end(); ++fi) - gr.insert(std::make_unique(*this, t, out, fi.getCoor())); + gr.insert(std::make_unique(*this, t, out, fi.getCoor())); gr.run(); } @@ -231,7 +231,7 @@ FoldedStackContainer::multAndAddSparse3(const FSSparseTensor &t, Vector outcol{out.getCol(*run)}; FRSingleTensor sumcol(t.nvar(), t.dimen()); sumcol.zeros(); - for (const auto & it : eset) + for (const auto &it : eset) if (it.numClasses() == t.dimen()) { StackProduct sp(*this, it, out.getSym()); @@ -485,7 +485,7 @@ WorkerUnfoldMAASparse1::operator()(std::mutex &mut) const Permutation &per = pset.get(iper); IntSequence percoor(coor.size()); per.apply(coor, percoor); - for (const auto & it : eset) + for (const auto &it : eset) if (it.numClasses() == t.dimen()) { StackProduct sp(cont, it, out.getSym()); @@ -611,7 +611,7 @@ UnfoldedStackContainer::multAndAddStacks(const IntSequence &fi, { Permutation sort_per(ui.getCoor()); sort_per.inverse(); - for (const auto & it : eset) + for (const auto &it : eset) if (it.numClasses() == g.dimen()) { StackProduct sp(*this, it, sort_per, out.getSym()); diff --git a/dynare++/tl/cc/stack_container.hh b/dynare++/tl/cc/stack_container.hh index d5800df42..e1a3e79be 100644 --- a/dynare++/tl/cc/stack_container.hh +++ b/dynare++/tl/cc/stack_container.hh @@ -107,12 +107,12 @@ from zero types, or unit matrices are deleted. See kron_prod.hh for an explanation. */ -template +template class StackContainerInterface { public: using _Ctype = TensorContainer<_Ttype>; - enum class itype { matrix, unit, zero}; + enum class itype { matrix, unit, zero }; public: StackContainerInterface() = default; virtual ~StackContainerInterface() = default; @@ -145,7 +145,7 @@ public: It does not own its tensors. */ -template +template class StackContainer : virtual public StackContainerInterface<_Ttype> { public: @@ -347,7 +347,7 @@ protected: on four variables, the third being u′ a dummy and always returning zero if dimension of u′ is positive. */ -template +template class ZContainer : public StackContainer<_Ttype> { public: @@ -429,7 +429,7 @@ public: third one is dummy, and always returns zero. The first stack corresponds to a container of g*. */ -template +template class GContainer : public StackContainer<_Ttype> { public: @@ -503,7 +503,7 @@ public: equivalence can have permuted classes by some given permutation. Nothing else is interesting. */ -template +template class StackProduct { public: @@ -614,7 +614,7 @@ public: /* Here we only inherit from Kronecker product KronProdAllOptim, only to allow for a constructor constructing from StackProduct. */ -template +template class KronProdStack : public KronProdAllOptim { public: diff --git a/dynare++/tl/cc/symmetry.cc b/dynare++/tl/cc/symmetry.cc index f41c48c29..72f896bed 100644 --- a/dynare++/tl/cc/symmetry.cc +++ b/dynare++/tl/cc/symmetry.cc @@ -116,7 +116,7 @@ symiterator::operator++() InducedSymmetries::InducedSymmetries(const Equivalence &e, const Symmetry &s) { - for (const auto & i : e) + for (const auto &i : e) emplace_back(s, i); } diff --git a/dynare++/tl/cc/t_container.hh b/dynare++/tl/cc/t_container.hh index b81d03fc4..4f097e5d6 100644 --- a/dynare++/tl/cc/t_container.hh +++ b/dynare++/tl/cc/t_container.hh @@ -136,7 +136,8 @@ public: insert(std::make_unique<_Ttype>(first_row, num, *(it.second))); } - TensorContainer<_Ttype> &operator=(const TensorContainer<_Ttype> &c) + TensorContainer<_Ttype> & + operator=(const TensorContainer<_Ttype> &c) { n = c.n; m.clear(); @@ -182,7 +183,7 @@ public: TL_RAISE_IF(check(t->getSym()), "Tensor already in container in TensorContainer::insert"); if (!t->isFinite()) - throw TLException(__FILE__, __LINE__, "NaN or Inf asserted in TensorContainer::insert"); + throw TLException(__FILE__, __LINE__, "NaN or Inf asserted in TensorContainer::insert"); m.emplace(t->getSym(), std::move(t)); } diff --git a/dynare++/tl/cc/t_polynomial.hh b/dynare++/tl/cc/t_polynomial.hh index 8a876ae9f..1b2905310 100644 --- a/dynare++/tl/cc/t_polynomial.hh +++ b/dynare++/tl/cc/t_polynomial.hh @@ -101,7 +101,8 @@ public: struct dummy { using type = T; }; template - const T &getNext() + const T & + getNext() { return getNext(dummy()); } @@ -128,7 +129,7 @@ private: See documentation to TensorPolynomial::derivative() and TensorPolynomial::evalPartially() for details. */ -template +template class TensorPolynomial : public TensorContainer<_Ttype> { int nr; @@ -138,18 +139,18 @@ class TensorPolynomial : public TensorContainer<_Ttype> public: TensorPolynomial(int rows, int vars) : TensorContainer<_Ttype>(1), - nr(rows), nv(vars), maxdim(0) + nr(rows), nv(vars), maxdim(0) { } TensorPolynomial(const TensorPolynomial<_Ttype, _TGStype, _Stype> &tp, int k) : TensorContainer<_Ttype>(tp), - nr(tp.nr), nv(tp.nv), maxdim(0) + nr(tp.nr), nv(tp.nv), maxdim(0) { derivative(k); } TensorPolynomial(int first_row, int num, TensorPolynomial<_Ttype, _TGStype, _Stype> &tp) : TensorContainer<_Ttype>(first_row, num, tp), - nr(num), nv(tp.nv), maxdim(tp.maxdim) + nr(num), nv(tp.nv), maxdim(tp.maxdim) { } @@ -176,7 +177,7 @@ public: TensorPolynomial(const TensorPolynomial<_Ttype, _TGStype, _Stype> &tp, const Vector &xval) : TensorContainer<_Ttype>(1), - nr(tp.nrows()), nv(tp.nvars() - xval.length()), maxdim(0) + nr(tp.nrows()), nv(tp.nvars() - xval.length()), maxdim(0) { TL_RAISE_IF(nvars() < 0, "Length of xval too big in TensorPolynomial contract constructor"); @@ -472,7 +473,7 @@ public: tensor, with the number of variables equal to the number of variables of the polynomial plus 1 for ‘1’. */ -template +template class CompactPolynomial : public _Ttype { public: diff --git a/dynare++/tl/cc/tensor.hh b/dynare++/tl/cc/tensor.hh index a4a4b1a10..cbeced9bb 100644 --- a/dynare++/tl/cc/tensor.hh +++ b/dynare++/tl/cc/tensor.hh @@ -83,7 +83,7 @@ class Tensor : public TwoDMatrix { public: - enum class indor {along_row, along_col}; + enum class indor { along_row, along_col }; /* The index represents n-tuple α₁…αₙ. Since its movement is dependent on the underlying tensor (with storage and symmetry), we maintain a reference to diff --git a/dynare++/tl/cc/tl_exception.hh b/dynare++/tl/cc/tl_exception.hh index 19002d541..201f4320c 100644 --- a/dynare++/tl/cc/tl_exception.hh +++ b/dynare++/tl/cc/tl_exception.hh @@ -59,7 +59,7 @@ # define TL_DEBUG 0 #endif -#define TL_RAISE(mes) \ +#define TL_RAISE(mes) \ throw TLException(__FILE__, __LINE__, mes) #define TL_RAISE_IF(expr, mes) \ @@ -71,8 +71,8 @@ class TLException { const std::string fname; int lnum; - const std::string message; public: + const std::string message; TLException(std::string fname_arg, int lnum_arg, std::string message_arg) : fname{std::move(fname_arg)}, lnum{lnum_arg}, diff --git a/dynare++/tl/cc/twod_matrix.hh b/dynare++/tl/cc/twod_matrix.hh index 83e1b27a2..bd45083d3 100644 --- a/dynare++/tl/cc/twod_matrix.hh +++ b/dynare++/tl/cc/twod_matrix.hh @@ -142,7 +142,6 @@ public: { } #endif - ~TwoDMatrix() override = default; TwoDMatrix &operator=(const TwoDMatrix &m) = default; diff --git a/dynare++/tl/testing/factory.hh b/dynare++/tl/testing/factory.hh index f5eab5d49..0dbd3ef26 100644 --- a/dynare++/tl/testing/factory.hh +++ b/dynare++/tl/testing/factory.hh @@ -42,7 +42,7 @@ class Factory public: double get(); // This can be used with UGSTensor, FGSTensor - template + template std::unique_ptr<_Ttype> make(int r, const Symmetry &s, const IntSequence &nvs) { @@ -53,7 +53,7 @@ public: } // This can be used with FFSTensor, UFSTensor, FRTensor, URTensor - template + template std::unique_ptr<_Ttype> make(int r, int nv, int dim) { @@ -63,7 +63,7 @@ public: return res; } - template + template _Ctype makeCont(int r, const IntSequence &nvs, int maxdim) { @@ -80,7 +80,7 @@ public: return res; } - template + template _Ptype makePoly(int r, int nv, int maxdim) { diff --git a/dynare++/tl/testing/tests.cc b/dynare++/tl/testing/tests.cc index d2f01fe5c..559bafd6f 100644 --- a/dynare++/tl/testing/tests.cc +++ b/dynare++/tl/testing/tests.cc @@ -56,10 +56,10 @@ protected: template static bool index_forward(const Symmetry &s, const IntSequence &nvs); - template + template static bool index_backward(const Symmetry &s, const IntSequence &nvs); - template + template static bool index_offset(const Symmetry &s, const IntSequence &nvs); static bool fold_unfold(std::unique_ptr folded); @@ -122,7 +122,7 @@ TestRunnable::test() const /****************************************************/ /* definition of TestRunnable static methods */ /****************************************************/ -template +template bool TestRunnable::index_forward(const Symmetry &s, const IntSequence &nvs) { @@ -154,7 +154,7 @@ TestRunnable::index_forward(const Symmetry &s, const IntSequence &nvs) return fails == 0; } -template +template bool TestRunnable::index_backward(const Symmetry &s, const IntSequence &nvs) { @@ -185,7 +185,7 @@ TestRunnable::index_backward(const Symmetry &s, const IntSequence &nvs) return fails == 0; } -template +template bool TestRunnable::index_offset(const Symmetry &s, const IntSequence &nvs) { diff --git a/dynare++/utils/cc/pascal_triangle.cc b/dynare++/utils/cc/pascal_triangle.cc index dff2d6b7e..8b8a63d26 100644 --- a/dynare++/utils/cc/pascal_triangle.cc +++ b/dynare++/utils/cc/pascal_triangle.cc @@ -68,7 +68,6 @@ PascalRow::print() const std::cout << std::endl; } - namespace PascalTriangle { namespace // Anonymous namespace that is a functional equivalent of “private” @@ -127,7 +126,7 @@ namespace PascalTriangle void print() { - for (const auto & i : tr) + for (const auto &i : tr) i.print(); } } diff --git a/dynare++/utils/cc/sthread.cc b/dynare++/utils/cc/sthread.cc index 303cd7b00..212f33572 100644 --- a/dynare++/utils/cc/sthread.cc +++ b/dynare++/utils/cc/sthread.cc @@ -49,20 +49,20 @@ namespace sthread { counter++; std::thread th{[&, it] { - // The ‘it’ variable is captured by value, because otherwise the iterator may move - (*it)->operator()(mut_threads); - std::unique_lock lk2{mut_cv}; - counter--; - /* First notify the thread waiting on the condition variable, then - unlock the mutex. We must do these two operations in that order, - otherwise there is a possibility of having the main process - destroying the condition variable before the thread tries to - notify it (if all other threads terminate at the same time and - bring the counter down to zero). - For that reason, we cannot use std::notify_all_at_thread_exit() */ - cv.notify_one(); - lk2.unlock(); - }}; + // The ‘it’ variable is captured by value, because otherwise the iterator may move + (*it)->operator()(mut_threads); + std::unique_lock lk2{mut_cv}; + counter--; + /* First notify the thread waiting on the condition variable, then + unlock the mutex. We must do these two operations in that order, + otherwise there is a possibility of having the main process + destroying the condition variable before the thread tries to + notify it (if all other threads terminate at the same time and + bring the counter down to zero). + For that reason, we cannot use std::notify_all_at_thread_exit() */ + cv.notify_one(); + lk2.unlock(); + }}; th.detach(); ++it; cv.wait(lk, [&] { return counter < max_parallel_threads; }); diff --git a/examples/NK_baseline.mod b/examples/NK_baseline.mod index 800bc1f02..805f19e86 100644 --- a/examples/NK_baseline.mod +++ b/examples/NK_baseline.mod @@ -29,11 +29,10 @@ * * Please note that the following copyright notice only applies to this Dynare * implementation of the model. - */ /* - * Copyright (C) 2013-2016 Dynare Team + * Copyright (C) 2013-2020 Dynare Team * * This file is part of Dynare. * @@ -51,72 +50,78 @@ * along with Dynare. If not, see . */ -var d //preference shock - c //consumption - mu_z //trend growth rate of the economy (from neutral and investment specific technology) - mu_I //growth rate of investment-specific technology growth - mu_A //growth rate of neutral technology - lambda //Lagrange multiplier - R //Nominal Interest rate - PI //Inflation - r //rental rate of capital - x //investment - u //capacity utilization - q //Tobin's marginal q - f //variable for recursive formulation of wage setting - ld //aggregate labor demand - w //real wage - wstar //optimal real wage - PIstarw //optimal wage inflation - PIstar //optimal price inflation - g1 //variable 1 for recursive formulation of price setting - g2 //variable 2 for recursive formulation of price setting - yd //aggregate output - mc //marginal costs - k //capital - vp //price dispersion term - vw //wage dispersion term - l //aggregate labor bundle - phi //labor disutility shock - F; //firm profits +var d (long_name='preference shock') + c (long_name='consumption') + mu_z (long_name='trend growth rate of the economy (from neutral and investment specific technology)') + mu_I (long_name='growth rate of investment-specific technology growth') + mu_A (long_name='growth rate of neutral technology') + lambda (long_name='Lagrange multiplier') + R (long_name='Nominal Interest rate') + PI (long_name='Inflation') + r (long_name='rental rate of capital') + x (long_name='investment') + u (long_name='capacity utilization') + q (long_name='Tobin marginal q') + f (long_name='variable for recursive formulation of wage setting') + ld (long_name='aggregate labor demand') + w (long_name='real wage') + wstar (long_name='optimal real wage') + PIstarw (long_name='optimal wage inflation') + PIstar (long_name='optimal price inflation') + g1 (long_name='variable 1 for recursive formulation of price setting') + g2 (long_name='variable 2 for recursive formulation of price setting') + yd (long_name='aggregate output') + mc (long_name='marginal costs') + k (long_name='capital') + vp (long_name='price dispersion term') + vw (long_name='wage dispersion term') + l (long_name='aggregate labor bundle') + phi (long_name='labor disutility shock') + F (long_name='firm profits') + ; -varexo epsd epsphi epsmu_I epsA epsm; +varexo epsd (long_name='Innovation preference shock') + epsphi (long_name='Innovation labor disutility shock') + epsmu_I (long_name='Innovation investment-specific technology') + epsA (long_name='Innovation neutral technology') + epsm (long_name='Innovation monetary policy shock') + ; predetermined_variables k; -parameters h //consumption habits - betta //discount factor - gammma1 //capital utilization, linear term - gammma2 //capital utilization, quadratic term - delta //depreciation rate - kappa //capital adjustment costs parameter - eta //elasticity of substitution between labor varieties - epsilon //elasticity of substitution between goods varieties - varpsi //labor disutility parameter - gammma //inverse Frisch elasticity - chiw //wage indexation parameter - chi //price indexation - thetap //Calvo parameter prices - thetaw //Calvo parameter wages - alppha //capital share - Rbar //steady state interest rate - PIbar //steady state inflation - gammmaR //interest smoothing coefficient Taylor rule - gammmaPI //feedback coefficient to inflation monetary policy rule - gammmay //feedback coefficient to output growth deviation in monetary policy rule - Phi //firms fixed costs - rhod //autocorrelation preference shock - rhophi //autocorrelation labor disutility shock - Lambdamu //steady state growth rate of investmentment-specific technology - LambdaA //steady state neutral technology growth - Lambdax //steady state growth rate of investment - LambdaYd //steady state growth rate of output - sigma_d //standard deviation preference shock - sigma_phi //standard deviation labor disutility shock - sigma_mu //standard deviation investment-specific technology - sigma_A //standard deviation neutral technology - sigma_m; //standard deviation preference shock - +parameters h (long_name='consumption habits') + betta (long_name='discount factor') + gammma1 (long_name='capital utilization, linear term') + gammma2 (long_name='capital utilization, quadratic term') + delta (long_name='depreciation rate') + kappa (long_name='capital adjustment costs parameter') + eta (long_name='elasticity of substitution between labor varieties') + epsilon (long_name='elasticity of substitution between goods varieties') + varpsi (long_name='labor disutility parameter') + gammma (long_name='inverse Frisch elasticity') + chiw (long_name='wage indexation parameter') + chi (long_name='price indexation') + thetap (long_name='Calvo parameter prices') + thetaw (long_name='Calvo parameter wages') + alppha (long_name='capital share') + Rbar (long_name='steady state interest rate') + PIbar (long_name='steady state inflation') + gammmaR (long_name='interest smoothing coefficient Taylor rule') + gammmaPI (long_name='feedback coefficient to inflation monetary policy rule') + gammmay (long_name='feedback coefficient to output growth deviation in monetary policy rule') + Phi (long_name='firms fixed costs') + rhod (long_name='autocorrelation preference shock') + rhophi (long_name='autocorrelation labor disutility shock') + Lambdamu (long_name='steady state growth rate of investmentment-specific technology') + LambdaA (long_name='steady state neutral technology growth') + Lambdax (long_name='steady state growth rate of investment') + LambdaYd (long_name='steady state growth rate of output') + sigma_d (long_name='standard deviation preference shock') + sigma_phi (long_name='standard deviation labor disutility shock') + sigma_mu (long_name='standard deviation investment-specific technology') + sigma_A (long_name='standard deviation neutral technology') + sigma_m (long_name='standard deviation monetary policy shock') + ; //Note that the parameter naming in FV(2010) differs from FV(2006) //Fixed parameters, taken from FV(2010), Table 2, p. 37 @@ -177,60 +182,67 @@ FV(2006), p. 20, section 3.2. */ model; -//1. FOC consumption +[name='FOC consumption'] d*(c-h*c(-1)*mu_z^(-1))^(-1)-h*betta*d(+1)*(c(+1)*mu_z(+1)-h*c)^(-1)=lambda; -//2. Euler equation +[name='Euler equation'] lambda=betta*lambda(+1)*mu_z(+1)^(-1)/PI(+1)*R; -//3. FOC capital utilization +[name='FOC capital utilization'] r=gammma1+gammma2*(u-1); -//4. FOC capital +[name='FOC capital'] q=betta*lambda(+1)/lambda*mu_z(+1)^(-1)*mu_I(+1)^(-1)*((1-delta)*q(+1)+r(+1)*u(+1)-(gammma1*(u(+1)-1)+gammma2/2*(u(+1)-1)^2)); -//5. FOC investment +[name='FOC investment'] 1=q*(1-(kappa/2*(x/x(-1)*mu_z-Lambdax)^2)-(kappa*(x/x(-1)*mu_z-Lambdax)*x/x(-1)*mu_z)) +betta*q(+1)*lambda(+1)/lambda*mu_z(+1)^(-1)*kappa*(x(+1)/x*mu_z(+1)-Lambdax)*(x(+1)/x*mu_z(+1))^2; -//6-7. Wage setting +[name='Wage setting 1'] f=(eta-1)/eta*wstar^(1-eta)*lambda*w^eta*ld+betta*thetaw*(PI^chiw/PI(+1))^(1-eta)*(wstar(+1)/wstar*mu_z(+1))^(eta-1)*f(+1); +[name='Wage setting 2'] f=varpsi*d*phi*PIstarw^(-eta*(1+gammma))*ld^(1+gammma)+betta*thetaw*(PI^chiw/PI(+1))^(-eta*(1+gammma))*(wstar(+1)/wstar*mu_z(+1))^(eta*(1+gammma))*f(+1); -//8-10. firm's price setting +[name='Firm price setting 1'] g1=lambda*mc*yd+betta*thetap*(PI^chi/PI(+1))^(-epsilon)*g1(+1); +[name='Firm price setting 2'] g2=lambda*PIstar*yd+betta*thetap*(PI^chi/PI(+1))^(1-epsilon)*PIstar/PIstar(+1)*g2(+1); +[name='Firm price setting 3'] epsilon*g1=(epsilon-1)*g2; -//11-12. optimal inputs +[name='Optimal capital labor ratio'] u*k/ld=alppha/(1-alppha)*w/r*mu_z*mu_I; +[name='Marginal costs'] mc=(1/(1-alppha))^(1-alppha)*(1/alppha)^alppha*w^(1-alppha)*r^alppha; -//13. law of motion wages +[name='law of motion wages'] 1=thetaw*(PI(-1)^chiw/PI)^(1-eta)*(w(-1)/w*mu_z^(-1))^(1-eta)+(1-thetaw)*PIstarw^(1-eta); -//14. law of motion prices +[name='law of motion prices'] 1=thetap*(PI(-1)^chi/PI)^(1-epsilon)+(1-thetap)*PIstar^(1-epsilon); -//15. Taylor Rule +[name='Taylor Rule'] R/Rbar=(R(-1)/Rbar)^gammmaR*((PI/PIbar)^gammmaPI*((yd/yd(-1)*mu_z)/exp(LambdaYd))^gammmay)^(1-gammmaR)*exp(epsm); -//16-17. Market clearing +[name='Resource constraint'] yd=c+x+mu_z^(-1)*mu_I^(-1)*(gammma1*(u-1)+gammma2/2*(u-1)^2)*k; +[name='Aggregate production'] yd=(mu_A*mu_z^(-1)*(u*k)^alppha*ld^(1-alppha)-Phi)/vp; -//18-20. Price and wage dispersion terms +[name='Aggregate labor market'] l=vw*ld; +[name='LOM Price dispersion term'] vp=thetap*(PI(-1)^chi/PI)^(-epsilon)*vp(-1)+(1-thetap)*PIstar^(-epsilon); +[name='LOM Wage dispersion term'] vw=thetaw*(w(-1)/w*mu_z^(-1)*PI(-1)^chiw/PI)^(-eta)*vw(-1)+(1-thetaw)*(PIstarw)^(-eta); -//21. Law of motion for capital +[name='Law of motion for capital'] k(+1)*mu_z*mu_I-(1-delta)*k-mu_z*mu_I*(1-kappa/2*(x/x(-1)*mu_z-Lambdax)^2)*x=0; -//22. Profits +[name='Profits'] F=yd-1/(1-alppha)*w*ld; -//23. definition optimal wage inflation +[name='definition optimal wage inflation'] PIstarw=wstar/w; //exogenous processes -//24. Preference Shock +[name='Preference Shock'] log(d)=rhod*log(d(-1))+epsd; -//25. Labor disutility Shock +[name='Labor disutility Shock'] log(phi)=rhophi*log(phi(-1))+epsphi; -//26. Investment specific technology +[name='Investment specific technology'] log(mu_I)=Lambdamu+epsmu_I; -//27. Neutral technology +[name='Neutral technology'] log(mu_A)=LambdaA+epsA; -//28. Defininition composite technology +[name='Defininition composite technology'] mu_z=mu_A^(1/(1-alppha))*mu_I^(alppha/(1-alppha)); end; diff --git a/examples/NK_baseline_steadystate.m b/examples/NK_baseline_steadystate.m index 02f70fe53..bcf0b8a67 100644 --- a/examples/NK_baseline_steadystate.m +++ b/examples/NK_baseline_steadystate.m @@ -15,6 +15,23 @@ function [ys,params,check] = NK_baseline_steadystate(ys,exo,M_,options_) % - check [scalar] set to 0 if steady state computation worked and to % 1 of not (allows to impose restrictions on parameters) +% Copyright (C) 2013-2020 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 . + % read out parameters to access them with their name NumberOfParameters = M_.param_nbr; for ii = 1:NumberOfParameters diff --git a/examples/Ramsey_Example.mod b/examples/Ramsey_Example.mod new file mode 100644 index 000000000..61e0df3cb --- /dev/null +++ b/examples/Ramsey_Example.mod @@ -0,0 +1,239 @@ +/* + * This file replicates the model studied in: + * Lawrence J. Christiano, Roberto Motto and Massimo Rostagno (2007): + * "Notes on Ramsey-Optimal Monetary Policy", Section 2 + * The paper is available at http://faculty.wcas.northwestern.edu/~lchrist/d16/d1606/ramsey.pdf + * + * Notes: + * - This mod-files allows to simulate a simple New Keynesian Model with Rotemberg price + * adjustment costs under three different monetary policy arrangements: + * 1. a Taylor rule with a fixed inflation feedback coefficient alpha + * -> set the Optimal_policy switch to 0 + * 2. a Taylor rule where the inflation feedback coefficient alpha is chosen + * optimally to minimize a quadratic loss function (optimal simple rule (OSR)) + * -> set the Optimal_policy switch to 1 and the Ramsey switch to 0 + * 3. fully optimal monetary under commitment (Ramsey) + * -> set the Optimal_policy switch to 1 and the Ramsey switch to 1 + * + * - The Efficent_steady_state switch can be used to switch from an distorted steady state + * due to a monopolistic distortion to one where a labor subsidy counteracts this + * distortion. Note that the purely quadratic loss function in the OSR case does not capture + * the full welfare losses with a distorted steady state as there would be a linear term + * appearing. + * + * - This files shows how to use a conditional steady state file in the Ramsey case. It takes + * the value of the defined instrument R as given and then computes the rest of the steady + * state, including the steady state inflation rate, based on this value. The initial value + * of the instrument for steady state search must then be defined in an initval-block. + * + * - The optim_weights in the OSR case are based on a second order approximation to the welfare function + * as in Gali (2015). The relative weight between inflation and output gap volatility is essentially + * given by the slope of the New Keynesian Phillips Curve. Note that the linear terms that would be + * present in case of a distorted steady state need to be dropped for OSR. + * + * - Due to divine coincidence, the first best policy involves fully stabilizing inflation + * and thereby the output gap. As a consequence, the optimal inflation feedback coefficient + * in a Taylor rule would be infinity. The OSR command therefore estimates it to be at the + * upper bound defined via osr_params_bounds. + * + * - The mod-file also allows to conduct estimation under Ramsey policy by setting the + * Estimation_under_Ramsey switch to 1. + * + * This implementation was written by Johannes Pfeifer. + * + * If you spot mistakes, email me at jpfeifer@gmx.de + * + * Please note that the following copyright notice only applies to this Dynare + * implementation of the model. + */ + +/* + * Copyright (C) 2019 Dynare Team + * + * This 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. + * + * It 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. + * + * For a copy of the GNU General Public License, + * see . + */ + +//**********Define which monetary policy setup to use *********** + +@#ifndef Optimal_policy + @#define Optimal_policy=1 + @#ifndef Ramsey + @#define Ramsey=1 + @#endif +@#endif + +//**********Define whether to use distorted steady state*********** + +@#ifndef Efficent_steady_state + @#define Efficent_steady_state=0 +@#endif + +@#ifndef Estimation_under_Ramsey + @#define Estimation_under_Ramsey=0 +@#endif + +var C $C$ (long_name='Consumption') + pi $\pi$ (long_name='Gross inflation') + h $h$ (long_name='hours worked') + Z $Z$ (long_name='TFP') + R $R$ (long_name='Net nominal interest rate') + log_C ${\ln C}$ (long_name='Log Consumption') + log_h ${\ln h}$ (long_name='Log hours worked') + pi_ann ${\pi^{ann}}$ (long_name='Annualized net inflation') + R_ann ${R^{ann}}$ (long_name='Annualized net nominal interest rate') + r_real ${r^{ann,real}}$ (long_name='Annualized net real interest rate') + y_nat ${y^{nat}}$ (long_name='Natural (flex price) output') + y_gap ${r^{gap}}$ (long_name='Output gap') +; + +varexo epsilon ${\varepsilon}$ (long_name='TFP shock') + ; + +parameters beta ${\beta}$ (long_name='discount factor') + theta ${\theta}$ (long_name='substitution elasticity') + tau ${\tau}$ (long_name='labor subsidy') + chi ${\chi}$ (long_name='labor disutility') + phi ${\phi}$ (long_name='price adjustment costs') + rho ${\rho}$ (long_name='TFP autocorrelation') + @# if !defined(Ramsey) || Ramsey==0 + pi_star ${\pi^*}$ (long_name='steady state inflation') + alpha ${\alpha}$ (long_name='inflation feedback Taylor rule') + @# endif + ; + +beta=0.99; +theta=5; +phi=100; +rho=0.9; +@# if !defined(Ramsey) || Ramsey==0 + alpha=1.5; + pi_star=1; +@# endif +@# if Efficent_steady_state + tau=1/(theta-1); +@# else + tau=0; +@# endif +chi=1; + +model; + [name='Euler equation'] + 1/(1+R)=beta*C/(C(+1)*pi(+1)); + [name='Firm FOC'] + (tau-1/(theta-1))*(1-theta)+theta*(chi*h*C/(exp(Z))-1)=phi*(pi-1)*pi-beta*phi*(pi(+1)-1)*pi(+1); + [name='Resource constraint'] + C*(1+phi/2*(pi-1)^2)=exp(Z)*h; + [name='TFP process'] + Z=rho*Z(-1)+epsilon; + @#if !defined(Ramsey) || Ramsey==0 + [name='Taylor rule'] + R=pi_star/beta-1+alpha*(pi-pi_star); + @#endif + [name='Definition log consumption'] + log_C=log(C); + [name='Definition log hours worked'] + log_h=log(h); + [name='Definition annualized inflation rate'] + pi_ann=4*log(pi); + [name='Definition annualized nominal interest rate'] + R_ann=4*R; + [name='Definition annualized real interest rate'] + r_real=4*log((1+R)/pi(+1)); + [name='Definition natural output'] + y_nat=exp(Z)*sqrt((theta-1)/theta*(1+tau)/chi); + [name='output gap'] + y_gap=log_C-log(y_nat); +end; + +steady_state_model; + Z=0; + @# if !defined(Ramsey) || Ramsey==0 + R=pi_star/beta-1; %only set this if not conditional steady state file for Ramsey + @# endif + pi=(R+1)*beta; + C=sqrt((1+1/theta*((1-beta)*(pi-1)*pi-(tau-1/(theta-1))*(1-theta)))/(chi*(1+phi/2*(pi-1)^2))); + h=C*(1+phi/2*(pi-1)^2); + log_C=log(C); + log_h=log(h); + pi_ann=4*log(pi); + R_ann=4*R; + r_real=4*log((1+R)/pi); + y_nat=sqrt((theta-1)/theta*(1+tau)/chi); + y_gap=log_C-log(y_nat); +end; + +@# if defined(Ramsey) && Ramsey==1 + //define initial value of instrument for Ramsey + initval; + R=1/beta-1; + end; +@# endif + +shocks; + var epsilon = 0.01^2; +end; + +@#if Optimal_policy==0 + //use Taylor rule + stoch_simul(order=2) pi_ann log_h R_ann log_C Z r_real y_nat; +@#else + @# if !defined(Ramsey) || Ramsey==0 + //use OSR Taylor rule + + //set weights on (co-)variances for OSR + optim_weights; + pi theta/((theta-1)/phi); + y_gap 1; + end; + + //define OSR parameters to be optimized + osr_params alpha; + + //starting value for OSR parameter + alpha = 1.5; + + //define bounds for OSR during optimization + osr_params_bounds; + alpha, 0, 100; + end; + + //compute OSR and provide output + osr(opt_algo=9) pi_ann log_h R_ann log_C Z r_real; + + @# else + //use Ramsey optimal policy + + //define planner objective, which corresponds to utility function of agents + planner_objective log(C)-chi/2*h^2; + + //set up Ramsey optimal policy problem with interest rate R as the instrument,... + // defining the discount factor in the planner objective to be the one of private agents + ramsey_model(instruments=(R),planner_discount=beta,planner_discount_latex_name=$\beta$); + + //conduct stochastic simulations of the Ramsey problem + stoch_simul(order=1,irf=20,periods=500) pi_ann log_h R_ann log_C Z r_real; + evaluate_planner_objective; + + @# if Estimation_under_Ramsey==1 + datatomfile('ramsey_simulation',{'log_C'}) + + estimated_params; + rho,0.5,uniform_pdf, , ,0,1; + end; + varobs log_C; + + estimation(datafile=ramsey_simulation,mode_compute=5); + @# endif + @# endif +@# endif \ No newline at end of file diff --git a/julia/Dynare.jl b/julia/Dynare.jl deleted file mode 100644 index ce24db7d2..000000000 --- a/julia/Dynare.jl +++ /dev/null @@ -1,57 +0,0 @@ -module Dynare - -## - # Copyright © 2015-2016 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 . -## - -export @compile, @dynare - -function compile(modfile) - # Add cd to path if not already there - if isempty(findin([pwd()], LOAD_PATH)) - unshift!(LOAD_PATH, pwd()) - end - # Process modfile - println(string("Using ", Sys.WORD_SIZE, "-bit preprocessor")) - preprocessor = string(dirname(@__FILE__()), "/preprocessor", Sys.WORD_SIZE, "/dynare_m") - run(`$preprocessor $modfile language=julia output=dynamic`) -end - -macro dynare(modfiles...) - ex = Expr(:toplevel) - if length(modfiles)>1 - for modfile in modfiles - eval(:(compile($modfile))) - basename = split(modfile, ".mod"; keep=false) - push!(ex.args, Expr(:import, Symbol(basename[1]))) - end - else - eval(:(compile($modfiles))) - basename = split(modfiles[1], ".mod"; keep=false) - push!(ex.args, Expr(:importall, Symbol(basename[1]))) - end - return ex -end - -macro compile(modfiles...) - for modfile in modfiles - eval(:(compile($modfile))) - end -end - -end diff --git a/julia/DynareModel.jl b/julia/DynareModel.jl deleted file mode 100644 index c2c5f46e1..000000000 --- a/julia/DynareModel.jl +++ /dev/null @@ -1,197 +0,0 @@ -module DynareModel -## - # Copyright © 2015-2018 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 . -## - -export Model, Endo, Exo, ExoDet, Param, dynare_model - -abstract type Atom end - -immutable Endo <: Atom - name::String - tex_name::String - long_name::String -end - -immutable Exo <: Atom - name::String - tex_name::String - long_name::String -end - -immutable ExoDet <: Atom - name::String - tex_name::String - long_name::String -end - -immutable Param <: Atom - name::String - tex_name::String - long_name::String -end - -immutable AuxVars - endo_index::Int - var_type::Int - orig_index::Int - orig_lead_lag::Int - eq_nbr::Int - orig_expr::String -end - -immutable PredVars - index::Int -end - -immutable ObsVars - index::Int -end - -immutable DetShocks - exo_det::Int - exo_id::Int - multiplicative::Bool - periods::Vector{Int} - value::Float64 -end - -immutable EquationTag - eq_nbr::Int - name::String - value::String -end - -type Model - fname::String - dname::String - dynare_version::String - endo::Vector{Endo} - exo::Vector{Exo} - exo_det::Vector{ExoDet} - param::Vector{Param} - aux_vars::Vector{AuxVars} - pred_vars::Vector{Int} - obs_vars::Vector{Int} - state_var::Vector{Int} - orig_endo_nbr::Int - orig_eq_nbr::Int - eq_nbr::Int - ramsey_eq_nbr::Int - det_shocks::Vector{DetShocks} - nstatic::Int - nfwrd::Int - npred::Int - nboth::Int - nsfwrd::Int - nspred::Int - ndynamic::Int - maximum_lag::Int - maximum_lead::Int - maximum_endo_lag::Int - maximum_endo_lead::Int - maximum_exo_lag::Int - maximum_exo_lead::Int - orig_maximum_lag::Int - orig_maximum_lead::Int - orig_maximum_endo_lag::Int - orig_maximum_endo_lead::Int - orig_maximum_exo_lag::Int - orig_maximum_exo_lead::Int - orig_maximum_exo_det_lag::Int - orig_maximum_exo_det_lead::Int - lead_lag_incidence::Matrix{Int} - nnzderivatives::Vector{Int} - analytical_steady_state::Bool - user_written_analytical_steady_state::Bool - static_and_dynamic_models_differ::Bool - equation_tags::Vector{String} - exo_names_orig_ord::Vector{Int} - sigma_e::Matrix{Float64} - correlation_matrix::Matrix{Float64} - h::Matrix{Float64} - correlation_matrix_me::Matrix{Float64} - sigma_e_is_diagonal::Bool - params::Vector{Float64} - static::Function - static_params_derivs::Function - dynamic::Function - dynamic_params_derivs::Function - steady_state::Function -end - -function dynare_model() - return Model("", # fname - "", # dname - "", # dynare_version - Vector{Endo}(), # endo - Vector{Exo}(), # exo - Vector{ExoDet}(), # exo_det - Vector{Param}(), # param - Vector{AuxVars}(), # aux_vars - Vector{Int}(), # pred_vars - Vector{Int}(), # obs_vars - Vector{Int}(), # state_var - 0, # orig_endo_nbr - 0, # orig_eq_nbr - 0, # eq_nbr - 0, # ramsey_eq_nbr - Vector{DetShocks}(), # det_shocks - 0, # nstatic - 0, # nfwrd - 0, # npred - 0, # nboth - 0, # nsfwrd - 0, # nspred - 0, # ndynamic - 0, # maximum_lag - 0, # maximum_lead - 0, # maximum_endo_lag - 0, # maximum_endo_lead - 0, # maximum_exo_lag - 0, # maximum_exo_lead - 0, # orig_maximum_lag - 0, # orig_maximum_lead - 0, # orig_maximum_endo_lag - 0, # orig_maximum_endo_lead - 0, # orig_maximum_exo_lag - 0, # orig_maximum_exo_lead - 0, # orig_maximum_exo_det_lag - 0, # orig_maximum_exo_det_lead - Matrix{Int}(0,0), # lead_lag_incidence - zeros(Int64,3), # nnzderivatives - false, # analytical_steady_state - false, # user_written_analytical_steady_state - false, # static_and_dynamic_models_differ - Vector{String}(), # equation_tags - Vector{Int}(), # exo_names_orig_ord - Matrix{Float64}(0,0), # sigma_e (Cov matrix of the structural innovations) - Matrix{Float64}(0,0), # correlation_matrix (Corr matrix of the structural innovations) - Matrix{Float64}(0,0), # h (Cov matrix of the measurement errors) - Matrix{Float64}(0,0), # correlation_matrix_me (Cov matrix of the measurement errors) - true, # sigma_e_is_diagonal - Vector{Float64}(), # params - function()end, # static - function()end, # static_params_derivs - function()end, # dynamic - function()end, # dynamic_params_derivs - function()end # steady_state - ) -end - -end diff --git a/julia/DynareOptions.jl b/julia/DynareOptions.jl deleted file mode 100644 index 226764e64..000000000 --- a/julia/DynareOptions.jl +++ /dev/null @@ -1,51 +0,0 @@ -module DynareOptions -## - # Copyright © 2015 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 . -## - -export Options, dynare_options - -type PFMSolver - maxit::Int - periods::Int - tolx::Float64 - tolf::Float64 -end - -function pfmsolver_set_defaults() - return PFMSolver(500, # maxit (Maximum number of iterations in Newton algorithm) - 400, # periods (Number of periods to return to the steady state) - 1e-6, # tolx (Tolerance criterion on the paths for the endogenous variables) - 1e-6 # tolf (Tolerance criterion on the stacked non linear equations) - ) -end - -type Options - dynare_version::String - linear::Bool - pfmsolver::PFMSolver -end - -function dynare_options() - return Options("", # dynare_version - false, # linear - pfmsolver_set_defaults() # pfmsolver - ) -end - -end diff --git a/julia/DynareOutput.jl b/julia/DynareOutput.jl deleted file mode 100644 index 9227267da..000000000 --- a/julia/DynareOutput.jl +++ /dev/null @@ -1,36 +0,0 @@ -module DynareOutput -## - # Copyright © 2015-2018 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 . -## - -export Ouput, dynare_output - -type Output - dynare_version::String - steady_state::Vector{Float64} - exo_steady_state::Vector{Float64} -end - -function dynare_output() - return Output("", # dynare_version - Vector{Float64}(), # steady_state - Vector{Float64}() # exo_steady_state - ) -end - -end diff --git a/julia/PerfectForesightModelSolver.jl b/julia/PerfectForesightModelSolver.jl deleted file mode 100644 index 2116b1583..000000000 --- a/julia/PerfectForesightModelSolver.jl +++ /dev/null @@ -1,134 +0,0 @@ -module PerfectForesightModelSolver - -## - # Copyright © 2016 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 . -## - -import DynareModel.Model -import DynareOutput.Output -import DynareOptions.Options - -export simulate_perfect_foresight_model! - -function simulate_perfect_foresight_model!(endogenousvariables::Matrix{Float64}, exogenousvariables::Matrix{Float64}, steadystate::Vector{Float64}, model::Model, options::Options) - - lead_lag_incidence = model.lead_lag_incidence - - nyp = countnz(lead_lag_incidence[1,:]) - ny0 = countnz(lead_lag_incidence[2,:]) - nyf = countnz(lead_lag_incidence[3,:]) - - ny = length(model.endo) - nd = nyp+ny0+nyf - - periods = options.pfmsolver.periods - params = model.params - - tmp = lead_lag_incidence[2:3,:]' - i_cols_A1 = find(tmp) - i_cols_1 = tmp[i_cols_A1] - - tmp = lead_lag_incidence[1:2,:]' - i_cols_AT = find(tmp) - i_cols_T = tmp[i_cols_AT] - - tmp = lead_lag_incidence[2,:]' - i_cols_A0 = find(tmp) - i_cols_0 = tmp[i_cols_A0] - - i_cols_j = collect(1:nd) - i_upd = ny+collect(1:periods*ny) - - Y = vec(endogenousvariables) - z = Y[find(lead_lag_incidence')] - - jacobian = zeros(Float64, ny, length(z)+length(model.exo)) - residuals = zeros(Float64, ny) - - println("\nMODEL SIMULATION:\n") - - rd = zeros(Float64, periods*ny) - - iA = zeros(Int64, periods*model.nnzderivatives[1]) - jA = zeros(Int64, periods*model.nnzderivatives[1]) - vA = zeros(Float64, periods*model.nnzderivatives[1]) - - convergence = false - iteration = 0 - - while !convergence - iteration += 1 - i_rows = collect(1:ny) - i_cols_A = find(lead_lag_incidence') - i_cols = i_cols_A - m = 0 - for it = 2:(periods+1) - model.dynamic(Y[i_cols], exogenousvariables, params, steadystate, it, residuals, jacobian) - if it==(periods+1) & it==2 - (r, c, v) = findnz(jacobian[:,i_cols_0]) - k = collect(1:length(v))+m - iA[k] = i_rows[r] - jA[k] = i_cols_A0[c] - vA[k] = v - elseif it==(periods+1) - (r, c, v) = findnz(jacobian[:,i_cols_T]) - k = collect(1:length(v))+m - iA[k] = i_rows[r] - jA[k] = i_cols_A[i_cols_T[c]] - vA[k] = v - elseif it==2 - (r, c, v) = findnz(jacobian[:,i_cols_1]) - k = collect(1:length(v))+m - iA[k] = i_rows[r] - jA[k] = i_cols_A1[c] - vA[k] = v - else - (r, c, v) = findnz(jacobian[:,i_cols_j]) - k = collect(1:length(v))+m - iA[k] = i_rows[r] - jA[k] = i_cols_A[c] - vA[k] = v - end - m += length(v) - rd[i_rows] = residuals - i_rows += ny - i_cols += ny - if it>2 - i_cols_A += ny - end - end - err = maximum(abs.(rd)) - println("Iter. ", iteration, "\t err. ", round(err, 12)) - if err. -## - -using NLsolve - -import DynareModel.Model -import DynareOutput.Output - -export steady, steady! -export steady_state, steady_state! - -function steady(model::Model, oo::Output) - if model.analytical_steady_state || model.user_written_analytical_steady_state - steadystate = zeros(length(model.endo)) - model.steady_state(steadystate, oo.exo_steady_state, model.params) - return steadystate - else - error("You have to provide a closed form solution for the steady state, or declare a guess\nfor the steady state as a third input argument.") - end -end - -function steady!(model::Model, oo::Output) - if model.analytical_steady_state || model.user_written_analytical_steady_state - model.steady_state(oo.steady_state, oo.exo_steady_state, model.params) - return - else - error("You have to provide a closed form solution for the steady state, or declare a guess\nfor the steady state as a third input argument.") - end -end - -function steady(model::Model, oo::Output, yinit::Vector{Float64}) - f!(fval::Vector{Float64}, y::Vector{Float64}) = model.static(y, oo.exo_steady_state, model.params, fval) - j!(fjac::Matrix{Float64}, y::Vector{Float64}) = model.static(y, oo.exo_steady_state, model.params, fjac) - fj!(fval::Vector{Float64}, fjac::Matrix{Float64}, y::Vector{Float64}) = model.static(y, oo.exo_steady_state, model.params, fval, fjac) - r = nlsolve(f!, j!, fj!, yinit, show_trace=false) - if converged(r) - return r.zero - else - return fill(NaN, length(yinit)) - end -end - -function steady!(model::Model, oo::Output, yinit::Vector{Float64}) - f!(fval::Vector{Float64}, y::Vector{Float64}) = model.static(y, oo.exo_steady_state, model.params, fval) - j!(fjac::Matrix{Float64}, y::Vector{Float64}) = model.static(y, oo.exo_steady_state, model.params, fjac) - fj!(fval::Vector{Float64}, fjac::Matrix{Float64}, y::Vector{Float64}) = model.static(y, oo.exo_steady_state, model.params, fval, fjac) - r = nlsolve(f!, j!, fj!, yinit, show_trace=false) - if converged(r) - oo.steady_state = r.zero - else - oo.steady_state = fill(NaN, length(yinit)) - end -end - -function steady_state(model::Model, oo::Output) - ys = steady(model, oo) - display_steady_state(model, oo, ys) -end - -function steady_state!(model::Model, oo::Output) - steady!(model, oo) - display_steady_state(model, oo, oo.steady_state) -end - -function display_steady_state(model::Model, oo::Output, ys::Vector{Float64}) - println("\n\nSTEADY STATE:\n") - for i = 1:length(model.endo) - println(string(model.endo[i].name, " = ", ys[i])) - end -end - -function issteadystate(model::Model, oo::Output, ys::Vector{Float64}) - residuals = zeros(Float64, length(ys)) - compute_static_model_residuals!(model, oo, ys, residuals) - return maximum(abs(residuals))<1e-6 -end - -function compute_static_model_residuals!(model::Model, oo::Output, ys::Vector{Float64}, residuals::Vector{Float64}) - model.static(ys, oo.exo_steady_state, model.params, residuals) -end - -end diff --git a/julia/Utils.jl b/julia/Utils.jl deleted file mode 100644 index 6bd17a2f5..000000000 --- a/julia/Utils.jl +++ /dev/null @@ -1,36 +0,0 @@ -module Utils -## - # Copyright © 2015 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 . -## - -export get_power_deriv - -function get_power_deriv(x::Float64, p::Real, k::Int) - if abs(x)<1e-12 && p>0 && k>p && typeof(p)==Int - dxp = .0 - else - dxp = x^(p-k) - for i = 0:k-1 - dxp *= p - p -= 1 - end - end - return dxp -end - -end diff --git a/license.txt b/license.txt index 96b1c0650..5bda147d2 100644 --- a/license.txt +++ b/license.txt @@ -1,6 +1,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Dynare -Upstream-Contact: Dynare Team, whose members in 2019 are: +Upstream-Contact: Dynare Team, whose members in 2020 are: - Stéphane Adjemian - Houtan Bastani - Michel Juillard @@ -22,7 +22,7 @@ Upstream-Contact: Dynare Team, whose members in 2019 are: Source: https://www.dynare.org Files: * -Copyright: 1996-2019 Dynare Team +Copyright: 1996-2020 Dynare Team License: GPL-3+ Files: matlab/AIM/SP* @@ -53,45 +53,45 @@ Files: matlab/optimization/bfgsi1.m matlab/csolve.m matlab/optimization/csminit1 matlab/bvar_toolbox.m matlab/partial_information/PI_gensys.m matlab/partial_information/qzswitch.m matlab/partial_information/qzdiv.m Copyright: 1993-2009 Christopher Sims - 2006-2016 Dynare Team + 2006-2017 Dynare Team License: GPL-3+ Files: matlab/optimization/cmaes.m Copyright: 2001-2012 Nikolaus Hansen - 2012 Dynare Team + 2012-2017 Dynare Team License: GPL-3+ Files: matlab/optimization/solvopt.m Copyright: 1997-2008 Alexei Kuntsevich and Franz Kappel 2008-2015 Giovanni Lombardo - 2015 Dynare Team + 2015-2017 Dynare Team License: GPL-3+ Files: matlab/optimization/simulated_annealing.m Copyright: 1995 E.G.Tsionas 1995-2002 Thomas Werner 2002-2015 Giovanni Lombardo - 2015 Dynare Team + 2015-2017 Dynare Team License: GPL-3+ Files: matlab/endogenous_prior.m Copyright: 2011 Lawrence J. Christiano, Mathias Trabandt and Karl Walentin - 2013 Dynare Team + 2013-2017 Dynare Team License: GPL-3+ Files: matlab/trust_region.m Copyright: 2008-2012 VZLU Prague, a.s. - 2014-2016 Dynare Team + 2014-2019 Dynare Team License: GPL-3+ Files: matlab/one_sided_hp_filter.m Copyright: 2010-2015 Alexander Meyer-Gohde - 2015 Dynare Team + 2015-2017 Dynare Team License: GPL-3+ Files: matlab/convergence_diagnostics/raftery_lewis.m Copyright: 2016 Benjamin Born and Johannes Pfeifer - 2016 Dynare Team + 2016-2017 Dynare Team License: GPL-3+ Files: matlab/commutation.m matlab/duplication.m @@ -99,10 +99,38 @@ Copyright: 1997 Tom Minka 2019 Dynare Team License: GPL-3+ +Files: matlab/allVL1.m +Copyright: 2007-2010 Bruno Luong + 2019 Dynare Team +License: GPL-3+ +Comment: The original author gave authorization to change + the license from BSD-2-clause to GPL-3+ and redistribute + it under GPL-3+ with Dynare. + +Files: matlab/uperm.m +Copyright: 2014 Bruno Luong + 2019 Dynare Team +License: GPL-3+ +Comment: The original author gave authorization to change + the license from BSD-2-clause to GPL-3+ and redistribute + it under GPL-3+ with Dynare. + +Files: matlab/prodmom.m matlab/bivmom.m +Copyright: 2008-2015 Raymond Kan + 2019-2020 Dynare Team +License: GPL-3+ +Comment: The author gave authorization to redistribute + these functions under GPL-3+ with Dynare and would + appreciate acknowledgement of the source by citation + of the following paper: + Kan, R.: "From moments of sum to moments of product." + Journal of Multivariate Analysis, 2008, vol. 99, issue 3, + pages 542-554. + Files: matlab/gsa/Morris_Measure_Groups.m matlab/gsa/Sampling_Function_2.m Copyright: 2005 European Commission - 2012 Dynare Team + 2012-2017 Dynare Team License: GPL-3+ Comment: Written by Jessica Cariboni and Francesca Campolongo Joint Research Centre, The European Commission, @@ -153,7 +181,7 @@ Comment: This file is part of GLUEWIN. Files: matlab/optimization/simpsa.m matlab/optimization/simpsaget.m matlab/optimization/simpsaset.m Copyright: 2005 Henning Schmidt, FCC, henning@fcc.chalmers.se 2006 Brecht Donckels, BIOMATH, brecht.donckels@ugent.be - 2013-2016 Dynare Team + 2013-2017 Dynare Team License: GPL-3+ Files: matlab/missing/stats/normpdf.m matlab/missing/stats/gamcdf.m @@ -163,22 +191,20 @@ Files: matlab/missing/stats/normpdf.m matlab/missing/stats/gamcdf.m matlab/missing/stats/betapdf.m matlab/missing/stats/normcdf.m matlab/missing/stats/stdnormal_cdf.m matlab/missing/stats/norminv.m matlab/missing/stats/stdnormal_pdf.m matlab/missing/stats/betainv.m - matlab/missing/stats-matlab/common_size.m Copyright: 1995-2007 Kurt Hornik - 2008-2011 Dynare Team + 2008-2017 Dynare Team License: GPL-3+ -Files: matlab/missing/stats-matlab/quantile.m +Files: matlab/missing/stats/quantile.m Copyright: 2014-2016 Christopher Hummersone - 2016 Dynare Team + 2016-2017 Dynare Team License: GPL-3+ - -Files: matlab/missing/stats-matlab/corr.m +Files: matlab/missing/stats/corr.m Copyright: 1993-1996 Kurt Hornik 1996-2015 John W. Eaton 2013-2015 Julien Bect - 2016 Dynare Team + 2016-2017 Dynare Team License: GPL-3+ Files: matlab/missing/strjoin/strjoin.m @@ -187,47 +213,35 @@ Copyright: 2013-2019 Ben Abbott 2019 Dynare Team License: GPL-3+ -Files: matlab/missing/corrcoef/corrcoef.m matlab/missing/corrcoef/sumskipnan.m - matlab/missing/corrcoef/flag_implicit_skip_nan.m matlab/missing/corrcoef/tcdf.m -Copyright: 2000-2005,2008,2009,2011 by Alois Schloegl - 2014 Dynare Team -License: GPL-3+ - Files: matlab/lmmcp/catstruct.m Copyright: 2005 Jos van der Geest 2013 Christophe Gouel - 2016 Dynare Team + 2016-2017 Dynare Team License: BSD-2-clause Files: matlab/lmmcp/lmmcp.m Copyright: 2005 Christian Kanzow and Stefania Petra 2013 Christophe Gouel - 2014 Dynare Team + 2014-2017 Dynare Team License: permissive-lmmcp Unlimited permission is granted to everyone to use, copy, modify or distribute this software. Files: matlab/utilities/graphics/distinguishable_colors.m Copyright: 2010-2011 Timothy E. Holy + 2017 Dynare Team License: BSD-2-clause Files: matlab/utilities/graphics/colorspace.m Copyright: 2005-2010 Pascal Getreuer + 2017 Dynare Team License: BSD-2-clause Files: doc/*.rst doc/*.tex doc/*.svg doc/*.pdf doc/*.bib -Copyright: 1996-2019 Dynare Team +Copyright: 1996-2020 Dynare Team License: GFDL-NIV-1.3+ -Files: doc/macroprocessor/* -Copyright: 2008-2015 Dynare Team -License: CC-BY-SA-4.0 - -Files: doc/preprocessor/* -Copyright: 2007-2019 Dynare Team -License: CC-BY-SA-4.0 - -Files: doc/dr.tex doc/bvar_a_la_sims.tex +Files: doc/dr.tex doc/dr.bib doc/bvar-a-la-sims.tex Copyright: 2007-2011 Sébastien Villemot License: GFDL-NIV-1.3+ @@ -237,19 +251,13 @@ Copyright: 2004-2011 Ondra Kamenik License: GPL-3+ Files: m4/ax_blas.m4 m4/ax_lapack.m4 -Copyright: 2008 Steven G. Johnson +Copyright: 2008-2009 Steven G. Johnson License: GPL-3+ with Autoconf exception -Files: m4/ax_boost_base.m4 -Copyright: 2008 Thomas Porschberg - 2009 Peter Adolphs -License: FSFAP - Files: m4/ax_compare_version.m4 Copyright: 2008 Tim Toolan License: FSFAP - Files: m4/ax_cxx_compile_stdcxx.m4 m4/ax_cxx_compile_stdcxx_17.m4 Copyright: 2008 Benjamin Kosnik @@ -262,14 +270,14 @@ Copyright: 2008 Benjamin Kosnik 2019 Enji Cooper License: FSFAP -Files: m4/ax_latex_class.m4 m4/ax_tex_test.m4 +Files: m4/ax_latex_class.m4 m4/ax_latex_test.m4 Copyright: 2008 Boretti Mathieu 2009 Dynare Team License: LGPL-2.1+ Files: m4/ax_matlab_arch.m4 m4/ax_matlab.m4 m4/ax_mexext.m4 Copyright: 2002-2003 Ralph Schleicher - 2009 Dynare Team + 2009-2019 Dynare Team License: GPL-2+ with Autoconf exception Files: scripts/dynare.el @@ -286,18 +294,48 @@ License: GPL-3+ Files: mex/sources/sobol/sobol.hh mex/sources/sobol/initialize_v_array.hh mex/sources/sobol/initialize_v_array.inc Copyright: 2009 John Burkardt - 2010-2011 Dynare Team + 2010-2017 Dynare Team License: LGPL-3+ Files: macOS/brewfiles/* -Copyright: 2009-2019, Homebrew contributors +Copyright: 2009-2019 Homebrew contributors 2019 Dynare Team License: BSD-2-clause -Files: contrib/jsonlab +Files: preprocessor/m4/ax_boost_base.m4 +Copyright: 2008-2009 Thomas Porschberg + 2009 Peter Adolphs +License: FSFAP + +Files: preprocessor/m4/ax_cxx_compile_stdcxx.m4 + preprocessor/m4/ax_cxx_compile_stdcxx_17.m4 +Copyright: 2008 Benjamin Kosnik + 2012 Zack Weinberg + 2013 Roy Stogner + 2014, 2015 Google Inc.; contributed by Alexey Sokolov + 2015 Paul Norman + 2015 Moritz Klammler + 2016, 2018 Krzesimir Nowak + 2019 Enji Cooper +License: FSFAP + +Files: preprocessor/m4/ax_latex_class.m4 + preprocessor/m4/ax_latex_test.m4 +Copyright: 2008 Boretti Mathieu + 2009 Dynare Team +License: LGPL-2.1+ + +Files: preprocessor/doc/macroprocessor/* +Copyright: 2008-2019 Dynare Team +License: CC-BY-SA-4.0 + +Files: preprocessor/doc/preprocessor/* +Copyright: 2007-2019 Dynare Team +License: CC-BY-SA-4.0 + +Files: contrib/jsonlab/* Copyright: 2011-2018 Qianqian Fang -License: BSD or GPL-3+ -Comment: https://www.mathworks.com/matlabcentral/fileexchange/33381-jsonlab-a-toolbox-to-encode-decode-json-files +License: BSD-2-clause or GPL-3+ Files: contrib/ms-sbvar/utilities_dw/* Copyright: 1996-2011 Daniel Waggoner @@ -565,7 +603,7 @@ License: CC-BY-SA-4.0 material not subject to the license. This includes other CC- licensed material, or material used under an exception or limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors + wiki.creativecommons.org/Considerations_for_licensors . Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the @@ -581,8 +619,8 @@ License: CC-BY-SA-4.0 such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees + for the public: + wiki.creativecommons.org/Considerations_for_licensees . ======================================================================= . diff --git a/m4/ax_tex_test.m4 b/m4/ax_tex_test.m4 deleted file mode 100644 index 323ebe55a..000000000 --- a/m4/ax_tex_test.m4 +++ /dev/null @@ -1,58 +0,0 @@ -# =========================================================================== -# http://www.nongnu.org/autoconf-archive/ax_latex_test.html -# =========================================================================== -# -# OBSOLETE MACRO -# -# Deprecated because of licensing issues. The Lesser GPL imposes licensing -# restrictions on the generated configure script unless it is augmented -# with an Autoconf Exception clause. -# -# SYNOPSIS -# -# AX_TEX_TEST(FILEDATA,VARIABLETOSET,[NOCLEAN]) -# -# DESCRIPTION -# -# This macros execute the pdftex application with FILEDATA as input and set -# VARIABLETOSET to yes or no depending on the result. If NOCLEAN is set, -# the folder used for the test is not delete after testing. -# -# The macro assumes that the variable PDFTEX is set. -# -# Adapted from the macro AX_LATEX_TEST by Sébastien Villemot. -# -# LICENSE -# -# Copyright © 2008 Boretti Mathieu -# Copyright © 2009 Dynare Team -# -# This library is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or (at -# your option) any later version. -# -# This library 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 Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . - -AC_DEFUN([AX_TEX_TEST],[ -rm -rf conftest.dir/.acltx -AS_MKDIR_P([conftest.dir/.acltx]) -cd conftest.dir/.acltx -m4_ifval([$2],[$2="no"; export $2;]) -cat > conftest.tex << ACLEOF -$1 -ACLEOF -cat conftest.tex | $PDFTEX 2>&1 1>output m4_ifval([$2],[&& $2=yes]) -cd .. -cd .. -sed 's/^/| /' conftest.dir/.acltx/conftest.tex >&5 -echo "$as_me:$LINENO: executing cat conftest.tex | $PDFTEX" >&5 -sed 's/^/| /' conftest.dir/.acltx/output >&5 -m4_ifval([$3],,[rm -rf conftest.dir/.acltx]) -]) diff --git a/macOS/build.sh b/macOS/build.sh index 3d9bf720b..55b78f7ca 100755 --- a/macOS/build.sh +++ b/macOS/build.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright © 2019 Dynare Team +# Copyright © 2019-2020 Dynare Team # # This file is part of Dynare. # @@ -99,7 +99,7 @@ mkdir -p \ if [[ $VERSION == *-unstable* ]]; then echo "$SHA" > "$PKGFILES"/sha.txt fi -cp -p "$ROOTDIR"/NEWS "$PKGFILES" +cp -p "$ROOTDIR"/NEWS.md "$PKGFILES" cp -p "$ROOTDIR"/COPYING "$PKGFILES" cp -p "$ROOTDIR"/VERSION "$PKGFILES" cp -p "$ROOTDIR"/license.txt "$PKGFILES" @@ -125,6 +125,7 @@ cp -r "$ROOTDIR"/doc/manual/build/html "$PKGFILES" cp "$ROOTDIR"/dynare++/doc/*.pdf "$PKGFILES"/doc/dynare++ cp "$ROOTDIR"/dynare++/src/dynare++ "$PKGFILES"/dynare++ +cp "$ROOTDIR"/dynare++/dynare_simul/dynare_simul.m "$PKGFILES"/dynare++ mkdir -p "$PKGFILES"/matlab/modules/dseries/externals/x13/macOS/64 cp -p "$ROOTDIR"/macOS/deps/lib64/x13as/x13as "$PKGFILES"/matlab/modules/dseries/externals/x13/macOS/64 @@ -152,15 +153,18 @@ cp -L "$ROOTDIR"/mex/matlab/* "$PKGFILES" ## Create mex for Octave ## cd "$ROOTDIR"/mex/build/octave -CC=$CC CXX=$CXX ./configure \ +OCTAVE_VERSION=$(grep OCTAVE_VERSION "$ROOTDIR"/macOS/deps/versions.mk | cut -d'=' -f2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') +OCTAVE_USR_DIR="/Applications/Octave-$OCTAVE_VERSION.app/Contents/Resources/usr" +OCTAVE_BIN_DIR="$OCTAVE_USR_DIR/Cellar/octave-octave-app@$OCTAVE_VERSION/$OCTAVE_VERSION/bin" +PATH="$OCTAVE_BIN_DIR:$PATH" CC=$CC CXX=$CXX ./configure \ PACKAGE_VERSION="$VERSION" \ PACKAGE_STRING="dynare $VERSION" \ CXXFLAGS=-I/usr/local/include \ - LDFLAGS="-static-libgcc -L/usr/local/lib" \ + LDFLAGS="-static-libgcc -L$OCTAVE_USR_DIR/lib " \ --with-gsl="$LIB64"/gsl \ --with-matio="$LIB64"/matio \ --with-slicot="$LIB64"/Slicot/with-underscore -make -j"$NTHREADS" +PATH="$OCTAVE_BIN_DIR:$PATH" make -j"$NTHREADS" cp -L "$ROOTDIR"/mex/octave/* "$PKGFILES"/mex/octave echo -e "function v = supported_octave_version\nv=\"$(octave --eval "disp(OCTAVE_VERSION)")\";\nend" > "$PKGFILES"/matlab/supported_octave_version.m diff --git a/macOS/deps/versions.mk b/macOS/deps/versions.mk index c3e232fe3..19f041cf5 100644 --- a/macOS/deps/versions.mk +++ b/macOS/deps/versions.mk @@ -1,2 +1,3 @@ SLICOT_VERSION = 5.0+20101122 X13AS_VERSION = 1.1_B39 +OCTAVE_VERSION = 4.4.1 diff --git a/macOS/distribution_template.xml b/macOS/distribution_template.xml index 15bfa4d1f..fa213eb3a 100644 --- a/macOS/distribution_template.xml +++ b/macOS/distribution_template.xml @@ -5,18 +5,18 @@ - + - - + + - - + + - - + + - dynare-VERSION_NO_SPACE.pkg - dynare-VERSION_NO_SPACE-gcc.pkg + dynare-VERSION_NO_SPACE.pkg + dynare-VERSION_NO_SPACE-gcc.pkg diff --git a/macOS/scripts/postinstall b/macOS/scripts/postinstall index e0d0f851d..42b00a4f2 100755 --- a/macOS/scripts/postinstall +++ b/macOS/scripts/postinstall @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright © 2019 Dynare Team +# Copyright © 2019-2020 Dynare Team # # This file is part of Dynare. # @@ -29,7 +29,12 @@ exec 2>&1 rm -f "$2"/dummy # Test for Internet connection -[[ -z $(curl -s -m 4 www.google.com) ]] && { echo "No internet connection found"; exit 1; } +[[ -z $(curl -s -m 4 https://github.com) ]] && \ + { \ + osascript -e 'display alert "Dynare Installation Error" message "Not able to connect to github.com. Either you are not connected to the internet or github.com is blocked where you are.\n\nAccess to GitHub is necessary to make Dynare work with the `use_dll` option on macOS.\n\nIf you cannot establish this connection or do not want to use the `use_dll` option of Dynare, please run the installer again and choose \"Customize\" from the \"Installation Type\" screen and uncheck the `GCC` option." as critical'; \ + echo "No internet connection to github.com"; \ + exit 1; \ + } # Install Command Line Tools if [[ -z $(/usr/bin/xcode-select -print-path) ]]; then @@ -49,7 +54,20 @@ fi # If CLT installation didn't work, exit [[ -z $(/usr/bin/xcode-select -print-path) ]] && \ - { echo "You must install Command Line Tools to proceed with installation of GCC"; exit 1; } + { \ + osascript -e 'display alert "Dynare Installation Error" message "Not able to find Command Line Tools.\n\nCommand Line Tools is necessary to make Dynare work with the `use_dll` option on macOS.\n\nIf you cannot establish this connection or do not want to use the `use_dll` option of Dynare, please run the installer again and choose \"Customize\" from the \"Installation Type\" screen and uncheck the `GCC` option." as critical'; \ + echo "Command Line Tools not installed"; \ + exit 1; \ + } + +# Ensure git is in the path +[[ -z $(which git) ]] && \ + { \ + osascript -e 'display alert "Dynare Installation Error" message "Not able to find Git even though the Command Line Tools have already been installed. This is likely a problem with your PATH environment variable.\n\nGit is necessary to make Dynare work with the `use_dll` option on macOS.\n\nIf you cannot establish this connection or do not want to use the `use_dll` option of Dynare, please run the installer again and choose \"Customize\" from the \"Installation Type\" screen and uncheck the `GCC` option." as critical'; \ + echo $PATH; \ + echo "Git not found in PATH"; \ + exit 1; \ + } # Install Homebrew BREWDIR="$2"/.brew diff --git a/macOS/welcome_template.html b/macOS/welcome_template.html index 5d023a2b7..43b5295d7 100644 --- a/macOS/welcome_template.html +++ b/macOS/welcome_template.html @@ -4,11 +4,11 @@

Version VERSION_NO_SPACE

DATE

-

Just a few things to note. This installation can be customized as you can choose not to install the GNU C Compiler (GCC). Installing GCC is necessary if you want to use the use_dll option in Dynare, but otherwise unnecessary.

+

Just a few things to note. This installation can be customized as you can choose not to install the GNU Compiler Collection (GCC). Installing GCC is necessary if you want to use the use_dll option in Dynare, but otherwise unnecessary.

To install GCC we run a script that first installs the XCode Command Line Tools (an Apple product). The script then installs Homebrew, a package manager for macOS and, finally, GCC itself. Both Homebrew and GCC will be installed in your Dynare installation folder. So, when you delete this folder, they too will be deleted.

-

Installing GCC will require an active internet connection and will take a few minutes to a half an hour during the Running package scripts phase of Installation. The time it takes depends on your internet speed, the speed of your computer, and whether or not you already have XCode Command Line Tools installed. The progress bar will not advance during this phase. Please be patient.

+

Installing GCC will require an active internet connection with the ability to connect to the Apple servers and GitHub. The installation will take anywhere from a few minutes to a half an hour during the Running package scripts phase of Installation. The time it takes depends on your internet speed, the speed of your computer, and whether or not you already have XCode Command Line Tools installed. The progress bar will not advance during this phase. Please be patient.

You can choose not to install GCC by choosing Customize from the Installation Type screen and deselecting GCC compiler. If you already have GCC_BINARY installed under /usr/local, you can forgo the installation of GCC here as Dynare will find your system compiler when you use use_dll.

diff --git a/matlab/+gui/+stochastic-simulation/read.m b/matlab/+gui/+stochastic-simulation/read.m index 018cc4018..65099482c 100644 --- a/matlab/+gui/+stochastic-simulation/read.m +++ b/matlab/+gui/+stochastic-simulation/read.m @@ -1,5 +1,5 @@ -function run(json) -% function varargout = run(json) +function read(json) +% function varargout = read(json) % Read JSON and run perfect foresight solver. Potentially return output as % JSON % @@ -13,7 +13,7 @@ function run(json) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2019 Dynare Team +% Copyright (C) 2019-2020 Dynare Team % % This file is part of Dynare. % @@ -34,7 +34,6 @@ global M_ options_ oo_ %loading JSON jm = loadjson_(json, 'SimplifyCell', 1); -runflag=1; data2json=struct(); M_.exo_det_length = 0; @@ -67,7 +66,7 @@ options_.order = jm.taylororder; % options_.k_order_solver = 3; % end var_list_ = char(); -info = stoch_simul(var_list_); +[~, oo_, options_] = stoch_simul(M_, options_, oo_, var_list_); irfnames=fieldnames(oo_.irfs); for jj = 1:numel(fieldnames(oo_.irfs)) diff --git a/matlab/DsgeSmoother.m b/matlab/DsgeSmoother.m index 793afa561..ee1546af5 100644 --- a/matlab/DsgeSmoother.m +++ b/matlab/DsgeSmoother.m @@ -58,7 +58,7 @@ function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,de % SPECIAL REQUIREMENTS % None -% Copyright (C) 2006-2018 Dynare Team +% Copyright (C) 2006-2020 Dynare Team % % This file is part of Dynare. % @@ -185,8 +185,7 @@ elseif options_.lik_init == 3 % Diffuse Kalman filter end [Pstar,Pinf] = compute_Pinf_Pstar(mf,T,R,Q,options_.qz_criterium); elseif options_.lik_init == 4 % Start from the solution of the Riccati equation. - [err, Pstar] = kalman_steady_state(transpose(T),R*Q*transpose(R),transpose(build_selection_matrix(mf,np,vobs)),H); - mexErrCheck('kalman_steady_state',err); + Pstar = kalman_steady_state(transpose(T),R*Q*transpose(R),transpose(build_selection_matrix(mf,np,vobs)),H); Pinf = []; if kalman_algo~=2 kalman_algo = 1; diff --git a/matlab/PosteriorIRF_core1.m b/matlab/PosteriorIRF_core1.m index 403c0b557..6c021576f 100644 --- a/matlab/PosteriorIRF_core1.m +++ b/matlab/PosteriorIRF_core1.m @@ -145,7 +145,7 @@ while fpar. +% ========================================================================= +np = p*(p+1)*(p+2)*(p+3)*(p+4)*(p+5)/(1*2*3*4*5*6); +DP6 = spalloc(p^6,np,p^6); +counti=1; +for i1=1:p + for i2=i1:p + for i3=i2:p + for i4=i3:p + for i5=i4:p + for i6=i5:p + idx = uperm([i6 i5 i4 i3 i2 i1]); + for r = 1:size(idx,1) + ii1 = idx(r,1); ii2= idx(r,2); ii3=idx(r,3); ii4=idx(r,4); ii5=idx(r,5); ii6=idx(r,6); + n = ii1 + (ii2-1)*p + (ii3-1)*p^2 + (ii4-1)*p^3 + (ii5-1)*p^4 + (ii6-1)*p^5; + m = mue(p,i6,i5,i4,i3,i2,i1); + DP6(n,m)=1; + end + counti = counti+1; + end + end + end + end + end +end +DP6inv = (transpose(DP6)*DP6)\transpose(DP6); + +function m = mue(p,i1,i2,i3,i4,i5,i6) +% Auxiliary expression, see page 122 of Meijer (2005) + m = binom_coef(p,6,1) - binom_coef(p,1,i1+1) - binom_coef(p,2,i2+1) - binom_coef(p,3,i3+1) - binom_coef(p,4,i4+1) - binom_coef(p,5,i5+1) - binom_coef(p,6,i6+1); + m = round(m); +end + +function N = binom_coef(p,q,i) +% Auxiliary expression for binomial coefficients, see page 119 of Meijer (2005) + t = q; r =p+q-i; + if t==0 + N=1; + else + N=1; + for h = 0:(t-1) + N = N*(r-h); + end + N=N/factorial(t); + end +end +end \ No newline at end of file diff --git a/matlab/UnivariateSpectralDensity.m b/matlab/UnivariateSpectralDensity.m index b46bdfd9c..1c04d622d 100644 --- a/matlab/UnivariateSpectralDensity.m +++ b/matlab/UnivariateSpectralDensity.m @@ -19,7 +19,7 @@ function [oo_] = UnivariateSpectralDensity(M_,oo_,options_,var_list) % Adapted from th_autocovariances.m. -% Copyright (C) 2006-2018 Dynare Team +% Copyright (C) 2006-2020 Dynare Team % % This file is part of Dynare. % @@ -105,7 +105,7 @@ end iky = iv(ivar); aa = ghx(iky,:); bb = ghu(iky,:); -ngrid = options_.hp_ngrid; %number of grid points +ngrid = options_.filtered_theoretical_moments_grid; %number of grid points freqs = (0 : pi/(ngrid-1):pi)'; % grid on which to compute tpos = exp( sqrt(-1)*freqs); %positive frequencies tneg = exp(-sqrt(-1)*freqs); %negative frequencies diff --git a/matlab/WriteShockDecomp2Excel.m b/matlab/WriteShockDecomp2Excel.m index f9c18fc7a..a11110455 100644 --- a/matlab/WriteShockDecomp2Excel.m +++ b/matlab/WriteShockDecomp2Excel.m @@ -100,8 +100,8 @@ for j=1:nvar comp_nbr=18; end - d0(1,:)=[{'Decomposition'} cellstr(labels(1:comp_nbr,:))' {'Smoot Var'}]; - d0=[d0; num2cell([x' z1'])]; + d0(1,:)=[{'Decomposition'} cellstr(labels(1:comp_nbr,:))' {'Smoot Var'} {'Steady State'}]; + d0=[d0; num2cell([x' z1' ]), [num2cell(SteadyState(i_var(j))); cell(size(z1,2)-1,1)]]; LastRow=size(d0,1); if use_shock_groups d0(LastRow+2,1)={'Legend.'}; diff --git a/matlab/accessors/get_irf.m b/matlab/accessors/get_irf.m new file mode 100644 index 000000000..93177435c --- /dev/null +++ b/matlab/accessors/get_irf.m @@ -0,0 +1,46 @@ + +function y0 = get_irf(exo,varargin) +% function x = get_irf(exoname, vname1, vname2, ...) +% returns IRF to individual exogenous for a list of variables and adds the +% steady state +% +% INPUTS: +% exo: exo variable name +% vname1, vname2, ... : list of variable names +% +% OUTPUTS +% x: irf matrix [time x number of variables] +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 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 . + +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)); +end diff --git a/matlab/accessors/get_mean.m b/matlab/accessors/get_mean.m new file mode 100644 index 000000000..85337c6c8 --- /dev/null +++ b/matlab/accessors/get_mean.m @@ -0,0 +1,56 @@ +function y0 = get_mean(varargin) +% function x = get_mean(vname1, vname2, ) +% returns the steady-state 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 +% +% OUTPUTS +% x: steady state values +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 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 . + +global M_ oo_ options_ + +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_,M_,options_,oo_,1); +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); diff --git a/matlab/get_param_by_name.m b/matlab/accessors/get_param_by_name.m similarity index 100% rename from matlab/get_param_by_name.m rename to matlab/accessors/get_param_by_name.m diff --git a/matlab/mexErrCheck.m b/matlab/accessors/get_shock_stderr_by_name.m similarity index 56% rename from matlab/mexErrCheck.m rename to matlab/accessors/get_shock_stderr_by_name.m index 708d4e505..7a5e7179d 100644 --- a/matlab/mexErrCheck.m +++ b/matlab/accessors/get_shock_stderr_by_name.m @@ -1,22 +1,17 @@ -function mexErrCheck(mexFunctionName, err) -% function mexErrCheck(mexFunctionName, err) -% this function halts processing if err is equal to 1. +function x = get_shock_stderr_by_name(exoname) +% function x = get_shock_stderr_by_name(exoname) +% returns the value of a shock identified by its name % -% INPUTS -% mexFunctionName [char] Name of the mexFunction -% err [double] error code returned from mexFunction +% INPUTS: +% exoname: shock name % % OUTPUTS -% none. -% -% ALGORITHM -% ... +% x: shock value % % SPECIAL REQUIREMENTS -% none. -% +% none -% Copyright (C) 2010 Dynare Team +% Copyright (C) 2019 Dynare Team % % This file is part of Dynare. % @@ -33,10 +28,12 @@ function mexErrCheck(mexFunctionName, err) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -if ~ischar(mexFunctionName) || ~isscalar(err) - error('The first argument must be a char and the second a scalar'); +global M_ + +i = find(strcmp(exoname,M_.exo_names)); + +if isempty(i) + error(['Can''t find shock ', exoname]) end -if err - error(['Error encountered in: ' mexFunctionName '.']); -end \ No newline at end of file +x = sqrt(M_.Sigma_e(i,i)); diff --git a/matlab/accessors/get_smooth.m b/matlab/accessors/get_smooth.m new file mode 100644 index 000000000..d4bfdf16b --- /dev/null +++ b/matlab/accessors/get_smooth.m @@ -0,0 +1,45 @@ + +function y0 = get_smooth(varargin) +% function x = get_smooth(vname1, vname2, ) +% returns smoothed variables or shocks identified by their name +% +% INPUTS: +% vname1, vname2, ... : list of variable/shock names +% +% OUTPUTS +% x: smoothed variables [T x number of variables] +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 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 . +global oo_ + +SmoothedVariables=[struct2cell(oo_.SmoothedVariables); struct2cell(oo_.SmoothedShocks)]; +my_field_names = [fieldnames(oo_.SmoothedVariables); fieldnames(oo_.SmoothedShocks)]; +isvar=zeros(length(SmoothedVariables),1); +for jf = 1:length(SmoothedVariables) + isvar(jf)=~(isstruct(SmoothedVariables{jf})); +end +SmoothedVariables=cell2struct(SmoothedVariables(logical(isvar)),my_field_names(logical(isvar))); + + +y0=zeros(length(SmoothedVariables.(varargin{1})),length(varargin)); +for j=1:length(varargin) + y0(:,j)=SmoothedVariables.(varargin{j}); +end diff --git a/matlab/accessors/get_update.m b/matlab/accessors/get_update.m new file mode 100644 index 000000000..8bdb2f907 --- /dev/null +++ b/matlab/accessors/get_update.m @@ -0,0 +1,35 @@ +function y0 = get_update(varargin) +% function x = get_update(vname1, vname2, ) +% returns updated variables identified by their name +% +% INPUTS: +% vname1, vname2, ... : list of variable names +% +% OUTPUTS +% x: smoothed variables [T x number of variables] +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 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 . +global oo_ + +y0=zeros(length(oo_.UpdatedVariables.(varargin{1})),length(varargin)); +for j=1:length(varargin) + y0(:,j)=oo_.UpdatedVariables.(varargin{j}); +end diff --git a/matlab/set_param_value.m b/matlab/accessors/set_param_value.m similarity index 100% rename from matlab/set_param_value.m rename to matlab/accessors/set_param_value.m diff --git a/matlab/accessors/set_shock_stderr_value.m b/matlab/accessors/set_shock_stderr_value.m new file mode 100644 index 000000000..f66e784ee --- /dev/null +++ b/matlab/accessors/set_shock_stderr_value.m @@ -0,0 +1,28 @@ +function set_shock_stderr_value(exoname,value) + +% Copyright (C) 2019 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 . + +global M_ + +i = strmatch(exoname,M_.exo_names,'exact'); + +if isempty(i) + error(['Shock name ' exoname ' doesn''t exist']) +end + +M_.Sigma_e(i,i) = value^2; diff --git a/matlab/allVL1.m b/matlab/allVL1.m new file mode 100644 index 000000000..7bc7e01b0 --- /dev/null +++ b/matlab/allVL1.m @@ -0,0 +1,200 @@ +function v = allVL1(n, L1, L1ops, MaxNbSol) +% All integer permutations with sum criteria +% +% function v=allVL1(n, L1); OR +% v=allVL1(n, L1, L1opt); +% v=allVL1(n, L1, L1opt, MaxNbSol); +% +% INPUT +% n: length of the vector +% L1: target L1 norm +% L1ops: optional string ('==' or '<=' or '<') +% default value is '==' +% MaxNbSol: integer, returns at most MaxNbSol permutations. +% When MaxNbSol is NaN, allVL1 returns the total number of all possible +% permutations, which is useful to check the feasibility before getting +% the permutations. +% OUTPUT: +% v: (m x n) array such as: sum(v,2) == L1, +% (or <= or < depending on L1ops) +% all elements of v is naturel numbers {0,1,...} +% v contains all (=m) possible combinations +% v is sorted by sum (L1 norm), then by dictionnary sorting criteria +% class(v) is same as class(L1) +% Algorithm: +% Recursive +% Remark: +% allVL1(n,L1-n)+1 for natural numbers defined as {1,2,...} +% Example: +% This function can be used to generate all orders of all +% multivariable polynomials of degree p in R^n: +% Order = allVL1(n, p) +% Author: Bruno Luong (brunoluong@yahoo.com) +% Original, 30/nov/2007 +% Version 1.1, 30/apr/2008: Add H1 line as suggested by John D'Errico +% 1.2, 17/may/2009: Possibility to get the number of permutations +% alone (set fourth parameter MaxNbSol to NaN) +% 1.3, 16/Sep/2009: Correct bug for number of solution +% 1.4, 18/Dec/2010: + non-recursive engine + +% Retrieved from https://www.mathworks.com/matlabcentral/fileexchange/17818-all-permutations-of-integers-with-sum-criteria +% ========================================================================= +% Copyright (C) 2007-2010 Bruno Luong +% Copyright (C) 2020 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 . +% ========================================================================= +global MaxCounter; + +if nargin<3 || isempty(L1ops) + L1ops = '=='; +end + +n = floor(n); % make sure n is integer + +if n<1 + v = []; + return +end + +if nargin<4 || isempty(MaxNbSol) + MaxCounter = Inf; +else + MaxCounter = MaxNbSol; +end +Counter(0); + +switch L1ops + case {'==' '='}, + if isnan(MaxCounter) + % return the number of solutions + v = nchoosek(n+L1-1,L1); % nchoosek(n+L1-1,n-1) + else + v = allVL1eq(n, L1); + end + case '<=', % call allVL1eq for various sum targets + if isnan(MaxCounter) + % return the number of solutions + %v = nchoosek(n+L1,L1)*factorial(n-L1); BUG <- 16/Sep/2009: + v = 0; + for j=0:L1 + v = v + nchoosek(n+j-1,j); + end + % See pascal's 11th identity, the sum doesn't seem to + % simplify to a fix formula + else + v = cell2mat(arrayfun(@(j) allVL1eq(n, j), (0:L1)', ... + 'UniformOutput', false)); + end + case '<', + v = allVL1(n, L1-1, '<=', MaxCounter); + otherwise + error('allVL1: unknown L1ops') +end + +end % allVL1 + +%% +function v = allVL1eq(n, L1) + +global MaxCounter; + +n = feval(class(L1),n); +s = n+L1; +sd = double(n)+double(L1); +notoverflowed = double(s)==sd; +if isinf(MaxCounter) && notoverflowed + v = allVL1nonrecurs(n, L1); +else + v = allVL1recurs(n, L1); +end + +end % allVL1eq + +%% Recursive engine +function v = allVL1recurs(n, L1, head) +% function v=allVL1eq(n, L1); +% INPUT +% n: length of the vector +% L1: desired L1 norm +% head: optional parameter to by concatenate in the first column +% of the output +% OUTPUT: +% if head is not defined +% v: (m x n) array such as sum(v,2)==L1 +% all elements of v is naturel numbers {0,1,...} +% v contains all (=m) possible combinations +% v is (dictionnary) sorted +% Algorithm: +% Recursive + +global MaxCounter; + +if n==1 + if Counter < MaxCounter + v = L1; + else + v = zeros(0,1,class(L1)); + end +else % recursive call + v = cell2mat(arrayfun(@(j) allVL1recurs(n-1, L1-j, j), (0:L1)', ... + 'UniformOutput', false)); +end + +if nargin>=3 % add a head column + v = [head+zeros(size(v,1),1,class(head)) v]; +end + +end % allVL1recurs + +%% +function res=Counter(newval) + persistent counter; + if nargin>=1 + counter = newval; + res = counter; + else + res = counter; + counter = counter+1; + end +end % Counter + +%% Non-recursive engine +function v = allVL1nonrecurs(n, L1) +% function v=allVL1eq(n, L1); +% INPUT +% n: length of the vector +% L1: desired L1 norm +% OUTPUT: +% if head is not defined +% v: (m x n) array such as sum(v,2)==L1 +% all elements of v is naturel numbers {0,1,...} +% v contains all (=m) possible combinations +% v is (dictionnary) sorted +% Algorithm: +% NonRecursive + +% Chose (n-1) the splitting points of the array [0:(n+L1)] +s = nchoosek(1:n+L1-1,n-1); +m = size(s,1); + +s1 = zeros(m,1,class(L1)); +s2 = (n+L1)+s1; + +v = diff([s1 s s2],1,2); % m x n +v = v-1; + +end % allVL1nonrecurs diff --git a/matlab/annualized_shock_decomposition.m b/matlab/annualized_shock_decomposition.m index e7a645764..038f15a68 100644 --- a/matlab/annualized_shock_decomposition.m +++ b/matlab/annualized_shock_decomposition.m @@ -158,7 +158,7 @@ if realtime_ && isstruct(oo_) && isfield(oo_, 'realtime_shock_decomposition') myopts.plot_shock_decomp.realtime=1; myopts.plot_shock_decomp.vintage=i; % retrieve quarterly shock decomp - z = plot_shock_decomposition(M_,oo_,myopts,[]); + [z, ~] = plot_shock_decomposition(M_,oo_,myopts,[]); zdim = size(z); z = z(i_var,:,:); if isstruct(aux) @@ -185,13 +185,14 @@ if realtime_ && isstruct(oo_) && isfield(oo_, 'realtime_shock_decomposition') if qvintage_>i-4 && qvintage_nfrcst oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)]) = ... oo_.annualized_realtime_shock_decomposition.pool(:,:,yr-nfrcst:end) - ... @@ -223,8 +225,12 @@ if realtime_ && isstruct(oo_) && isfield(oo_, 'realtime_shock_decomposition') oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,1:my_forecast_+1); oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,end,:) = ... oo_.annualized_realtime_shock_decomposition.pool(:,end,yr-my_forecast_:yr); + oo_.annualized_realtime_conditional_shock_decomposition.pool(:,:,yr-my_forecast_+1) = ... + oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-my_forecast_)])(:,:,2); end end + oo_.annualized_realtime_conditional_shock_decomposition.pool(:,:,yr-nfrcst+1) = ... + oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(yr-nfrcst)])(:,:,2); end end % ztmp=oo_.realtime_shock_decomposition.pool(:,:,21:29)-oo_.realtime_forecast_shock_decomposition.time_21; @@ -251,14 +257,14 @@ if realtime_ && isstruct(oo_) && isfield(oo_, 'realtime_shock_decomposition') if vintage_ z = oo_.annualized_realtime_conditional_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]); else - error(); + z = oo_.annualized_realtime_conditional_shock_decomposition.pool; end case 3 % forecast if vintage_ z = oo_.annualized_realtime_forecast_shock_decomposition.(['yr_' int2str(floor(vintage_/4))]); else - error() + z = oo_.annualized_realtime_forecast_shock_decomposition.pool; end end end @@ -299,16 +305,22 @@ for j=1:nvar end ztmp=squeeze(za(j,:,:)); if cumfix==0 - zscale = sum(ztmp(1:end-1,:))./ztmp(end,:); - ztmp(1:end-1,:) = ztmp(1:end-1,:)./repmat(zscale,[nterms-1,1]); + zres = ztmp(end,:) - sum(ztmp(1:end-1,:)); + w = abs(ztmp(1:end-1,:))./sum(abs(ztmp(1:end-1,:))); + ztmp(1:end-1,:) = ztmp(1:end-1,:) + repmat(zres,[nterms-1 1]).*w; +% zscale = sum(ztmp(1:end-1,:))./ztmp(end,:); +% ztmp(1:end-1,:) = ztmp(1:end-1,:)./repmat(zscale,[nterms-1,1]); else zres = ztmp(end,:)-sum(ztmp(1:end-1,:)); ztmp(1:end-1,:) = ztmp(1:end-1,:) + repmat(zres,[nterms-1 1])/(nterms-1); end gztmp=squeeze(gza(j,:,:)); if cumfix==0 - gscale = sum(gztmp(1:end-1,:))./ gztmp(end,:); - gztmp(1:end-1,:) = gztmp(1:end-1,:)./repmat(gscale,[nterms-1,1]); + gres = gztmp(end,:) - sum(gztmp(1:end-1,:)); + w = abs(gztmp(1:end-1,:))./sum(abs(gztmp(1:end-1,:))); + gztmp(1:end-1,:) = gztmp(1:end-1,:) + repmat(gres,[nterms-1 1]).*w; +% gscale = sum(gztmp(1:end-1,:))./ gztmp(end,:); +% gztmp(1:end-1,:) = gztmp(1:end-1,:)./repmat(gscale,[nterms-1,1]); else gres = gztmp(end,:) - sum(gztmp(1:end-1,:)); gztmp(1:end-1,:) = gztmp(1:end-1,:) + repmat(gres,[nterms-1 1])/(nterms-1); diff --git a/matlab/backward/backward_model_forecast.m b/matlab/backward/backward_model_forecast.m index 4b12b5ba2..cbf40f15e 100644 --- a/matlab/backward/backward_model_forecast.m +++ b/matlab/backward/backward_model_forecast.m @@ -2,13 +2,13 @@ function forecasts = backward_model_forecast(initialcondition, listofvariables, % Returns unconditional forecasts. % -% INPUTS +% INPUTS % - initialcondition [dseries] Initial conditions for the endogenous variables. % - periods [integer] scalar, the number of (forecast) periods. % - withuncertainty [logical] scalar, returns confidence bands if true. % -% OUTPUTS -% - forecast [dseries] +% OUTPUTS +% - forecast [dseries] % Copyright (C) 2017-2018 Dynare Team % @@ -98,7 +98,7 @@ end forecasts.pointforecast = dseries(transpose(ysim__0(idy,:)), initialcondition.init, listofvariables); % Set first period of forecast -forecasts.start = start; +forecasts.start = start; if withuncertainty % Preallocate an array gathering the simulations. @@ -110,7 +110,7 @@ if withuncertainty else [ysim__, xsim__] = simul_backward_nonlinear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, iy1, model_dynamic); end - ArrayOfForecasts(:,:,i) = ysim__(idy,:); + ArrayOfForecasts(:,:,i) = ysim__(idy,:); end % Compute mean (over future uncertainty) forecast. forecasts.meanforecast = dseries(transpose(mean(ArrayOfForecasts, 3)), initialcondition.init, listofvariables); diff --git a/matlab/backward/calibrateresiduals.m b/matlab/backward/calibrateresiduals.m index e417a068f..912ea17ce 100644 --- a/matlab/backward/calibrateresiduals.m +++ b/matlab/backward/calibrateresiduals.m @@ -50,7 +50,7 @@ eqname = @(z) DynareModel.equations_tags{cellfun(@(x) x==z, DynareModel.equation exogenousvariablesindbase = intersect(info.exonames, dbase.name); residuals = dseries(NaN(dbase.nobs, length(info.residuals)), dbase.init, info.residuals); allexogenousvariables = [dbase{exogenousvariablesindbase{:}}, residuals]; -allexogenousvariables = allexogenousvariables{info.exonames{:}}; +allexogenousvariables = allexogenousvariables{info.exonames{:}}; xdata = allexogenousvariables.data; % Evaluate the dynamic equation diff --git a/matlab/backward/get_lags_on_endogenous_variables.m b/matlab/backward/get_lags_on_endogenous_variables.m index 6b53dd59e..f9b5d75d0 100644 --- a/matlab/backward/get_lags_on_endogenous_variables.m +++ b/matlab/backward/get_lags_on_endogenous_variables.m @@ -1,6 +1,6 @@ function l = get_lags_on_endogenous_variables(DynareModel) -% Returns a vector with the max lag for each endogenous variable. +% Returns a vector with the max lag for each endogenous variable. % Copyright (C) 2017 Dynare Team % diff --git a/matlab/backward/get_lags_on_exogenous_variables.m b/matlab/backward/get_lags_on_exogenous_variables.m index b5465b715..590fa77a8 100644 --- a/matlab/backward/get_lags_on_exogenous_variables.m +++ b/matlab/backward/get_lags_on_exogenous_variables.m @@ -1,6 +1,6 @@ function l = get_lags_on_exogenous_variables(DynareModel) -% Returns a vector with the max lag for each exogenous variable. +% Returns a vector with the max lag for each exogenous variable. % Copyright (C) 2017 Dynare Team % diff --git a/matlab/backward/simul_backward_linear_model_.m b/matlab/backward/simul_backward_linear_model_.m index f57585e0d..742d68343 100644 --- a/matlab/backward/simul_backward_linear_model_.m +++ b/matlab/backward/simul_backward_linear_model_.m @@ -44,9 +44,9 @@ end % Get coefficients [cst, jacob] = model_dynamic(zeros(DynareModel.endo_nbr+ny1,1), ... - zeros(DynareModel.orig_maximum_lag+1,DynareModel.exo_nbr), ... - DynareModel.params, ... - DynareOutput.steady_state, DynareModel.orig_maximum_lag+1); + zeros(DynareModel.orig_maximum_lag+1,DynareModel.exo_nbr), ... + DynareModel.params, ... + DynareOutput.steady_state, DynareModel.orig_maximum_lag+1); A0inv = inv(jacob(:,jdx)); A1 = jacob(:,nonzeros(DynareModel.lead_lag_incidence(1,:))); diff --git a/matlab/backward/simul_backward_model_init.m b/matlab/backward/simul_backward_model_init.m index ab1e30c6e..c5801eacb 100644 --- a/matlab/backward/simul_backward_model_init.m +++ b/matlab/backward/simul_backward_model_init.m @@ -1,7 +1,7 @@ function [initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput, endonames, exonames, nx, ny1, iy1, jdx, model_dynamic, y] = ... simul_backward_model_init(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations) -% Initialization of the routines simulating backward models. +% Initialization of the routines simulating backward models. % Copyright (C) 2017-2019 Dynare Team % @@ -67,7 +67,7 @@ endolags_ = endolags(find(endolags)); endowithlagnames = endonames(find(endolags)); if ~isempty(missingendogenousvariables) missingendogenousvariables = setdiff(endowithlagnames, initialconditions.name); - missingendogenouslaggedvariables = intersect(endowithlagnames, missingendogenousvariables); + missingendogenouslaggedvariables = intersect(endowithlagnames, missingendogenousvariables); if ~isempty(missingendogenouslaggedvariables) disp('You have to initialize the following endogenous variables:') msg = sprintf('%s\n', missingendogenouslaggedvariables{1:end-1}); @@ -83,7 +83,7 @@ maxlag = abs(min(endolags)); if maxlag>initialconditions.nobs error('The dseries object provided as first input argument should at least have %s periods!', num2str(maxlag)) end -missinginitialcondition = false; +missinginitialcondition = false; for i = 1:length(endowithlagnames) lags = abs(endolags_(i)); variable = initialconditions{endowithlagnames{i}}; @@ -102,7 +102,7 @@ if missinginitialcondition error('Please fix the dseries object used for setting the initial conditions!') end -% If the model has lags on the exogenous variables, test if we have corresponding initial conditions. +% If the model has lags on the exogenous variables, test if we have corresponding initial conditions. exonames = DynareModel.exo_names; missingexogenousvariables = setdiff(exonames, initialconditions.name); exolags = get_lags_on_exogenous_variables(DynareModel); @@ -110,7 +110,7 @@ exolags_ = exolags(find(exolags)); exowithlagnames = exonames(find(exolags)); if ~isempty(missingexogenousvariables) missingexogenousvariables = setdiff(exowithlagnames, initialconditions.name); - missingexogenouslaggedvariables = intersect(exowithlagnames, missingexogenousvariables); + missingexogenouslaggedvariables = intersect(exowithlagnames, missingexogenousvariables); if ~isempty(missingexogenouslaggedvariables) disp('You have to initialize the following exogenous variables:') msg = sprintf('%s\n', missingexogenouslaggedvariables{1:end-1}); @@ -126,7 +126,7 @@ maxlag = abs(min(exolags)); if maxlag>initialconditions.nobs error('The dseries object provided as first input argument should at least have %s periods!', num2str(maxlag)) end -missinginitialcondition = false; +missinginitialcondition = false; for i = 1:length(exowithlagnames) lags = abs(exolags_(i)); variable = initialconditions{exowithlagnames{i}}; @@ -190,14 +190,14 @@ end if nargout>8 - nx = size(DynareOutput.exo_simul,2); - ny0 = nnz(DynareModel.lead_lag_incidence(2,:)); - ny1 = nnz(DynareModel.lead_lag_incidence(1,:)); - iy1 = find(DynareModel.lead_lag_incidence(1,:)>0); - idx = 1:DynareModel.endo_nbr; - jdx = idx+ny1; - % Get the name of the dynamic model routine. - model_dynamic = str2func([DynareModel.fname,'.dynamic']); - % initialization of vector y. - y = NaN(length(idx)+ny1,1); + nx = size(DynareOutput.exo_simul,2); + ny0 = nnz(DynareModel.lead_lag_incidence(2,:)); + ny1 = nnz(DynareModel.lead_lag_incidence(1,:)); + iy1 = find(DynareModel.lead_lag_incidence(1,:)>0); + idx = 1:DynareModel.endo_nbr; + jdx = idx+ny1; + % Get the name of the dynamic model routine. + model_dynamic = str2func([DynareModel.fname,'.dynamic']); + % initialization of vector y. + y = NaN(length(idx)+ny1,1); end \ No newline at end of file diff --git a/matlab/bivmom.m b/matlab/bivmom.m new file mode 100644 index 000000000..f850fe1c2 --- /dev/null +++ b/matlab/bivmom.m @@ -0,0 +1,83 @@ +function [y,dy] = bivmom(p,rho) +% Computes the product moment (and its derivative with respect to standard +% errors and correlation parameters) of X_1^{p_1}X_2^{p_2}, where X_1 and X_2 +% are standard bivariate normally distributed. +% n : dimension of X +% rho: correlation coefficient between X_1 and X_2 +% ========================================================================= +% INPUTS +% p [2 by 1] powers of X_{1} and X_{2} +% rho [1 by 1] correlation coefficient between X_1 and X_2 +% ------------------------------------------------------------------------- +% OUTPUTS +% y [1 by 1] product moment E[X_1^{p_1}X_2^{p_2}] +% dy [1 by 1] derivative of y wrt to rho +% ------------------------------------------------------------------------- +% This function is based upon bivmom.m which is part of replication codes +% of the following paper: +% Kan, R.: "From moments of sum to moments of product." Journal of +% Multivariate Analysis, 2008, vol. 99, issue 3, pages 542-554. +% bivmom.m can be retrieved from http://www-2.rotman.utoronto.ca/~kan/papers/prodmom.zip +% Further references: +% Kotz, Balakrishnan, and Johnson (2000), Continuous Multivariate Distributions, Vol. 1, p.261 +% Note that there is a typo in Eq.(46.25), there should be an extra rho in front +% of the equation. +% ========================================================================= +% Copyright (C) 2008-2015 Raymond Kan +% Copyright (C) 2019-2020 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 . +% ========================================================================= +s1 = p(1); +s2 = p(2); +rho2 = rho^2; +if nargout > 1 + drho2 = 2*rho; +end +if rem(s1+s2,2)==1 + y = 0; + return +end +r = fix(s1/2); +s = fix(s2/2); +y = 1; +c = 1; +if nargout > 1 + dy = 0; + dc = 0; +end +odd = 2*rem(s1,2); +for j=1:min(r,s) + if nargout > 1 + dc = 2*dc*(r+1-j)*(s+1-j)*rho2/(j*(2*j-1+odd)) + 2*c*(r+1-j)*(s+1-j)*drho2/(j*(2*j-1+odd)); + end + c = 2*c*(r+1-j)*(s+1-j)*rho2/(j*(2*j-1+odd)); + y = y+c; + if nargout > 1 + dy = dy + dc; + end +end +if odd + if nargout > 1 + dy = y + dy*rho; + end + y = y*rho; +end +y = prod([1:2:s1])*prod([1:2:s2])*y; +if nargout > 1 + dy = prod([1:2:s1])*prod([1:2:s2])*dy; +end + diff --git a/matlab/block_bytecode_mfs_steadystate.m b/matlab/block_bytecode_mfs_steadystate.m index a34b15c19..ba0bef861 100644 --- a/matlab/block_bytecode_mfs_steadystate.m +++ b/matlab/block_bytecode_mfs_steadystate.m @@ -2,7 +2,7 @@ function [r, g1] = block_bytecode_mfs_steadystate(y, b, y_all, exo, params, M) % Wrapper around the *_static.m file, for use with dynare_solve, % when block_mfs option is given to steady. -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -21,4 +21,4 @@ function [r, g1] = block_bytecode_mfs_steadystate(y, b, y_all, exo, params, M) indx = M.block_structure_stat.block(b).variable; y_all(indx) = y; -[chk, r, g1] = bytecode( y_all, exo, params, y_all, 1, y_all, 'evaluate', 'static', ['block = ' int2str(b) ]); +[r, g1] = bytecode( y_all, exo, params, y_all, 1, y_all, 'evaluate', 'static', ['block = ' int2str(b) ]); diff --git a/matlab/bytecode_steadystate.m b/matlab/bytecode_steadystate.m index 4c3e2f46f..dff35373f 100644 --- a/matlab/bytecode_steadystate.m +++ b/matlab/bytecode_steadystate.m @@ -2,7 +2,7 @@ function [r, g1] = bytecode_steadystate(y, exo, params) % Wrapper around the *_static.m file, for use with dynare_solve, % when block_mfs option is given to steady. -% Copyright (C) 2009-2011 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -19,4 +19,4 @@ function [r, g1] = bytecode_steadystate(y, exo, params) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -eval('[chk, r, g1] = bytecode( y, exo, params, y, 1, exo, ''evaluate'', ''static'');'); +eval('[r, g1] = bytecode( y, exo, params, y, 1, exo, ''evaluate'', ''static'');'); diff --git a/matlab/cellofchararraymaxlength.m b/matlab/cellofchararraymaxlength.m index 2fa7b95cf..2f42e38c3 100644 --- a/matlab/cellofchararraymaxlength.m +++ b/matlab/cellofchararraymaxlength.m @@ -1,5 +1,5 @@ function n = cellofchararraymaxlength(c) - + % Copyright (C) 2018 Dynare Team % % This file is part of Dynare. diff --git a/matlab/cli/prior.m b/matlab/cli/prior.m index 2d3018685..2ecaa3310 100644 --- a/matlab/cli/prior.m +++ b/matlab/cli/prior.m @@ -11,7 +11,7 @@ function varargout = prior(varargin) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2015-2018 Dynare Team +% Copyright (C) 2015-2019 Dynare Team % % This file is part of Dynare. % @@ -143,7 +143,8 @@ if ismember('moments', varargin) % Prior simulations (2nd order moments). end if info skipline() - fprintf('Cannot solve the model on the prior mode (info = %s, %s)\n', num2str(info(1)), interpret_resol_info(info)); + message = get_error_message(info,options_); + fprintf('Cannot solve the model on the prior mode (info = %d, %s)\n', info(1), message); skipline() return end diff --git a/matlab/commutation.m b/matlab/commutation.m index 2dd3bc209..a87017e9b 100644 --- a/matlab/commutation.m +++ b/matlab/commutation.m @@ -1,7 +1,7 @@ function k = commutation(n, m, sparseflag) % k = commutation(n, m, sparseflag) % ------------------------------------------------------------------------- -% Returns Magnus and Neudecker's commutation matrix of dimensions n by m, +% Returns Magnus and Neudecker's commutation matrix of dimensions n by m, % that solves k*vec(X)=vec(X') % ========================================================================= % INPUTS @@ -10,17 +10,18 @@ function k = commutation(n, m, sparseflag) % sparseflag: [integer] whether to use sparse matrices (=1) or not (else) % ------------------------------------------------------------------------- % OUTPUTS -% k: [n by m] commutation matrix +% k: [n by m] commutation matrix % ------------------------------------------------------------------------- -% This function is called by -% * get_first_order_solution_params_deriv.m (previously getH.m) +% This function is called by +% * get_perturbation_params_derivs.m (previously getH.m) % * get_identification_jacobians.m (previously getJJ.m) +% * pruned_state_space_system.m % ------------------------------------------------------------------------- % This function calls % * vec (embedded) % ========================================================================= % Copyright (C) 1997 Tom Minka -% Copyright (C) 2019 Dynare Team +% Copyright (C) 2019-2020 Dynare Team % % This file is part of Dynare. % @@ -40,33 +41,21 @@ function k = commutation(n, m, sparseflag) % Original author: Thomas P Minka (tpminka@media.mit.edu), April 22, 2013 if nargin < 2 - m = n(2); - n = n(1); + m = n(2); + n = n(1); end if nargin < 3 - sparseflag = 0; + sparseflag = 0; end -if 0 - % first method - i = 1:(n*m); - a = reshape(i, n, m); - j = vec(transpose(a)); - k = zeros(n*m,n*m); - for r = i - k(r, j(r)) = 1; - end +if sparseflag + k = reshape(kron(vec(speye(n)), speye(m)), n*m, n*m); else - % second method - k = reshape(kron(vec(eye(n)), eye(m)), n*m, n*m); -end - -if sparseflag ~= 0 - k = sparse(k); + k = reshape(kron(vec(eye(n)), eye(m)), n*m, n*m); end function V = vec(A) - V = A(:); + V = A(:); end end diff --git a/matlab/compute_Pinf_Pstar.m b/matlab/compute_Pinf_Pstar.m index 0ccbd02d8..6e2113f5c 100644 --- a/matlab/compute_Pinf_Pstar.m +++ b/matlab/compute_Pinf_Pstar.m @@ -150,8 +150,8 @@ Pinf = zeros(np,np); Pinf(1:nk,1:nk) = eye(nk); if np0 STtriu = STinf-eye(nk); -% A\B is the matrix division of A into B, which is roughly the -% same as INV(A)*B + % A\B is the matrix division of A into B, which is roughly the + % same as INV(A)*B STinf0 = ST00*(eye(nk)-iSTinf*STtriu); Pinf = blkdiag(zeros(np0),Pinf); QT = blkdiag(eye(np0),QT); diff --git a/matlab/compute_decision_rules.m b/matlab/compute_decision_rules.m new file mode 100644 index 000000000..372a7fa18 --- /dev/null +++ b/matlab/compute_decision_rules.m @@ -0,0 +1,36 @@ +function [dr,info,M_,options_,oo_] =compute_decision_rules(M_,options_,oo_) +% function [dr,info,M_,options_,oo_] =compute_decision_rules(M_,options_,oo_) +% INPUTS +% - M_ [structure] Matlab's structure describing the model (M_). +% - options_ [structure] Matlab's structure describing the current options (options_). +% - oo_ [structure] Matlab's structure containing the results (oo_). +% +% OUTPUTS +% - dr [structure] Reduced form model. +% - info [integer] scalar or vector, error code. +% - M_ [structure] Matlab's structure describing the model (M_). +% - options_ [structure] Matlab's structure describing the current options (options_). +% - oo_ [structure] Matlab's structure containing the results (oo_). + +% Copyright (C) 2020 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 . + +if options_.discretionary_policy + [dr,info,M_,options_,oo_] = discretionary_policy_1(options_.instruments,M_,options_,oo_); +else + [dr,info,M_,options_,oo_] = resol(0,M_,options_,oo_); +end diff --git a/matlab/compute_moments_varendo.m b/matlab/compute_moments_varendo.m index 294a9b978..4bfabce34 100644 --- a/matlab/compute_moments_varendo.m +++ b/matlab/compute_moments_varendo.m @@ -247,7 +247,7 @@ if M_.exo_nbr > 1 title = 'Posterior mean conditional variance decomposition (in percent) with measurement error'; save_name_string = 'dsge_post_mean_var_decomp_ME_cond_h'; else - for i=1:NumberOfObservedEndogenousVariables + for i=1:NumberOfObservedEndogenousVariables for j=1:NumberOfExogenousVariables temp(i,j,:) = oo_.PriorTheoreticalMoments.dsge.ConditionalVarianceDecompositionME.Mean.(observable_name_requested_vars{i}).(M_.exo_names{j}); end diff --git a/matlab/conditional_variance_decomposition.m b/matlab/conditional_variance_decomposition.m index 5f17f7d8f..4ef81da55 100644 --- a/matlab/conditional_variance_decomposition.m +++ b/matlab/conditional_variance_decomposition.m @@ -95,7 +95,7 @@ if ~all(StateSpaceModel.measurement_error==0) [observable_pos,index_subset,index_observables]=intersect(SubsetOfVariables,StateSpaceModel.observable_pos,'stable'); end ME_Variance=diag(StateSpaceModel.measurement_error); - + ConditionalVarianceDecomposition_ME = zeros(length(observable_pos),length(Steps),number_of_state_innovations+1); for i=1:number_of_state_innovations for h = 1:length(Steps) @@ -104,5 +104,5 @@ if ~all(StateSpaceModel.measurement_error==0) end ConditionalVarianceDecomposition_ME(:,:,number_of_state_innovations+1)=1-sum(ConditionalVarianceDecomposition_ME(:,:,1:number_of_state_innovations),3); else - ConditionalVarianceDecomposition_ME=[]; + ConditionalVarianceDecomposition_ME=[]; end diff --git a/matlab/conditional_variance_decomposition_ME_mc_analysis.m b/matlab/conditional_variance_decomposition_ME_mc_analysis.m index 3daf3fc48..cfe9a1b15 100644 --- a/matlab/conditional_variance_decomposition_ME_mc_analysis.m +++ b/matlab/conditional_variance_decomposition_ME_mc_analysis.m @@ -56,10 +56,10 @@ end exogenous_variable_index = check_name(exonames,exo); if isempty(exogenous_variable_index) if isequal(exo,'ME') - exogenous_variable_index=length(exonames)+1; + exogenous_variable_index=length(exonames)+1; else disp([ type '_analysis:: ' exo ' is not a declared exogenous variable!']) - return + return end end diff --git a/matlab/conditional_variance_decomposition_mc_analysis.m b/matlab/conditional_variance_decomposition_mc_analysis.m index 6fa536ad3..556e8ca76 100644 --- a/matlab/conditional_variance_decomposition_mc_analysis.m +++ b/matlab/conditional_variance_decomposition_mc_analysis.m @@ -51,7 +51,7 @@ end exogenous_variable_index = check_name(exonames,exo); if isempty(exogenous_variable_index) if ~isequal(exo,'ME') - disp([ type '_analysis:: ' exo ' is not a declared exogenous variable!']) + disp([ type '_analysis:: ' exo ' is not a declared exogenous variable!']) end return end diff --git a/matlab/convergence_diagnostics/McMCDiagnostics.m b/matlab/convergence_diagnostics/McMCDiagnostics.m index 36c513163..44c4f872d 100644 --- a/matlab/convergence_diagnostics/McMCDiagnostics.m +++ b/matlab/convergence_diagnostics/McMCDiagnostics.m @@ -184,7 +184,7 @@ if nblck == 1 % Brooks and Gelman tests need more than one block if options_.TeX Geweke_tex_header = {'Parameter'; 'Mean'; 'Std'; 'No\ Taper'}; additional_header = {[' & \multicolumn{2}{c}{Posterior} & \multicolumn{',num2str(1+length(options_.convergence.geweke.taper_steps)),'}{c}{p-values} \\'], - ['\cmidrule(r{.75em}){2-3} \cmidrule(r{.75em}){4-',num2str(4+length(options_.convergence.geweke.taper_steps)),'}']}; + ['\cmidrule(r{.75em}){2-3} \cmidrule(r{.75em}){4-',num2str(4+length(options_.convergence.geweke.taper_steps)),'}']}; for ii=1:length(options_.convergence.geweke.taper_steps) Geweke_tex_header = vertcat(Geweke_tex_header, [num2str(options_.convergence.geweke.taper_steps(ii)),'\%%\ Taper']); end diff --git a/matlab/convergence_diagnostics/geweke_moments.m b/matlab/convergence_diagnostics/geweke_moments.m index 61c22979f..51f894edd 100644 --- a/matlab/convergence_diagnostics/geweke_moments.m +++ b/matlab/convergence_diagnostics/geweke_moments.m @@ -89,7 +89,7 @@ results_struct.rne_iid = results_vec(1,4); centered_window_means=window_means-total_mean; autocov_grouped_means=zeros(n_groups,1); for lag=0:n_groups-1 - autocov_grouped_means(lag+1)=centered_window_means(lag+1:n_groups,1)'*centered_window_means(1:n_groups-lag,1)/100; + autocov_grouped_means(lag+1)=centered_window_means(lag+1:n_groups,1)'*centered_window_means(1:n_groups-lag,1)/n_groups; end % numerical standard error with tapered autocovariance functions diff --git a/matlab/convergence_diagnostics/raftery_lewis.m b/matlab/convergence_diagnostics/raftery_lewis.m index ab0e51cb7..798e102db 100644 --- a/matlab/convergence_diagnostics/raftery_lewis.m +++ b/matlab/convergence_diagnostics/raftery_lewis.m @@ -149,10 +149,10 @@ for ind_1 = 1:2 end % end of for i3 end % end of for i2 end % end of for i1 - g2 = g2*2; - bic = g2 - log(n_obs-2)*2; +g2 = g2*2; +bic = g2 - log(n_obs-2)*2; - end +end function [g2, bic] = independence_chain_test(d) diff --git a/matlab/cosn.m b/matlab/cosn.m index 9095491cc..9e239160a 100644 --- a/matlab/cosn.m +++ b/matlab/cosn.m @@ -3,7 +3,7 @@ function [co, b, yhat] = cosn(H) % ------------------------------------------------------------------------- % computes the cosine of the angle between the (endogenous variable) H(:,1) % and its projection onto the span of (exogenous variables) H(:,2:end) -% Note: This is not the same as multiple correlation coefficient since the +% Note: This is not the same as multiple correlation coefficient since the % means are not zero % ========================================================================= % INPUTS @@ -16,7 +16,7 @@ function [co, b, yhat] = cosn(H) % * b [k by 1] ols estimator % * y [n by 1] predicted endogenous values given ols estimation % ------------------------------------------------------------------------- -% This function is called by +% This function is called by % * identification_checks.m % * ident_bruteforce.m % ========================================================================= diff --git a/matlab/cubature_with_gaussian_weight.m b/matlab/cubature_with_gaussian_weight.m index c7f0ac178..75f129ccd 100644 --- a/matlab/cubature_with_gaussian_weight.m +++ b/matlab/cubature_with_gaussian_weight.m @@ -115,23 +115,23 @@ d = 4; t = zeros(5,1); try - [nodes,weights] = cubature_with_gaussian_weight(d,3); - t(1) = 1; + [nodes,weights] = cubature_with_gaussian_weight(d,3); + t(1) = 1; catch - t = t(1); - T = all(t); + t = t(1); + T = all(t); end if t(1) - m1 = nodes*weights; - m2 = nodes.^2*weights; - m3 = nodes.^3*weights; - m4 = nodes.^4*weights; - t(2) = dassert(m1,zeros(d,1),1e-12); - t(3) = dassert(m2,ones(d,1),1e-12); - t(4) = dassert(m3,zeros(d,1),1e-12); - t(5) = dassert(m4,d*ones(d,1),1e-10); - T = all(t); + m1 = nodes*weights; + m2 = nodes.^2*weights; + m3 = nodes.^3*weights; + m4 = nodes.^4*weights; + t(2) = dassert(m1,zeros(d,1),1e-12); + t(3) = dassert(m2,ones(d,1),1e-12); + t(4) = dassert(m3,zeros(d,1),1e-12); + t(5) = dassert(m4,d*ones(d,1),1e-10); + T = all(t); end %@eof:1 @@ -142,24 +142,24 @@ Omega = diag(sqrt(1:d)); t = zeros(5,1); try - [nodes,weights] = cubature_with_gaussian_weight(d,3); - t(1) = 1; + [nodes,weights] = cubature_with_gaussian_weight(d,3); + t(1) = 1; catch - t = t(1); - T = all(t); + t = t(1); + T = all(t); end if t(1) - nodes = Omega*nodes; - m1 = nodes*weights; - m2 = nodes.^2*weights; - m3 = nodes.^3*weights; - m4 = nodes.^4*weights; - t(2) = dassert(m1,zeros(d,1),1e-12); - t(3) = dassert(m2,transpose(1:d),1e-12); - t(4) = dassert(m3,zeros(d,1),1e-12); - t(5) = dassert(m4,d*transpose(1:d).^2,1e-10); - T = all(t); + nodes = Omega*nodes; + m1 = nodes*weights; + m2 = nodes.^2*weights; + m3 = nodes.^3*weights; + m4 = nodes.^4*weights; + t(2) = dassert(m1,zeros(d,1),1e-12); + t(3) = dassert(m2,transpose(1:d),1e-12); + t(4) = dassert(m3,zeros(d,1),1e-12); + t(5) = dassert(m4,d*transpose(1:d).^2,1e-10); + T = all(t); end %@eof:2 @@ -170,21 +170,21 @@ Omega = diag(sqrt(1:d)); t = zeros(4,1); try - [nodes,weights] = cubature_with_gaussian_weight(d,3); - t(1) = 1; + [nodes,weights] = cubature_with_gaussian_weight(d,3); + t(1) = 1; catch - t = t(1); - T = all(t); + t = t(1); + T = all(t); end if t(1) - nodes = Omega*nodes; - m1 = nodes*weights; - m2 = bsxfun(@times,nodes,transpose(weights))*transpose(nodes); - t(2) = dassert(m1,zeros(d,1),1e-12); - t(3) = dassert(diag(m2),transpose(1:d),1e-12); - t(4) = dassert(m2(:),vec(diag(diag(m2))),1e-12); - T = all(t); + nodes = Omega*nodes; + m1 = nodes*weights; + m2 = bsxfun(@times,nodes,transpose(weights))*transpose(nodes); + t(2) = dassert(m1,zeros(d,1),1e-12); + t(3) = dassert(diag(m2),transpose(1:d),1e-12); + t(4) = dassert(m2(:),vec(diag(diag(m2))),1e-12); + T = all(t); end %@eof:3 @@ -196,24 +196,24 @@ Omega = chol(Sigma,'lower'); t = zeros(4,1); try - [nodes,weights] = cubature_with_gaussian_weight(d,3); - t(1) = 1; + [nodes,weights] = cubature_with_gaussian_weight(d,3); + t(1) = 1; catch - t = t(1); - T = all(t); + t = t(1); + T = all(t); end if t(1) - for i=1:length(weights) - nodes(:,i) = Omega*nodes(:,i); - end - m1 = nodes*weights; - m2 = bsxfun(@times,nodes,transpose(weights))*transpose(nodes); - m3 = nodes.^3*weights; - t(2) = dassert(m1,zeros(d,1),1e-12); - t(3) = dassert(m2(:),vec(Sigma),1e-12); - t(4) = dassert(m3,zeros(d,1),1e-12); - T = all(t); + for i=1:length(weights) + nodes(:,i) = Omega*nodes(:,i); + end + m1 = nodes*weights; + m2 = bsxfun(@times,nodes,transpose(weights))*transpose(nodes); + m3 = nodes.^3*weights; + t(2) = dassert(m1,zeros(d,1),1e-12); + t(3) = dassert(m2(:),vec(Sigma),1e-12); + t(4) = dassert(m3,zeros(d,1),1e-12); + T = all(t); end %@eof:4 @@ -222,26 +222,26 @@ d = 5; t = zeros(6,1); try - [nodes,weights] = cubature_with_gaussian_weight(d,5); - t(1) = 1; + [nodes,weights] = cubature_with_gaussian_weight(d,5); + t(1) = 1; catch - t = t(1); - T = all(t); + t = t(1); + T = all(t); end if t(1) - nodes = nodes; - m1 = nodes*weights; - m2 = nodes.^2*weights; - m3 = nodes.^3*weights; - m4 = nodes.^4*weights; - m5 = nodes.^5*weights; - t(2) = dassert(m1,zeros(d,1),1e-12); - t(3) = dassert(m2,ones(d,1),1e-12); - t(4) = dassert(m3,zeros(d,1),1e-12); - t(5) = dassert(m4,3*ones(d,1),1e-12); - t(6) = dassert(m5,zeros(d,1),1e-12); - T = all(t); + nodes = nodes; + m1 = nodes*weights; + m2 = nodes.^2*weights; + m3 = nodes.^3*weights; + m4 = nodes.^4*weights; + m5 = nodes.^5*weights; + t(2) = dassert(m1,zeros(d,1),1e-12); + t(3) = dassert(m2,ones(d,1),1e-12); + t(4) = dassert(m3,zeros(d,1),1e-12); + t(5) = dassert(m4,3*ones(d,1),1e-12); + t(6) = dassert(m5,zeros(d,1),1e-12); + T = all(t); end %@eof:5 @@ -251,20 +251,20 @@ t = zeros(4,1); % Call the tested routine try - [nodes,weights] = cubature_with_gaussian_weight(d,3,'ScaledUnscentedTransform'); - t(1) = 1; + [nodes,weights] = cubature_with_gaussian_weight(d,3,'ScaledUnscentedTransform'); + t(1) = 1; catch - t = t(1); - T = all(t); + t = t(1); + T = all(t); end if t(1) - m1 = nodes*weights; - m2 = nodes.^2*weights; - m3 = nodes.^3*weights; - t(2) = dassert(m1,zeros(d,1),1e-12); - t(3) = dassert(m2,ones(d,1),1e-12); - t(4) = dassert(m3,zeros(d,1),1e-12); - T = all(t); + m1 = nodes*weights; + m2 = nodes.^2*weights; + m3 = nodes.^3*weights; + t(2) = dassert(m1,zeros(d,1),1e-12); + t(3) = dassert(m2,ones(d,1),1e-12); + t(4) = dassert(m3,zeros(d,1),1e-12); + T = all(t); end %@eof:6 \ No newline at end of file diff --git a/matlab/datatomfile.m b/matlab/datatomfile.m index 4cff2b26a..3b50ab6b5 100644 --- a/matlab/datatomfile.m +++ b/matlab/datatomfile.m @@ -17,7 +17,7 @@ function datatomfile (s, var_list, names) % provided, all the variables as defined in M_.endo_names will be saved in % the generated m file. -% Copyright (C) 2001-2018 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -68,8 +68,7 @@ for i=1:n ivar(i) = i_tmp; end end -stack = dbstack; -fprintf(fid,'%% Dataset generated by %s.\n',stack(2).file); +fprintf(fid,'%% Dataset generated by %s.mod\n',M_.fname); fprintf(fid,['%% ' datestr(now,0) '\n']); % Save the selected data. for i = 1:n diff --git a/matlab/default_option_values.m b/matlab/default_option_values.m index 46d9afc7b..797a0df65 100644 --- a/matlab/default_option_values.m +++ b/matlab/default_option_values.m @@ -12,7 +12,7 @@ function options_ = default_option_values(M_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2018-2019 Dynare Team +% Copyright (C) 2018-2020 Dynare Team % % This file is part of Dynare. % @@ -71,6 +71,7 @@ options_.huge_number = 1e7; % Default number of threads for parallelized mex files. options_.threads.kronecker.sparse_hessian_times_B_kronecker_C = num_procs; options_.threads.local_state_space_iteration_2 = 1; +options_.threads.local_state_space_iteration_k = 1; options_.threads.perfect_foresight_problem = num_procs; options_.threads.k_order_perturbation = max(1, num_procs/2); @@ -154,7 +155,7 @@ options_.relative_irf = false; options_.ar = 5; options_.hp_filter = 0; options_.one_sided_hp_filter = 0; -options_.hp_ngrid = 512; +options_.filtered_theoretical_moments_grid = 512; options_.nodecomposition = false; options_.nomoments = false; options_.nocorr = false; @@ -651,6 +652,7 @@ options_.parameter_set = []; options_.use_shock_groups = ''; options_.shock_decomp.colormap = ''; options_.shock_decomp.init_state = 0; +options_.shock_decomp.with_epilogue = false; % Shock decomposition realtime options_.shock_decomp.forecast = 0; @@ -714,6 +716,9 @@ options_.convergence.geweke.geweke_interval=[0.2 0.5]; options_.convergence.rafterylewis.indicator=false; options_.convergence.rafterylewis.qrs=[0.025 0.005 0.95]; +%tolerance for Modified Harmonic Mean estimator +options_.marginal_data_density.harmonic_mean.tolerance = 0.01; + % Options for lmmcp solver options_.lmmcp.status = false; diff --git a/matlab/discretionary_policy.m b/matlab/discretionary_policy/discretionary_policy.m similarity index 51% rename from matlab/discretionary_policy.m rename to matlab/discretionary_policy/discretionary_policy.m index faff08ba9..b2c67403d 100644 --- a/matlab/discretionary_policy.m +++ b/matlab/discretionary_policy/discretionary_policy.m @@ -1,6 +1,18 @@ -function [info, oo_, options_] = discretionary_policy(M_, options_, oo_, var_list) +function [info, oo_, options_, M_] = discretionary_policy(M_, options_, oo_, var_list) +% function [info, oo_, options_, M_] = discretionary_policy(M_, options_, oo_, var_list) +% INPUTS +% - M_ [structure] Matlab's structure describing the model (M_). +% - options_ [structure] Matlab's structure describing the current options (options_). +% - oo_ [structure] Matlab's structure containing the results (oo_). +% - var_list [cell] list of variables +% +% OUTPUTS +% - info [integer] scalar or vector, error code. +% - oo_ [structure] Matlab's structure containing the results (oo_). +% - options_ [structure] Matlab's structure describing the current options (options_). +% - M_ [structure] Matlab's structure describing the model (M_). -% Copyright (C) 2007-2019 Dynare Team +% Copyright (C) 2007-2020 Dynare Team % % This file is part of Dynare. % @@ -17,15 +29,12 @@ function [info, oo_, options_] = discretionary_policy(M_, options_, oo_, var_lis % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -if options_.loglinear - % Ensure it's ok to ignore options_ returned from stoch_simul. #1197 - error('discretionary_policy is not compatible with `loglinear` option set to 1') -end +M_=discretionary_policy_initialization(M_,options_); origorder = options_.order; options_.discretionary_policy = 1; options_.order = 1; -[info, oo_] = stoch_simul(M_, options_, oo_, var_list); +[info, oo_, options_, M_] = stoch_simul(M_, options_, oo_, var_list); if ~options_.noprint disp_steady_state(M_,oo_) diff --git a/matlab/discretionary_policy/discretionary_policy_1.m b/matlab/discretionary_policy/discretionary_policy_1.m new file mode 100644 index 000000000..314f44272 --- /dev/null +++ b/matlab/discretionary_policy/discretionary_policy_1.m @@ -0,0 +1,125 @@ +function [dr, info, M_, options_, oo_]=discretionary_policy_1(Instruments, M_, options_, oo_) +% Higher-level function for solving discretionary optimal policy +% INPUTS +% - Instruments [cell] array containing instrument names +% - M_ [structure] Matlab's structure describing the model (M_). +% - options_ [structure] Matlab's structure describing the current options (options_). +% - oo_ [structure] Matlab's structure containing the results (oo_). +% +% OUTPUTS +% - dr [structure] Reduced form model. +% - info [integer] scalar or vector, error code. +% - M_ [structure] Matlab's structure describing the model (M_). +% - options_ [structure] Matlab's structure describing the current options (options_). +% - oo_ [structure] Matlab's structure containing the results (oo_). + +% Copyright (C) 2007-2020 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 . + +persistent Hold + +info = 0; + +dr=oo_.dr; %initialize output argument + +beta = get_optimal_policy_discount_factor(M_.params, M_.param_names); + +%call steady_state_file if present to update parameters +if options_.steadystate_flag + % explicit steady state file + [~,M_.params,info] = evaluate_steady_state_file(oo_.steady_state,[oo_.exo_steady_state; oo_.exo_det_steady_state],M_, ... + options_,false); + if info(1) + return; + end +end +[U,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; +end +if any(any(Uy~=0)) + if options_.debug + non_zero_derivs=find(any(Uy~=0)); + for ii=1:length(non_zero_derivs) + non_zero_deriv_names{ii,1} = M_.endo_names{non_zero_derivs(ii)}; + end + disp_string=[non_zero_deriv_names{1,:}]; + for ii=2:size(non_zero_deriv_names,1) + disp_string=[disp_string,', ',non_zero_deriv_names{ii,:}]; + end + fprintf('\nThe derivative of the objective function w.r.t. to variable(s) %s is not 0\n',disp_string); + end + info = 66; + return; +end + +W=reshape(W,M_.endo_nbr,M_.endo_nbr); + +klen = M_.maximum_lag + M_.maximum_lead + 1; +iyv=M_.lead_lag_incidence'; +% Find the jacobian +z = repmat(zeros(M_.endo_nbr,1),1,klen); +z = z(nonzeros(iyv)) ; +it_ = M_.maximum_lag + 1 ; + +if M_.exo_nbr == 0 + oo_.exo_steady_state = [] ; +end + +[junk,jacobia_] = feval([M_.fname '.dynamic'],z, [zeros(size(oo_.exo_simul)) ... + oo_.exo_det_simul], M_.params, zeros(M_.endo_nbr,1), it_); +if any(junk~=0) + info = 65; %the model must be written in deviation form and not have constant terms + return; +end + +Indices={'lag','contemp','lead'}; +iter=1; +for j=1:numel(Indices) + A.(Indices{j})=zeros(M_.orig_eq_nbr,M_.endo_nbr); + if strcmp(Indices{j},'contemp')||(strcmp(Indices{j},'lag') && M_.maximum_lag)||(strcmp(Indices{j},'lead') && M_.maximum_lead) + [~,row,col]=find(M_.lead_lag_incidence(iter,:)); + A.(Indices{j})(:,row)=jacobia_(:,col); + iter=iter+1; + end +end +B=jacobia_(:,nnz(iyv)+1:end); + +%%% MAIN ENGINE %%% + +if ~isempty(Hold) + [H,G,info]=discretionary_policy_engine(A.lag,A.contemp,A.lead,B,W,M_.instr_id,beta,options_.dp.maxit,options_.discretionary_tol,options_.qz_criterium,Hold); +else + [H,G,info]=discretionary_policy_engine(A.lag,A.contemp,A.lead,B,W,M_.instr_id,beta,options_.dp.maxit,options_.discretionary_tol,options_.qz_criterium); +end + +if info + return +else + Hold=H; %save previous solution + % Hold=[]; use this line if persistent command is not used. +end + +%write back solution to dr +dr.ys =zeros(M_.endo_nbr,1); +dr=set_state_space(dr,M_,options_); +T=H(dr.order_var,dr.order_var); +dr.ghu=G(dr.order_var,:); +Selection=M_.lead_lag_incidence(1,dr.order_var)>0;%select state variables +dr.ghx=T(:,Selection); +oo_.dr = dr; diff --git a/matlab/discretionary_policy_engine.m b/matlab/discretionary_policy/discretionary_policy_engine.m similarity index 100% rename from matlab/discretionary_policy_engine.m rename to matlab/discretionary_policy/discretionary_policy_engine.m diff --git a/matlab/discretionary_policy/discretionary_policy_initialization.m b/matlab/discretionary_policy/discretionary_policy_initialization.m new file mode 100644 index 000000000..2c417f440 --- /dev/null +++ b/matlab/discretionary_policy/discretionary_policy_initialization.m @@ -0,0 +1,65 @@ +function M_=discretionary_policy_initialization(M_,options_) +% function M_=discretionary_policy_initialization(M_,options_) +% INPUTS +% - M_ [structure] Matlab's structure describing the model (M_). +% - options_ [structure] Matlab's structure describing the current options (options_). +% +% OUTPUTS +% - M_ [structure] Matlab's structure describing the model (M_). + +% Copyright (C) 2020 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 . + + +if options_.loglinear + % Ensure it's ok to ignore options_ returned from stoch_simul. #1197 + error('discretionary_policy is not compatible with `loglinear` option set to 1') +end + +% safeguard against issues like running ramsey policy first and then running discretion +if isfield(M_,'orig_model') + M_.endo_nbr = M_.orig_model.endo_nbr; + M_.endo_names = M_.orig_model.endo_names; + M_.lead_lag_incidence = M_.orig_model.lead_lag_incidence; + M_.maximum_lead = M_.orig_model.maximum_lead; + M_.maximum_endo_lead = M_.orig_model.maximum_endo_lead; + M_.maximum_lag = M_.orig_model.maximum_lag; + M_.maximum_endo_lag = M_.orig_model.maximum_endo_lag; +end + +instr_nbr=M_.orig_endo_nbr-M_.orig_eq_nbr; + +if instr_nbr==0 + error('discretionary_policy:: There are no available instruments, because the model has as many equations as variables.') +end +if size(options_.instruments,1)< instr_nbr + error('discretionary_policy:: There are fewer declared instruments than omitted equations.') +elseif size(options_.instruments,1)> instr_nbr + error('discretionary_policy:: There are more declared instruments than omitted equations.') +end + +instr_id=NaN(size(options_.instruments,1),1); +for j=1:size(options_.instruments,1) + vj=deblank(options_.instruments{j}); + vj_id=strmatch(vj, M_.endo_names, 'exact'); + if ~isempty(vj_id) + instr_id(j)=vj_id; + else + error([mfilename,':: instrument ',vj,' not found']) + end +end +M_.instr_id=instr_id; diff --git a/matlab/discretionary_policy_1.m b/matlab/discretionary_policy_1.m deleted file mode 100644 index 72d87b606..000000000 --- a/matlab/discretionary_policy_1.m +++ /dev/null @@ -1,179 +0,0 @@ -function [dr,ys,info]=discretionary_policy_1(oo_,Instruments) - -% Copyright (C) 2007-2018 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 . - -global M_ options_ -persistent Hold - -dr = []; -ys = []; -info = 0; - -if isempty(options_.qz_criterium) - options_.qz_criterium = 1+1e-6; -end - -% safeguard against issues like running ramsey policy first and then running discretion -if isfield(M_,'orig_model') - orig_model = M_.orig_model; - M_.endo_nbr = orig_model.endo_nbr; - M_.endo_names = orig_model.endo_names; - M_.lead_lag_incidence = orig_model.lead_lag_incidence; - M_.maximum_lead = orig_model.maximum_lead; - M_.maximum_endo_lead = orig_model.maximum_endo_lead; - M_.maximum_lag = orig_model.maximum_lag; - M_.maximum_endo_lag = orig_model.maximum_endo_lag; -else - M_.orig_model = M_; -end - -beta = get_optimal_policy_discount_factor(M_.params, M_.param_names); - -exo_nbr = M_.exo_nbr; -if isfield(M_,'orig_model') - orig_model = M_.orig_model; - endo_nbr = orig_model.endo_nbr; - endo_names = orig_model.endo_names; - lead_lag_incidence = orig_model.lead_lag_incidence; - MaxLead = orig_model.maximum_lead; - MaxLag = orig_model.maximum_lag; -else - endo_names = M_.endo_names; - endo_nbr = M_.endo_nbr; - MaxLag=M_.maximum_lag; - MaxLead=M_.maximum_lead; - lead_lag_incidence = M_.lead_lag_incidence; -end - -%call steady_state_file if present to update parameters -if options_.steadystate_flag - % explicit steady state file - [~,M_.params,info] = evaluate_steady_state_file(oo_.steady_state,[oo_.exo_steady_state; oo_.exo_det_steady_state],M_, ... - options_,0); -end -[U,Uy,W] = feval([M_.fname,'.objective.static'],zeros(endo_nbr,1),[], M_.params); -if any(any(isnan(Uy))) - error(['discretionary_policy: the derivatives of the objective function contain NaN']) -end -if any(any(Uy~=0)) - non_zero_derivs=find(any(Uy~=0)); - for ii=1:length(non_zero_derivs) - non_zero_deriv_names{ii,1} = M_.endo_names{non_zero_derivs(ii)}; - end - disp_string=[non_zero_deriv_names{1,:}]; - for ii=2:size(non_zero_deriv_names,1) - disp_string=[disp_string,', ',non_zero_deriv_names{ii,:}]; - end - fprintf('\nThe derivative of the objective function w.r.t. to variable(s) %s is not 0\n',disp_string) - error(['discretionary_policy: the objective function must have zero ' ... - 'first order derivatives']) -end - -W=reshape(W,endo_nbr,endo_nbr); - -klen = MaxLag + MaxLead + 1; -iyv=lead_lag_incidence'; -% Find the jacobian -z = repmat(zeros(endo_nbr,1),1,klen); -z = z(nonzeros(iyv)) ; -it_ = MaxLag + 1 ; - -if exo_nbr == 0 - oo_.exo_steady_state = [] ; -end - -[junk,jacobia_] = feval([M_.fname '.dynamic'],z, [zeros(size(oo_.exo_simul)) ... - oo_.exo_det_simul], M_.params, zeros(endo_nbr,1), it_); -if any(junk~=0) - error(['discretionary_policy: the model must be written in deviation ' ... - 'form and not have constant terms']) -end - -eq_nbr= size(jacobia_,1); -instr_nbr=endo_nbr-eq_nbr; - -if instr_nbr==0 - error('discretionary_policy:: There are no available instruments, because the model has as many equations as variables.') -end -if size(Instruments,1)< instr_nbr - error('discretionary_policy:: There are fewer declared instruments than omitted equations.') -elseif size(Instruments,1)> instr_nbr - error('discretionary_policy:: There are more declared instruments than omitted equations.') -end - -instr_id=nan(instr_nbr,1); -for j=1:instr_nbr - vj=deblank(Instruments{j}); - vj_id=strmatch(vj, endo_names, 'exact'); - if ~isempty(vj_id) - instr_id(j)=vj_id; - else - error([mfilename,':: instrument ',vj,' not found']) - end -end - -Indices={'lag','0','lead'}; -iter=1; -for j=1:numel(Indices) - eval(['A',Indices{j},'=zeros(eq_nbr,endo_nbr);']) - if strcmp(Indices{j},'0')||(strcmp(Indices{j},'lag') && MaxLag)||(strcmp(Indices{j},'lead') && MaxLead) - [~,row,col]=find(lead_lag_incidence(iter,:)); - eval(['A',Indices{j},'(:,row)=jacobia_(:,col);']) - iter=iter+1; - end -end -B=jacobia_(:,nnz(iyv)+1:end); - -%%% MAIN ENGINE %%% -qz_criterium = options_.qz_criterium; -solve_maxit = options_.dp.maxit; -discretion_tol = options_.discretionary_tol; - -if ~isempty(Hold) - [H,G,info]=discretionary_policy_engine(Alag,A0,Alead,B,W,instr_id,beta,solve_maxit,discretion_tol,qz_criterium,Hold); -else - [H,G,info]=discretionary_policy_engine(Alag,A0,Alead,B,W,instr_id,beta,solve_maxit,discretion_tol,qz_criterium); -end - -if info - dr=[]; - return -else - Hold=H; %save previous solution - % Hold=[]; use this line if persistent command is not used. -end -% set the state -dr=oo_.dr; -dr.ys =zeros(endo_nbr,1); -dr=set_state_space(dr,M_,options_); -order_var=dr.order_var; - -T=H(order_var,order_var); -dr.ghu=G(order_var,:); -Selection=lead_lag_incidence(1,order_var)>0;%select state variables -dr.ghx=T(:,Selection); - -ys=NondistortionarySteadyState(M_); -dr.ys=ys; % <--- dr.ys =zeros(NewEndo_nbr,1); - -function ys=NondistortionarySteadyState(M_) -if exist([M_.fname,'_steadystate.m'],'file') - eval(['ys=',M_.fname,'_steadystate.m;']) -else - ys=zeros(M_.endo_nbr,1); -end diff --git a/matlab/disp_dr.m b/matlab/disp_dr.m index 98e8865cb..d11699222 100644 --- a/matlab/disp_dr.m +++ b/matlab/disp_dr.m @@ -29,7 +29,7 @@ function disp_dr(dr,order,var_list) global M_ options_ -if M_.hessian_eq_zero && order~=1 +if order~=1 && M_.hessian_eq_zero order = 1; warning('disp_dr: using order = 1 because Hessian is equal to zero'); end @@ -299,4 +299,4 @@ if abs(x) >= options_.dr_display_tol else str = [str sprintf(value_format_zero, 0)]; end -end \ No newline at end of file +end diff --git a/matlab/disp_identification.m b/matlab/disp_identification.m index bad140934..29142c2fa 100644 --- a/matlab/disp_identification.m +++ b/matlab/disp_identification.m @@ -21,11 +21,8 @@ function disp_identification(pdraws, ide_reducedform, ide_moments, ide_spectrum, % OUTPUTS % * all output is printed on the command line % ------------------------------------------------------------------------- -% This function is called by -% * dynare_identification.m -% ------------------------------------------------------------------------- -% This function calls -% * dynare_identification.m +% This function is called by +% * dynare_identification.m % ========================================================================= % Copyright (C) 2010-2019 Dynare Team % @@ -58,23 +55,23 @@ fprintf('Note that differences in the criteria could be due to numerical setting fprintf('numerical errors or the method used to find problematic parameter sets.\n') fprintf('Settings:\n') if options_ident.analytic_derivation_mode == 0 -fprintf(' Derivation mode for Jacobians: Analytic using sylvester equations\n'); + fprintf(' Derivation mode for Jacobians: Analytic using sylvester equations\n'); elseif options_ident.analytic_derivation_mode == 1 -fprintf(' Derivation mode for Jacobians: Analytic using kronecker products\n'); + fprintf(' Derivation mode for Jacobians: Analytic using kronecker products\n'); elseif options_ident.analytic_derivation_mode < 0 -fprintf(' Derivation mode for Jacobians: Numerical\n'); + fprintf(' Derivation mode for Jacobians: Numerical\n'); end if checks_via_subsets -fprintf(' Method to find problematic parameters: Rank condition on all possible subsets\n'); + fprintf(' Method to find problematic parameters: Rank condition on all possible subsets\n'); else -fprintf(' Method to find problematic parameters: Nullspace and multicorrelation coefficients\n'); + fprintf(' Method to find problematic parameters: Nullspace and multicorrelation coefficients\n'); end if options_ident.normalize_jacobians == 1 -fprintf(' Normalize Jacobians: Yes\n'); + fprintf(' Normalize Jacobians: Yes\n'); else -fprintf(' Normalize Jacobians: No\n'); + fprintf(' Normalize Jacobians: No\n'); end -fprintf(' Tolerance level for rank computations: %.0d\n',options_ident.tol_rank); +fprintf(' Tolerance level for rank computations: %s\n',num2str(options_ident.tol_rank)); fprintf(' Tolerance level for selecting nonzero columns: %.0d\n',options_ident.tol_deriv); fprintf(' Tolerance level for selecting nonzero singular values: %.0d\n',options_ident.tol_sv); @@ -84,52 +81,63 @@ for jide = 1:4 no_warning_message_display = 1; %% Set output strings depending on test if jide == 1 - strTest = 'REDUCED-FORM'; strJacobian = 'Tau'; strMeaning = 'reduced-form solution'; + strTest = 'REDUCED-FORM'; strJacobian = 'Tau'; strMeaning = 'Jacobian of steady state and reduced-form solution matrices'; if ~no_identification_reducedform - noidentification = 0; ide = ide_reducedform; + noidentification = 0; ide = ide_reducedform; if SampleSize == 1 - Jacob = ide.dTAU; + Jacob = ide.dREDUCEDFORM; end else %skip test noidentification = 1; no_warning_message_display = 0; end elseif jide == 2 - strTest = 'Iskrev (2010)'; strJacobian = 'J'; strMeaning = 'moments'; - if ~no_identification_moments - noidentification = 0; ide = ide_moments; + strTest = 'MINIMAL SYSTEM (Komunjer and Ng, 2011)'; strJacobian = 'Deltabar'; strMeaning = 'Jacobian of steady state and minimal system'; + if options_ident.order == 2 + strMeaning = 'Jacobian of first-order minimal system and second-order accurate mean'; + elseif options_ident.order == 3 + strMeaning = 'Jacobian of first-order minimal system and third-order accurate mean'; + end + if ~no_identification_minimal + noidentification = 0; ide = ide_minimal; if SampleSize == 1 - Jacob = ide.si_J; + Jacob = ide.dMINIMAL; end else %skip test noidentification = 1; no_warning_message_display = 0; - end + end elseif jide == 3 - strTest = 'Komunjer and NG (2011)'; strJacobian = 'D'; strMeaning = 'minimal system'; - if ~no_identification_minimal - noidentification = 0; ide = ide_minimal; + strTest = 'SPECTRUM (Qu and Tkachenko, 2012)'; strJacobian = 'Gbar'; strMeaning = 'Jacobian of mean and spectrum'; + if options_ident.order > 1 + strTest = 'SPECTRUM (Mutschler, 2015)'; + end + if ~no_identification_spectrum + noidentification = 0; ide = ide_spectrum; if SampleSize == 1 - Jacob = ide.D; + Jacob = ide.dSPECTRUM; end else %skip test noidentification = 1; no_warning_message_display = 0; end elseif jide == 4 - strTest = 'Qu and Tkachenko (2012)'; strJacobian = 'G'; strMeaning = 'spectrum'; - if ~no_identification_spectrum - noidentification = 0; ide = ide_spectrum; + strTest = 'MOMENTS (Iskrev, 2010)'; strJacobian = 'J'; strMeaning = 'Jacobian of first two moments'; + if options_ident.order > 1 + strTest = 'MOMENTS (Mutschler, 2015)'; strJacobian = 'Mbar'; + end + if ~no_identification_moments + noidentification = 0; ide = ide_moments; if SampleSize == 1 - Jacob = ide.G; + Jacob = ide.si_dMOMENTS; end else %skip test noidentification = 1; no_warning_message_display = 0; end end - + if ~noidentification %% display problematic parameters computed by identifcation_checks.m if ~checks_via_subsets if any(ide.ino) || any(any(ide.ind0==0)) || any(any(ide.jweak_pair)) - no_warning_message_display=0; + no_warning_message_display=0; skipline() disp([upper(strTest), ':']) disp(' !!!WARNING!!!'); @@ -176,8 +184,8 @@ for jide = 1:4 end end - %% display problematic parameters computed by identification_checks_via_subsets (only for debugging) - elseif checks_via_subsets + %% display problematic parameters computed by identification_checks_via_subsets + elseif checks_via_subsets if ide.rank < size(Jacob,2) no_warning_message_display = 0; skipline() @@ -191,7 +199,7 @@ for jide = 1:4 if all(cellfun(@isempty,ide.problpars)) disp([' No problematic parameter combinations with maximum dimension ', num2str(size(ide.problpars,2)), ' were found. Increase max_dim_subsets_groups.']); skipline() - else + else disp([' Displaying problematic parameter combinations (with maximum dimension ', num2str(size(ide.problpars,2)), '):']); skipline() probparamset_nbr = 0; @@ -213,11 +221,11 @@ for jide = 1:4 disp([' ',problparnamestring, ' is not identified!' ]) else disp([' [',problparnamestring, '] are collinear!' ]) - end + end end end end - end + end end end end @@ -227,7 +235,7 @@ for jide = 1:4 if no_warning_message_display skipline() disp([upper(strTest), ':']); - disp([' All parameters are identified in the ', strMeaning, ' (rank(', strJacobian, ') is full with tol = ', num2str(tol_rank), ').' ]), + disp([' All parameters are identified in the ', strMeaning, ' (rank(', strJacobian, ') is full with tol = ', num2str(tol_rank), ').' ]), end end @@ -235,8 +243,8 @@ end %% Advanced identificaton patterns if SampleSize==1 && options_ident.advanced - skipline() - for j=1:size(ide_moments.cosnJ,2) + skipline() + for j=1:size(ide_moments.cosndMOMENTS,2) pax=NaN(totparam_nbr,totparam_nbr); fprintf('\n') disp(['Collinearity patterns with ', int2str(j) ,' parameter(s)']) @@ -249,10 +257,10 @@ if SampleSize==1 && options_ident.advanced namx=[namx ' ' sprintf('%-15s','--')]; else namx=[namx ' ' sprintf('%-15s',name{dumpindx})]; - pax(i,dumpindx)=ide_moments.cosnJ(i,j); + pax(i,dumpindx)=ide_moments.cosndMOMENTS(i,j); end end - fprintf('%-15s [%s] %14.7f\n',name{i},namx,ide_moments.cosnJ(i,j)) + fprintf('%-15s [%s] %14.7f\n',name{i},namx,ide_moments.cosndMOMENTS(i,j)) end end end diff --git a/matlab/disp_moments.m b/matlab/disp_moments.m index 6ae4e4d33..8223ba4f9 100644 --- a/matlab/disp_moments.m +++ b/matlab/disp_moments.m @@ -61,8 +61,8 @@ if ~all(M_.H==0) chol_S = chol(M_.H(i_ME,i_ME)); %decompose rest shock_mat=zeros(options_.periods,size(M_.H,1)); %initialize shock_mat(:,i_ME)=randn(length(i_ME),options_.periods)'*chol_S; - y_ME = y(:,index_subset)+shock_mat(options_.drop+1:end,index_observables); - y_ME_only = shock_mat(options_.drop+1:end,index_observables); + y_ME = y(:,index_subset)+shock_mat(options_.drop+1:end,index_observables); + y_ME_only = shock_mat(options_.drop+1:end,index_observables); m_ME = mean(y_ME); y_ME=get_filtered_time_series(y_ME,m_ME,options_); y_ME_only_filtered=get_filtered_time_series(y_ME_only,mean(y_ME_only),options_); @@ -169,13 +169,13 @@ if ~options_.nodecomposition y_sim_one_shock = simult_(M_,options_,y0,oo_.dr,temp_shock_mat,options_.order); y_sim_one_shock=y_sim_one_shock(ivar,1+options_.drop+1:end)'; y_sim_one_shock=get_filtered_time_series(y_sim_one_shock,mean(y_sim_one_shock),options_); - oo_.variance_decomposition(:,i_exo_var(shock_iter))=var(y_sim_one_shock)./s2*100; + oo_.variance_decomposition(:,i_exo_var(shock_iter))=var(y_sim_one_shock)./s2*100; end if ME_present oo_.variance_decomposition_ME=oo_.variance_decomposition(index_subset,:)... .*repmat((s2(index_subset)./s2_ME)',1,length(i_exo_var)); oo_.variance_decomposition_ME(:,end+1)=var(y_ME_only_filtered)./s2_ME*100; - end + end if ~options_.noprint %options_.nomoments == 0 skipline() title='VARIANCE DECOMPOSITION SIMULATING ONE SHOCK AT A TIME (in percent)'; @@ -201,9 +201,9 @@ if ~options_.nodecomposition if ME_present headers_ME = vertcat(headers, 'ME'); dyn_latex_table(M_, options_, [title, ' WITH MEASUREMENT ERROR'], 'sim_var_decomp_ME', ... - vertcat(headers_ME, 'Tot. lin. contr.'), ... - labels_TeX(ivar(index_subset)), ... - [oo_.variance_decomposition_ME sum(oo_.variance_decomposition_ME, 2)], lh, 8, 2); + vertcat(headers_ME, 'Tot. lin. contr.'), ... + labels_TeX(ivar(index_subset)), ... + [oo_.variance_decomposition_ME sum(oo_.variance_decomposition_ME, 2)], lh, 8, 2); end end diff --git a/matlab/disp_th_moments.m b/matlab/disp_th_moments.m index 7441330cd..33fdb7100 100644 --- a/matlab/disp_th_moments.m +++ b/matlab/disp_th_moments.m @@ -64,7 +64,7 @@ if ~all(M_.H==0) ME_present=1; end end - + if size(stationary_vars, 1) > 0 if ~nodecomposition oo_.variance_decomposition=100*oo_.gamma_y{options_.ar+2}; @@ -145,8 +145,8 @@ if size(stationary_vars, 1) > 0 display_conditional_variance_decomposition(oo_.conditional_variance_decomposition, conditional_variance_steps, ivar, M_, options_); if ME_present display_conditional_variance_decomposition(oo_.conditional_variance_decomposition_ME, conditional_variance_steps, ... - observable_pos_requested_vars, M_, options_); - end + observable_pos_requested_vars, M_, options_); + end end end end @@ -161,7 +161,7 @@ end if ~options_.nocorr && size(stationary_vars, 1)>0 corr = NaN(size(oo_.gamma_y{1})); corr(i1,i1) = oo_.gamma_y{1}(i1,i1)./(sd(i1)*sd(i1)'); - if options_.contemporaneous_correlation + if options_.contemporaneous_correlation oo_.contemporaneous_correlation = corr; end if ~options_.noprint diff --git a/matlab/display_conditional_variance_decomposition.m b/matlab/display_conditional_variance_decomposition.m index 8cee73dc5..300320109 100644 --- a/matlab/display_conditional_variance_decomposition.m +++ b/matlab/display_conditional_variance_decomposition.m @@ -68,7 +68,7 @@ if options_.TeX labels_TeX = M_.endo_names_tex(SubsetOfVariables); lh = cellofchararraymaxlength(labels_TeX)+2; end - + vardec_i = zeros(length(SubsetOfVariables), shock_number); for i=1:length(Steps) diff --git a/matlab/display_problematic_vars_Jacobian.m b/matlab/display_problematic_vars_Jacobian.m index 2eca7173b..7d828885a 100644 --- a/matlab/display_problematic_vars_Jacobian.m +++ b/matlab/display_problematic_vars_Jacobian.m @@ -94,7 +94,7 @@ if strcmp(type,'dynamic') eq_nbr, type_string, M_.exo_names{var_index}); else eq_nbr = problemrow(ii)-aux_eq_nbr; - fprintf('Derivative of Equation %d with respect to %s shock %s \n', ... + fprintf('Derivative of Equation %d with respect to %s shock %s \n', ... eq_nbr, type_string, M_.exo_names{var_index}); end else @@ -111,10 +111,10 @@ elseif strcmp(type, 'static') if problemrow(ii)<=aux_eq_nbr eq_nbr = problemrow(ii); fprintf('Derivative of Auxiliary Equation %d with respect to Variable %s (initial value of %s: %g) \n', ... - eq_nbr, M_.endo_names{problemcol(ii)}, M_.endo_names{problemcol(ii)}, x(problemcol(ii))); + eq_nbr, M_.endo_names{problemcol(ii)}, M_.endo_names{problemcol(ii)}, x(problemcol(ii))); else eq_nbr = problemrow(ii)-aux_eq_nbr; - fprintf('Derivative of Equation %d with respect to Variable %s (initial value of %s: %g) \n', ... + fprintf('Derivative of Equation %d with respect to Variable %s (initial value of %s: %g) \n', ... eq_nbr, M_.endo_names{problemcol(ii)}, M_.endo_names{problemcol(ii)}, x(problemcol(ii))); end else %auxiliary vars diff --git a/matlab/dr_block.m b/matlab/dr_block.m index 0328c1048..d65248b77 100644 --- a/matlab/dr_block.m +++ b/matlab/dr_block.m @@ -34,7 +34,7 @@ function [dr,info,M_,options_,oo_] = dr_block(dr,task,M_,options_,oo_,varargin) % none. % -% Copyright (C) 2010-2017 Dynare Team +% Copyright (C) 2010-2020 Dynare Team % % This file is part of Dynare. % @@ -71,12 +71,10 @@ else Size = 1; end if (options_.bytecode) - [chck, zz, data]= bytecode('dynamic','evaluate', z, zx, M_.params, dr.ys, 1, data); + [zz, data]= bytecode('dynamic','evaluate', z, zx, M_.params, dr.ys, 1, data); else [r, data] = feval([M_.fname '.dynamic'], options_, M_, oo_, z', zx, M_.params, dr.ys, M_.maximum_lag+1, data); - chck = 0; end -mexErrCheck('bytecode', chck); dr.full_rank = 1; dr.eigval = []; dr.nd = 0; @@ -440,7 +438,7 @@ for i = 1:Size D = [[aa(row_indx,index_0m) zeros(n_dynamic,n_both) aa(row_indx,index_p)] ; [zeros(n_both, n_pred) eye(n_both) zeros(n_both, n_both + n_fwrd)]]; E = [-aa(row_indx,[index_m index_0p]) ; [zeros(n_both, n_both + n_pred) eye(n_both, n_both + n_fwrd) ] ]; - [err, ss, tt, w, sdim, data(i).eigval, info1] = mjdgges(E,D,options_.qz_criterium,options_.qz_zero_threshold); + [ss, tt, w, sdim, data(i).eigval, info1] = mjdgges(E,D,options_.qz_criterium,options_.qz_zero_threshold); if (verbose) disp('eigval'); @@ -591,7 +589,7 @@ for i = 1:Size elseif options_.sylvester_fp ghx_other = gensylv_fp(A_, B_, C_, D_, i, options_.sylvester_fixed_point_tol); else - [err, ghx_other] = gensylv(1, A_, B_, C_, -D_); + ghx_other = gensylv(1, A_, B_, C_, -D_); end if options_.aim_solver ~= 1 % Necessary when using Sims' routines for QZ diff --git a/matlab/dsge_likelihood.m b/matlab/dsge_likelihood.m index 0c67c6598..7b568277c 100644 --- a/matlab/dsge_likelihood.m +++ b/matlab/dsge_likelihood.m @@ -111,11 +111,11 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,Model,DynareOpti %! @sp 2 %! @strong{This function calls:} %! @sp 1 -%! @ref{dynare_resolve}, @ref{lyapunov_symm}, @ref{lyapunov_solver}, @ref{compute_Pinf_Pstar}, @ref{kalman_filter_d}, @ref{missing_observations_kalman_filter_d}, @ref{univariate_kalman_filter_d}, @ref{kalman_steady_state}, @ref{get_first_order_solution_params_deriv}, @ref{kalman_filter}, @ref{score}, @ref{AHessian}, @ref{missing_observations_kalman_filter}, @ref{univariate_kalman_filter}, @ref{priordens} +%! @ref{dynare_resolve}, @ref{lyapunov_symm}, @ref{lyapunov_solver}, @ref{compute_Pinf_Pstar}, @ref{kalman_filter_d}, @ref{missing_observations_kalman_filter_d}, @ref{univariate_kalman_filter_d}, @ref{kalman_steady_state}, @ref{get_perturbation_params_deriv}, @ref{kalman_filter}, @ref{score}, @ref{AHessian}, @ref{missing_observations_kalman_filter}, @ref{univariate_kalman_filter}, @ref{priordens} %! @end deftypefn %@eod: -% Copyright (C) 2004-2019 Dynare Team +% Copyright (C) 2004-2020 Dynare Team % % This file is part of Dynare. % @@ -150,7 +150,9 @@ if DynareOptions.estimation_dll [fval,exit_flag,SteadyState,trend_coeff,info,params,H,Q] ... = logposterior(xparam1,DynareDataset, DynareOptions,Model, ... EstimatedParameters,BayesInfo,DynareResults); - mexErrCheck('logposterior', exit_flag); + if exit_flag + error('Error encountered in logposterior') + end Model.params = params; if ~isequal(Model.H,0) Model.H = H; @@ -455,12 +457,14 @@ switch DynareOptions.lik_init if kalman_algo ~= 2 kalman_algo = 1; end - if isequal(H,0) - [err,Pstar] = kalman_steady_state(transpose(T),R*Q*transpose(R),transpose(build_selection_matrix(Z,mm,length(Z)))); - else - [err,Pstar] = kalman_steady_state(transpose(T),R*Q*transpose(R),transpose(build_selection_matrix(Z,mm,length(Z))),H); - end - if err + try + if isequal(H,0) + Pstar = kalman_steady_state(transpose(T),R*Q*transpose(R),transpose(build_selection_matrix(Z,mm,length(Z)))); + else + Pstar = kalman_steady_state(transpose(T),R*Q*transpose(R),transpose(build_selection_matrix(Z,mm,length(Z))),H); + end + catch ME + disp(ME.message) disp(['dsge_likelihood:: I am not able to solve the Riccati equation, so I switch to lik_init=1!']); DynareOptions.lik_init = 1; Pstar=lyapunov_solver(T,R,Q,DynareOptions); @@ -522,11 +526,29 @@ if analytic_derivation else indparam=[]; end - if full_Hess - [DT, ~, ~, DOm, DYss, ~, D2T, D2Om, D2Yss] = get_first_order_solution_params_deriv(A, B, EstimatedParameters, Model,DynareResults,DynareOptions,kron_flag,indparam,indexo,[],iv); - else - [DT, ~, ~, DOm, DYss] = get_first_order_solution_params_deriv(A, B, EstimatedParameters, Model,DynareResults,DynareOptions,kron_flag,indparam,indexo,[],iv); + old_order = DynareOptions.order; + if DynareOptions.order > 1%not sure whether this check is necessary + DynareOptions.order = 1; fprintf('Reset order to 1 for analytical parameter derivatives.\n'); end + old_analytic_derivation_mode = DynareOptions.analytic_derivation_mode; + DynareOptions.analytic_derivation_mode = kron_flag; + if full_Hess + DERIVS = get_perturbation_params_derivs(Model, DynareOptions, EstimatedParameters, DynareResults, indparam, indexo, [], true); + indD2T = reshape(1:Model.endo_nbr^2, Model.endo_nbr, Model.endo_nbr); + indD2Om = dyn_unvech(1:Model.endo_nbr*(Model.endo_nbr+1)/2); + D2T = DERIVS.d2KalmanA(indD2T(iv,iv),:); + D2Om = DERIVS.d2Om(dyn_vech(indD2Om(iv,iv)),:); + D2Yss = DERIVS.d2Yss(iv,:,:); + else + DERIVS = get_perturbation_params_derivs(Model, DynareOptions, EstimatedParameters, DynareResults, indparam, indexo, [], false); + end + DT = zeros(Model.endo_nbr, Model.endo_nbr, size(DERIVS.dghx,3)); + DT(:,Model.nstatic+(1:Model.nspred),:) = DERIVS.dghx; + DT = DT(iv,iv,:); + DOm = DERIVS.dOm(iv,iv,:); + DYss = DERIVS.dYss(iv,:); + DynareOptions.order = old_order; %make sure order is reset (not sure if necessary) + DynareOptions.analytic_derivation_mode = old_analytic_derivation_mode;%make sure analytic_derivation_mode is reset (not sure if necessary) else DT = derivatives_info.DT(iv,iv,:); DOm = derivatives_info.DOm(iv,iv,:); @@ -629,8 +651,7 @@ singularity_has_been_detected = false; if ((kalman_algo==1) || (kalman_algo==3))% Multivariate Kalman Filter if no_missing_data_flag if DynareOptions.block - [err, LIK] = block_kalman_filter(T,R,Q,H,Pstar,Y,start,Z,kalman_tol,riccati_tol, Model.nz_state_var, Model.n_diag, Model.nobs_non_statevar); - mexErrCheck('block_kalman_filter', err); + LIK = block_kalman_filter(T,R,Q,H,Pstar,Y,start,Z,kalman_tol,riccati_tol, Model.nz_state_var, Model.n_diag, Model.nobs_non_statevar); elseif DynareOptions.fast_kalman_filter if diffuse_periods %kalman_algo==3 requires no diffuse periods (stationary @@ -659,8 +680,8 @@ if ((kalman_algo==1) || (kalman_algo==3))% Multivariate Kalman Filter end else if 0 %DynareOptions.block - [err, LIK,lik] = block_kalman_filter(DatasetInfo.missing.aindex,DatasetInfo.missing.number_of_observations,DatasetInfo.missing.no_more_missing_observations,... - T,R,Q,H,Pstar,Y,start,Z,kalman_tol,riccati_tol, Model.nz_state_var, Model.n_diag, Model.nobs_non_statevar); + [LIK,lik] = block_kalman_filter(DatasetInfo.missing.aindex,DatasetInfo.missing.number_of_observations,DatasetInfo.missing.no_more_missing_observations,... + T,R,Q,H,Pstar,Y,start,Z,kalman_tol,riccati_tol, Model.nz_state_var, Model.n_diag, Model.nobs_non_statevar); else [LIK,lik] = missing_observations_kalman_filter(DatasetInfo.missing.aindex,DatasetInfo.missing.number_of_observations,DatasetInfo.missing.no_more_missing_observations,Y,diffuse_periods+1,size(Y,2), ... a, Pstar, ... diff --git a/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m b/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m index 21aa0e032..540b2e239 100644 --- a/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m +++ b/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m @@ -19,7 +19,7 @@ function [nvar,vartan,NumberOfConditionalDecompFiles] = ... % vartan [char] array of characters (with nvar rows). % NumberOfConditionalDecompFiles [integer] scalar, number of prior or posterior data files (for covariance). -% Copyright (C) 2009-2015 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -39,10 +39,10 @@ function [nvar,vartan,NumberOfConditionalDecompFiles] = ... % Get informations about the _posterior_draws files. if strcmpi(type,'posterior') - DrawsFiles = dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ])); posterior = 1; elseif strcmpi(type,'prior') - DrawsFiles = dir([M_.dname '/prior/draws/' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/prior/draws/' type '_draws*' ])); CheckPath('prior/moments',M_.dname); posterior = 0; else @@ -78,7 +78,6 @@ nvar = length(ivar); nar = options_.ar; options_.ar = 0; -NumberOfDrawsFiles = rows(DrawsFiles); NumberOfSavedElementsPerSimulation = nvar*M_.exo_nbr*length(Steps); MaXNumberOfConditionalDecompLines = ceil(options_.MaxNumberOfBytes/NumberOfSavedElementsPerSimulation/8); @@ -114,7 +113,7 @@ if ME_present Conditional_decomposition_array_ME = zeros(nobs_ME,length(Steps),M_.exo_nbr+1,SampleSize); NumberOfLinesInTheLastConditionalDecompFile_ME = mod(SampleSize,MaXNumberOfConditionalDecompLines_ME); NumberOfConditionalDecompFiles_ME = ceil(SampleSize/MaXNumberOfConditionalDecompLines_ME); - end + end NumberOfConditionalDecompLines_ME = size(Conditional_decomposition_array_ME,4); ConditionalDecompFileNumber_ME = 0; end @@ -132,9 +131,9 @@ linea = 0; linea_ME = 0; for file = 1:NumberOfDrawsFiles if posterior - load([M_.dname '/metropolis/' DrawsFiles(file).name ]); + load([M_.dname '/metropolis/' M_.fname '_' type '_draws' num2str(file) ]); else - load([M_.dname '/prior/draws/' DrawsFiles(file).name ]); + load([M_.dname '/prior/draws/' type '_draws' num2str(file) ]); end isdrsaved = columns(pdraws)-1; NumberOfDraws = rows(pdraws); @@ -197,10 +196,10 @@ for file = 1:NumberOfDrawsFiles linea_ME = 0; if posterior save([M_.dname '/metropolis/' M_.fname '_PosteriorConditionalVarianceDecompME' int2str(ConditionalDecompFileNumber_ME) '.mat' ], ... - 'Conditional_decomposition_array_ME'); + 'Conditional_decomposition_array_ME'); else save([M_.dname '/prior/moments/' M_.fname '_PriorConditionalVarianceDecompME' int2str(ConditionalDecompFileNumber_ME) '.mat' ], ... - 'Conditional_decomposition_array_ME'); + 'Conditional_decomposition_array_ME'); end if (ConditionalDecompFileNumber_ME==NumberOfConditionalDecompFiles_ME-1)% Prepare last round. Conditional_decomposition_array_ME = zeros(nobs_ME, length(Steps),M_.exo_nbr+1,NumberOfLinesInTheLastConditionalDecompFile_ME) ; diff --git a/matlab/dsge_simulated_theoretical_correlation.m b/matlab/dsge_simulated_theoretical_correlation.m index 7bc6239c5..fb00d5ddc 100644 --- a/matlab/dsge_simulated_theoretical_correlation.m +++ b/matlab/dsge_simulated_theoretical_correlation.m @@ -17,7 +17,7 @@ function [nvar,vartan,CorrFileNumber] = dsge_simulated_theoretical_correlation(S % vartan [char] array of characters (with nvar rows). % CorrFileNumber [integer] scalar, number of prior or posterior data files (for correlation). -% Copyright (C) 2007-2017 Dynare Team +% Copyright (C) 2007-2020 Dynare Team % % This file is part of Dynare. % @@ -38,17 +38,16 @@ nodecomposition = 1; % Get informations about the _posterior_draws files. if strcmpi(type,'posterior') - DrawsFiles = dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ])); posterior = 1; elseif strcmpi(type,'prior') - DrawsFiles = dir([M_.dname '/prior/draws/' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/prior/draws/' type '_draws*' ])); CheckPath('prior/moments',M_.dname); posterior = 0; else disp('dsge_simulated_theoretical_correlation:: Unknown type!'); error() end -NumberOfDrawsFiles = length(DrawsFiles); %delete old stale files before creating new ones if posterior @@ -95,9 +94,9 @@ CorrFileNumber = 1; linea = 0; for file = 1:NumberOfDrawsFiles if posterior - load([M_.dname '/metropolis/' DrawsFiles(file).name ]); + load([M_.dname '/metropolis/' M_.fname '_' type '_draws' num2str(file) ]); else - load([M_.dname '/prior/draws/' DrawsFiles(file).name]); + load([M_.dname '/prior/draws/' type '_draws' num2str(file) ]); end NumberOfDraws = rows(pdraws); isdrsaved = columns(pdraws)-1; @@ -136,4 +135,4 @@ for file = 1:NumberOfDrawsFiles end end -options_.ar = oldnar; \ No newline at end of file +options_.ar = oldnar; diff --git a/matlab/dsge_simulated_theoretical_covariance.m b/matlab/dsge_simulated_theoretical_covariance.m index e5dfd58e8..0be948bc3 100644 --- a/matlab/dsge_simulated_theoretical_covariance.m +++ b/matlab/dsge_simulated_theoretical_covariance.m @@ -16,7 +16,7 @@ function [nvar,vartan,CovarFileNumber] = dsge_simulated_theoretical_covariance(S % vartan [char] array of characters (with nvar rows). % CovarFileNumber [integer] scalar, number of prior or posterior data files (for covariance). -% Copyright (C) 2007-2017 Dynare Team +% Copyright (C) 2007-2020 Dynare Team % % This file is part of Dynare. % @@ -37,17 +37,16 @@ nodecomposition = 1; % Get informations about the _posterior_draws files. if strcmpi(type,'posterior') - DrawsFiles = dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ])); posterior = 1; elseif strcmpi(type,'prior') - DrawsFiles = dir([M_.dname '/prior/draws/' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/prior/draws/' type '_draws*' ])); CheckPath('prior/moments',M_.dname); posterior = 0; else disp('dsge_simulated_theoretical_covariance:: Unknown type!') error(); end -NumberOfDrawsFiles = length(DrawsFiles); %delete old stale files before creating new ones if posterior @@ -94,9 +93,9 @@ CovarFileNumber = 1; linea = 0; for file = 1:NumberOfDrawsFiles if posterior - load([M_.dname '/metropolis/' DrawsFiles(file).name ],'pdraws'); + load([M_.dname '/metropolis/' M_.fname '_' type '_draws' num2str(file) ]); else - load([M_.dname '/prior/draws/' DrawsFiles(file).name ],'pdraws'); + load([M_.dname '/prior/draws/' type '_draws' num2str(file) ]); end NumberOfDraws = rows(pdraws); isdrsaved = columns(pdraws)-1; @@ -136,4 +135,4 @@ for file = 1:NumberOfDrawsFiles end end -options_.ar = nar; \ No newline at end of file +options_.ar = nar; diff --git a/matlab/dsge_simulated_theoretical_variance_decomposition.m b/matlab/dsge_simulated_theoretical_variance_decomposition.m index 0037ec427..7e6942c19 100644 --- a/matlab/dsge_simulated_theoretical_variance_decomposition.m +++ b/matlab/dsge_simulated_theoretical_variance_decomposition.m @@ -18,7 +18,7 @@ function [nvar,vartan,NumberOfDecompFiles] = ... % vartan [char] array of characters (with nvar rows). % CovarFileNumber [integer] scalar, number of prior or posterior data files (for covariance). -% Copyright (C) 2007-2017 Dynare Team +% Copyright (C) 2007-2020 Dynare Team % % This file is part of Dynare. % @@ -39,10 +39,10 @@ nodecomposition = 0; % Get informations about the _posterior_draws files. if strcmpi(type,'posterior') - DrawsFiles = dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/metropolis/' M_.fname '_' type '_draws*' ])); posterior = 1; elseif strcmpi(type,'prior') - DrawsFiles = dir([M_.dname '/prior/draws/' type '_draws*' ]); + NumberOfDrawsFiles = length(dir([M_.dname '/prior/draws/' type '_draws*' ])); CheckPath('prior/moments',M_.dname); posterior = 0; else @@ -81,7 +81,6 @@ options_.ar = 0; nexo = M_.exo_nbr; -NumberOfDrawsFiles = rows(DrawsFiles); NumberOfSavedElementsPerSimulation = nvar*(nexo+1); MaXNumberOfDecompLines = ceil(options_.MaxNumberOfBytes/NumberOfSavedElementsPerSimulation/8); @@ -131,9 +130,9 @@ linea_ME = 0; only_non_stationary_vars=0; for file = 1:NumberOfDrawsFiles if posterior - load([M_.dname '/metropolis/' DrawsFiles(file).name ]); + load([M_.dname '/metropolis/' M_.fname '_' type '_draws' num2str(file) ]); else - load([M_.dname '/prior/draws/' DrawsFiles(file).name ]); + load([M_.dname '/prior/draws/' type '_draws' num2str(file) ]); end isdrsaved = columns(pdraws)-1; NumberOfDraws = rows(pdraws); @@ -156,7 +155,7 @@ for file = 1:NumberOfDrawsFiles end end if only_non_stationary_vars - Decomposition_array(linea,:) = NaN; + Decomposition_array(linea,:) = NaN; else tmp = th_autocovariances(dr,ivar,M_,options_,nodecomposition); for i=1:nvar diff --git a/matlab/duplication.m b/matlab/duplication.m index ca086e7ab..324154168 100644 --- a/matlab/duplication.m +++ b/matlab/duplication.m @@ -10,7 +10,7 @@ function [Dp,DpMPinv] = duplication(p) % Dp: Duplication matrix % DpMPinv: Moore-Penroze inverse of Dp % ------------------------------------------------------------------------- -% This function is called by +% This function is called by % * get_identification_jacobians.m (previously getJJ.m) % ========================================================================= % Copyright (C) 1997 Tom Minka @@ -43,7 +43,7 @@ j = a(:); m = p*(p+1)/2; Dp = spalloc(p*p,m,p^2); for r = 1:size(Dp,1) - Dp(r, j(r)) = 1; + Dp(r, j(r)) = 1; end if nargout > 1 diff --git a/matlab/dyn_first_order_solver.m b/matlab/dyn_first_order_solver.m index 63cb4f9da..101a33700 100644 --- a/matlab/dyn_first_order_solver.m +++ b/matlab/dyn_first_order_solver.m @@ -21,7 +21,7 @@ function [dr, info] = dyn_first_order_solver(jacobia, DynareModel, dr, DynareOpt % info=5 -> Blanchard and Kahn conditions are not satisfied: indeterminacy due to rank failure, % info=7 -> One of the eigenvalues is close to 0/0 (infinity of complex solutions) -% Copyright (C) 2001-2018 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -187,8 +187,7 @@ else E(row_indx_de_1,index_e1) = -aa(row_indx,index_e); E(row_indx_de_2,index_e2) = eye(nboth); - [err, ss, tt, w, sdim, dr.eigval, info1] = mjdgges(E, D, DynareOptions.qz_criterium, DynareOptions.qz_zero_threshold); - mexErrCheck('mjdgges', err); + [ss, tt, w, sdim, dr.eigval, info1] = mjdgges(E, D, DynareOptions.qz_criterium, DynareOptions.qz_zero_threshold); if info1 if info1 == -30 diff --git a/matlab/dyn_latex_table.m b/matlab/dyn_latex_table.m index 10acf1b68..d55a2c7dc 100644 --- a/matlab/dyn_latex_table.m +++ b/matlab/dyn_latex_table.m @@ -1,7 +1,7 @@ function dyn_latex_table(M_, options_, title, LaTeXtitle, headers, labels, values, label_width, val_width, val_precis, optional_header) %function dyn_latex_table(M_, options_, title, LaTeXtitle, headers, labels, values, label_width, val_width, val_precis, optional_header) -% Copyright (C) 2015-2019 Dynare Team +% Copyright (C) 2015-2020 Dynare Team % % This file is part of Dynare. % @@ -42,7 +42,7 @@ if all(~isfinite(values)) else values_length = max(ceil(max(max(log10(abs(values(isfinite(values))))))),1)+val_precis+1; end -if any(values) < 0 %add one character for minus sign +if any(values < 0) %add one character for minus sign values_length = values_length+1; end headers_length = cellofchararraymaxlength(headers(2:end)); diff --git a/matlab/dyn_ramsey_static.m b/matlab/dyn_ramsey_static.m index e94deb504..029528592 100644 --- a/matlab/dyn_ramsey_static.m +++ b/matlab/dyn_ramsey_static.m @@ -18,7 +18,7 @@ function [steady_state,params,check] = dyn_ramsey_static(ys_init,M,options_,oo) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2003-2018 Dynare Team +% Copyright (C) 2003-2020 Dynare Team % % This file is part of Dynare. % @@ -121,10 +121,15 @@ if options_.steadystate_flag oo.exo_det_steady_state], ... M,options_,~options_.steadystate.nocheck); if any(imag(x(1:M.orig_endo_nbr))) %return with penalty - resids=1+sum(abs(imag(x(1:M.orig_endo_nbr)))); %return with penalty + resids=ones(inst_nbr,1)+sum(abs(imag(x(1:M.orig_endo_nbr)))); %return with penalty steady_state=NaN(endo_nbr,1); return end + if check %return + resids=ones(inst_nbr,1)+sum(abs(x(1:M.orig_endo_nbr))); %return with penalty + steady_state=NaN(endo_nbr,1); + return + end end @@ -156,8 +161,8 @@ Uyy = reshape(Uyy,endo_nbr,endo_nbr); % set multipliers and auxiliary variables that % depends on multipliers to 0 to compute residuals if (options_.bytecode) - [chck, res, junk] = bytecode('static',xx,[oo.exo_steady_state oo.exo_det_steady_state], ... - params, 'evaluate'); + [res, junk] = bytecode('static',xx,[oo.exo_steady_state oo.exo_det_steady_state], ... + params, 'evaluate'); fJ = junk.g1; else [res,fJ] = feval([fname '.static'],xx,[oo.exo_steady_state oo.exo_det_steady_state], ... @@ -194,8 +199,8 @@ end function result = check_static_model(ys,M,options_,oo) result = false; if (options_.bytecode) - [chck, res, ~] = bytecode('static',ys,[oo.exo_steady_state oo.exo_det_steady_state], ... - M.params, 'evaluate'); + [res, ~] = bytecode('static',ys,[oo.exo_steady_state oo.exo_det_steady_state], ... + M.params, 'evaluate'); else res = feval([M.fname '.static'],ys,[oo.exo_steady_state oo.exo_det_steady_state], ... M.params); diff --git a/matlab/dyn_risky_steadystate_solver.m b/matlab/dyn_risky_steadystate_solver.m index d8fe2ede1..93c75da4d 100644 --- a/matlab/dyn_risky_steadystate_solver.m +++ b/matlab/dyn_risky_steadystate_solver.m @@ -341,8 +341,7 @@ if nargout > 1 nu2 = exo_nbr*(exo_nbr+1)/2; nu3 = exo_nbr*(exo_nbr+1)*(exo_nbr+2)/3; M_np.NZZDerivatives = [nnz(d1_np); nnz(d2_np); nnz(d3_np)]; - [err, dynpp_derivs] = k_order_perturbation(dr_np,M_np,options,d1_np,d2_np,d3_np); - mexErrCheck('k_order_perturbation', err); + dynpp_derivs = k_order_perturbation(dr_np,M_np,options,d1_np,d2_np,d3_np); g_0 = dynpp_derivs.g_0; g_1 = dynpp_derivs.g_1; g_2 = dynpp_derivs.g_2; diff --git a/matlab/dyn_second_order_solver.m b/matlab/dyn_second_order_solver.m index 9e4dc6bab..bd5c37a9f 100644 --- a/matlab/dyn_second_order_solver.m +++ b/matlab/dyn_second_order_solver.m @@ -8,7 +8,7 @@ function dr = dyn_second_order_solver(jacobia,hessian_mat,dr,M,threads_BC) %! * Juillard and Kamenik (2004): Solving Stochastic Dynamic Equilibrium Models: A k-Order Perturbation Approach %! * Kamenik (2005) - Solving SDGE Models: A New Algorithm for the Sylvester Equation %! Note that this function makes use of the fact that Dynare internally transforms the model -%! so that there is only one lead and one lag on endogenous variables and, in the case of a stochastic model, +%! so that there is only one lead and one lag on endogenous variables and, in the case of a stochastic model, %! no leads/lags on exogenous variables. See the manual for more details. % Auxiliary variables %! @sp 2 @@ -36,7 +36,7 @@ function dr = dyn_second_order_solver(jacobia,hessian_mat,dr,M,threads_BC) %! @end deftypefn %@eod: -% Copyright (C) 2001-2019 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -85,29 +85,23 @@ zu = [zeros(length(ic),M.exo_nbr); dr.ghx(klead~=0,:)*dr.ghu(ic,:); eye(M.exo_nbr); zeros(M.exo_det_nbr,M.exo_nbr)]; -[rhs, err] = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(kk1,kk1)),zx,threads_BC); %hessian_mat: reordering to DR order -mexErrCheck('sparse_hessian_times_B_kronecker_C', err); +rhs = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(kk1,kk1)),zx,threads_BC); %hessian_mat: reordering to DR order rhs = -rhs; -[err, dr.ghxx] = gensylv(2,A,B,C,rhs); -mexErrCheck('gensylv', err); +dr.ghxx = gensylv(2,A,B,C,rhs); %% ghxu %rhs -[rhs, err] = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(kk1,kk1)),zx,zu,threads_BC); %hessian_mat: reordering to DR order -mexErrCheck('sparse_hessian_times_B_kronecker_C', err); -[abcOut,err] = A_times_B_kronecker_C(dr.ghxx, dr.ghx(ic,:), dr.ghu(ic,:)); -mexErrCheck('A_times_B_kronecker_C', err); +rhs = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(kk1,kk1)),zx,zu,threads_BC); %hessian_mat: reordering to DR order +abcOut = A_times_B_kronecker_C(dr.ghxx, dr.ghx(ic,:), dr.ghu(ic,:)); rhs = -rhs-B*abcOut; %lhs dr.ghxu = A\rhs; %% ghuu %rhs -[rhs, err] = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(kk1,kk1)),zu,threads_BC); %hessian_mat: reordering to DR order -mexErrCheck('sparse_hessian_times_B_kronecker_C', err); -[B1, err] = A_times_B_kronecker_C(B*dr.ghxx,dr.ghu(ic,:)); -mexErrCheck('A_times_B_kronecker_C', err); +rhs = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(kk1,kk1)),zu,threads_BC); %hessian_mat: reordering to DR order +B1 = A_times_B_kronecker_C(B*dr.ghxx,dr.ghu(ic,:)); rhs = -rhs-B1; %lhs dr.ghuu = A\rhs; @@ -120,8 +114,7 @@ LHS = zeros(M.endo_nbr,M.endo_nbr); LHS(:,kcurr~=0) = jacobia(:,nonzeros(kcurr)); RHS = zeros(M.endo_nbr,M.exo_nbr^2); E = eye(M.endo_nbr); -[B1, err] = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(nonzeros(klead),nonzeros(klead))), dr.ghu(klead~=0,:),threads_BC); %hessian_mat:focus only on forward variables and reorder to DR order -mexErrCheck('sparse_hessian_times_B_kronecker_C', err); +B1 = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kk2(nonzeros(klead),nonzeros(klead))), dr.ghu(klead~=0,:),threads_BC); %hessian_mat:focus only on forward variables and reorder to DR order RHS = RHS + jacobia(:,nonzeros(klead))*dr.ghuu(klead~=0,:)+B1; % LHS LHS = LHS + jacobia(:,nonzeros(klead))*(E(klead~=0,:)+[O1(klead~=0,:) dr.ghx(klead~=0,:) O2(klead~=0,:)]); diff --git a/matlab/dynare.m b/matlab/dynare.m index 3fe549a34..32ea530d9 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -16,7 +16,7 @@ function dynare(fname, varargin) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2019 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -45,28 +45,26 @@ if ~nargin || strcmpi(fname,'help') return end -% Set default local options -change_path_flag = true; +% The following needs to come early, to avoid spurious warnings (especially under Octave) +warning_config; -% Filter out some options. -preprocessoroutput = true; +% Handle nopathchange option +% Note that it is only handled if it appears on the command-line, and not at +% the top of the .mod file (since the treatment needs to take place very early, +% even before we make the various checks on the filename) +change_path_flag = true; if nargin>1 id = ismember(varargin, 'nopathchange'); if any(id) change_path_flag = false; varargin(id) = []; end - preprocessoroutput = ~ismember('nopreprocessoroutput', varargin); end - -% Check matlab path check_matlab_path(change_path_flag); % Detect if MEX files are present; if not, use alternative M-files dynareroot = dynare_config(); -warning_config() - if isoctave % The supported_octave_version.m file is not in git nor in the source % package, it is manually added in binary packages distributed on dynare.org @@ -78,14 +76,14 @@ if isoctave 'of precompiled mex files and some\nfeatures, like solution ' ... 'of models approximated at third order, will not be available.'], supported_octave_version()) skipline() - elseif octave_ver_less_than('4.2') % Should match the test in mex/build/octave/configure.ac - % and in m4/ax_mexopts.m4 + elseif octave_ver_less_than('4.4') % Should match the test in mex/build/octave/configure.ac skipline() - warning(['This version of Dynare has only been tested on Octave 4.2 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 4.4 and above. Dynare may fail to run or give unexpected result. Consider upgrading your version of Octave.']) skipline() end else if matlab_ver_less_than('7.9') % Should match the test in mex/build/matlab/configure.ac + % and in m4/ax_mexopts.m4 skipline() warning('This version of Dynare has only been tested on MATLAB 7.9 (R2009b) and above. Since your MATLAB version is older than that, Dynare may fail to run, or give unexpected results. Consider upgrading your MATLAB installation, or switch to Octave.'); skipline() @@ -186,6 +184,14 @@ if exist(fname(1:end-4),'dir') && exist([fname(1:end-4) filesep 'hooks'],'dir') run([fname(1:end-4) filesep 'hooks/priorprocessing']) end +% Parse some options, either for the command-line or from the top of the .mod file +file_opts = parse_options_line(fname); +preprocessoroutput = ~ismember('nopreprocessoroutput', varargin) && ... + ~ismember('nopreprocessoroutput', file_opts); +nolog = ismember('nolog', varargin) || ismember('nolog', file_opts); +onlymacro = ismember('onlymacro', varargin) || ismember('onlymacro', file_opts); +onlyjson = ismember('onlyjson', varargin) || ismember('onlyjson', file_opts); + if ispc arch = getenv('PROCESSOR_ARCHITECTURE'); else @@ -204,47 +210,54 @@ else end end -command = ['"' dynareroot 'preprocessor' arch_ext filesep 'dynare_m" ' fname] ; -command = [ command ' mexext=' mexext ' "matlabroot=' matlabroot '"']; -for i=1:length(varargin) - idx = regexp(varargin{i}, '(in|ex)clude_eqs'); - if ~isempty(idx) && idx(1) == 1 - command = [command ' "' varargin{i} '"']; - else - command = [command ' ' varargin{i}]; - end -end - if preprocessoroutput fprintf(['Starting Dynare (version ' dynare_version() ').\n']); fprintf('Calling Dynare with arguments: '); if isempty(varargin) disp('none') else - disp(strjoin(varargin)); + disp(strjoin(varargin, ' ')); end end +command = ['"' dynareroot 'preprocessor' arch_ext filesep 'dynare_m" ' fname] ; +command = [ command ' mexext=' mexext ' "matlabroot=' matlabroot '"']; +% Properly quote arguments before passing them to the shell +if ~isempty(varargin) + varargincopy = varargin; + % Escape backslashes and double-quotes + varargincopy = strrep(varargincopy, '\', '\\'); + varargincopy = strrep(varargincopy, '"', '\"'); + if ~ispc + % On GNU/Linux and macOS, also escape dollars and backquotes + varargincopy = strrep(varargincopy, '$', '\$'); + varargincopy = strrep(varargincopy, '`', '\`'); + end + % Finally, enclose arguments within double quotes + dynare_varargin = ['"' strjoin(varargincopy, '" "') '"']; + command = [command ' ' dynare_varargin]; +end + % Under Windows, make sure the MEX file is unloaded (in the use_dll case), % otherwise the preprocessor can't recompile it if isoctave - clear([fname(1:end-4) '.static'], [fname(1:end-4) '.dynamic']) + clear([fname(1:end-4) '.static'], [fname(1:end-4) '.dynamic']) else - clear(['+' fname(1:end-4) '/static'], ['+' fname(1:end-4) '/dynamic']) + clear(['+' fname(1:end-4) '/static'], ['+' fname(1:end-4) '/dynamic']) end [status, result] = system(command); if status ~= 0 || preprocessoroutput disp(result) end -if ismember('onlymacro', varargin) +if onlymacro if preprocessoroutput disp('Preprocessor stopped after macroprocessing step because of ''onlymacro'' option.'); end return end -if ismember('onlyjson', varargin) +if onlyjson if preprocessoroutput disp('Preprocessor stopped after preprocessing step because of ''onlyjson'' option.'); end @@ -257,11 +270,7 @@ if exist(fname(1:end-4),'dir') && exist([fname(1:end-4) filesep 'hooks'],'dir') end % Save preprocessor result in logfile (if `no_log' option not present) -fid = fopen(fname, 'r'); -firstline = fgetl(fid); -fclose(fid); -if ~ismember('nolog', varargin) ... - && isempty(regexp(firstline, '//\s*--\+\s*options:(|.*\s|.*,)nolog(|\s.*|,.*)\+--')) +if ~nolog logname = [fname(1:end-4) '.log']; fid = fopen(logname, 'w'); fprintf(fid, '%s', result); @@ -282,3 +291,38 @@ end clear(['+' fname '/driver']) evalin('base',[fname '.driver']) ; + +end + +% Looks for an options list in the first non-empty line of the .mod file +% Should be kept in sync with the function of the same name in preprocessor/src/DynareMain.cc +% +% Note that separating options with commas is accepted, but is deprecated (and undocumented) +% +% Also, the parser does not handle correctly some corner cases: for example, it +% will fail on something like -Dfoo="a b,c" (will split at whitespace and comma) +function opts = parse_options_line(fname) + opts = {}; + fid = fopen(fname, 'r'); + while true + firstline = fgetl(fid); + if firstline == -1 + fclose(fid); + return + end + if ~isempty(firstline) + break + end + end + fclose(fid); + t = regexp(firstline, '^\s*//\s*--\+\s*options:([^\+]*)\+--', 'tokens'); + if isempty(t) + return + end + + opts = regexp(t{1}{1}, '[^,\s]+', 'match'); + + if ismember(opts, 'nopathchange') + warning('The ''nopathchange'' option is not taken into account when it appears at the top of ''.mod'' file. You should rather pass it on the command-line.') + end +end diff --git a/matlab/dynare_config.m b/matlab/dynare_config.m index e74fa1cf5..58a3ba3f3 100644 --- a/matlab/dynare_config.m +++ b/matlab/dynare_config.m @@ -16,7 +16,7 @@ function dynareroot = dynare_config(path_to_dynare) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2019 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -57,12 +57,14 @@ p = {'/distributions/' ; ... '/gsa/' ; ... '/ep/' ; ... '/backward/' ; ... - '/convergence_diagnostics/' ; ... + '/convergence_diagnostics/' ; ... '/cli/' ; ... '/lmmcp/' ; ... '/optimization/' ; ... '/ols/'; ... '/pac-tools/'; ... + '/discretionary_policy/' ; ... + '/accessors/' ; ... '/modules/dseries/src/' ; ... '/utilities/doc/' ; ... '/utilities/tests/src/' ; ... @@ -87,11 +89,6 @@ if isoctave && octave_ver_less_than('5') p{end+1} = '/missing/ordeig'; end -% corrcoef with two outputs is missing in Octave < 4.4 (ticket #796) -if isoctave && octave_ver_less_than('4.4') && ~user_has_octave_forge_package('nan') - p{end+1} = '/missing/corrcoef'; -end - %% intersect(…, 'stable') doesn't exist in Octave and in MATLAB < R2013a if isoctave || matlab_ver_less_than('8.1') p{end+1} = '/missing/intersect_stable'; @@ -99,10 +96,10 @@ end % Replacements for functions of the MATLAB statistics toolbox if isoctave - % These functions were part of Octave < 4.4, they are now in the statistics Forge package - if ~octave_ver_less_than('4.4') && ~user_has_octave_forge_package('statistics') - % Our replacement functions don't work under Octave (because of gamrnd, see - % #1638), hence the statistics toolbox is now a hard requirement + % Under Octave, these functions are in the statistics Forge package. + % Our replacement functions don't work under Octave (because of gamrnd, see + % #1638), hence the statistics toolbox is now a hard requirement + if ~user_has_octave_forge_package('statistics') error('You must install the "statistics" package from Octave Forge, either with your distribution package manager or with "pkg install -forge statistics"') end else @@ -139,7 +136,7 @@ if ~isoctave && matlab_ver_less_than('7.11') end %% isdiag is missing in MATLAB < R2014a -if ~isoctave && matlab_ver_less_than('8.4') +if ~isoctave && matlab_ver_less_than('8.3') p{end+1} = '/missing/isdiag'; end diff --git a/matlab/dynare_estimation.m b/matlab/dynare_estimation.m index 571ea4d2a..812857d00 100644 --- a/matlab/dynare_estimation.m +++ b/matlab/dynare_estimation.m @@ -12,7 +12,7 @@ function oo_recursive_=dynare_estimation(var_list,dname) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2003-2018 Dynare Team +% Copyright (C) 2003-2020 Dynare Team % % This file is part of Dynare. % @@ -144,7 +144,7 @@ if nnobs > 1 && horizon > 0 k = time_offset+min(nobs(end)-nobs(1)+horizon, ... size(dataset_.data,1)-nobs(1)); data2 = dataset_info.rawdata(end-k+1:end,:); - [nbplt,nr,nc,lr,lc,nstar] = pltorg(nvar); + [~,nr,nc,~,~,nstar] = pltorg(nvar); m = 1; plot_index=0; OutputDirectoryName = CheckPath('graphs',M_.fname); @@ -214,3 +214,5 @@ if nnobs > 1 && horizon > 0 end options_.mode_file = mode_file0; %reset stored mode-file to user defined one (and in case it was only set by the recursive estimation) +oo_.gui.ran_estimation = true; + diff --git a/matlab/dynare_estimation_1.m b/matlab/dynare_estimation_1.m index 2245dc290..e27931d1d 100644 --- a/matlab/dynare_estimation_1.m +++ b/matlab/dynare_estimation_1.m @@ -52,7 +52,7 @@ end % Set particle filter flag. if options_.order > 1 - if options_.particle.status && options_.order==2 + if options_.particle.status skipline() disp('Estimation using a non linear filter!') skipline() @@ -78,12 +78,8 @@ if options_.order > 1 end end end - elseif options_.particle.status && options_.order>2 - error(['Non linear filter are not implemented with order ' int2str(options_.order) ' approximation of the model!']) - elseif ~options_.particle.status && options_.order==2 - error('For estimating the model with a second order approximation using a non linear filter, one should have options_.particle.status=true;') else - error(['Cannot estimate a model with an order ' int2str(options_.order) ' approximation!']) + error('For estimating the model with a second order approximation using a non linear filter, one should have options_.particle.status=true;') end end @@ -443,15 +439,15 @@ if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ... end % Tunes the jumping distribution's scale parameter if options_.mh_tune_jscale.status - if options_.posterior_sampler_options.posterior_sampling_method=='random_walk_metropolis_hastings' + if strcmp(options_.posterior_sampler_options.posterior_sampling_method, 'random_walk_metropolis_hastings') options = options_.mh_tune_jscale; options.rwmh = options_.posterior_sampler_options.rwmh; options_.mh_jscale = calibrate_mh_scale_parameter(objective_function, ... - invhess, xparam1, [bounds.lb,bounds.ub], ... - options, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds, oo_); - bayestopt_.jscale(:) = options_.mh_jscale; - disp(sprintf('mh_jscale has been set equal to %s', num2str(options_.mh_jscale))) - skipline() + invhess, xparam1, [bounds.lb,bounds.ub], ... + options, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds, oo_); + bayestopt_.jscale(:) = options_.mh_jscale; + disp(sprintf('mh_jscale has been set equal to %s', num2str(options_.mh_jscale))) + skipline() else warning('mh_tune_jscale is only available with Random Walk Metropolis Hastings!') end @@ -523,23 +519,27 @@ if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ... end end [error_flag,~,options_]= metropolis_draw(1,options_,estim_params_,M_); - if options_.bayesian_irf - if error_flag - error('Estimation::mcmc: I cannot compute the posterior IRFs!') + if ~(~isempty(options_.sub_draws) && options_.sub_draws==0) + if options_.bayesian_irf + if error_flag + error('Estimation::mcmc: I cannot compute the posterior IRFs!') + end + PosteriorIRF('posterior'); end - PosteriorIRF('posterior'); - end - if options_.moments_varendo - if error_flag - error('Estimation::mcmc: I cannot compute the posterior moments for the endogenous variables!') + if options_.moments_varendo + if error_flag + error('Estimation::mcmc: I cannot compute the posterior moments for the endogenous variables!') + end + oo_ = compute_moments_varendo('posterior',options_,M_,oo_,var_list_); end - oo_ = compute_moments_varendo('posterior',options_,M_,oo_,var_list_); - end - if options_.smoother || ~isempty(options_.filter_step_ahead) || options_.forecast - if error_flag - error('Estimation::mcmc: I cannot compute the posterior statistics!') + if options_.smoother || ~isempty(options_.filter_step_ahead) || options_.forecast + if error_flag + error('Estimation::mcmc: I cannot compute the posterior statistics!') + end + prior_posterior_statistics('posterior',dataset_,dataset_info); end - prior_posterior_statistics('posterior',dataset_,dataset_info); + else + fprintf('Estimation:mcmc: sub_draws was set to 0. Skipping posterior computations.') end xparam1 = get_posterior_parameters('mean',M_,estim_params_,oo_,options_); M_ = set_all_parameters(xparam1,estim_params_,M_); diff --git a/matlab/dynare_estimation_init.m b/matlab/dynare_estimation_init.m index 5bd1ce9ac..3495a7d04 100644 --- a/matlab/dynare_estimation_init.m +++ b/matlab/dynare_estimation_init.m @@ -32,7 +32,7 @@ function [dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_, % SPECIAL REQUIREMENTS % none -% Copyright (C) 2003-2018 Dynare Team +% Copyright (C) 2003-2020 Dynare Team % % This file is part of Dynare. % @@ -100,9 +100,17 @@ if length(unique(options_.varobs))2 - error(['I cannot estimate a model with a ' int2str(options_.order) ' order approximation of the model!']) +if options_.discretionary_policy + if options_.order>1 + error('discretionary_policy does not support order>1'); + else + M_=discretionary_policy_initialization(M_,options_); + end +end + +% Check the perturbation order (k order perturbation based nonlinear filters are not yet implemented for k>1). +if options_.order>2 && options_.particle.pruning + error('Higher order nonlinear filters are not compatible with pruning option.') end % analytical derivation is not yet available for kalman_filter_fast @@ -566,7 +574,7 @@ end if info(1) fprintf('\ndynare_estimation_init:: The steady state at the initial parameters cannot be computed.\n') if options_.debug - M.params=params; + M.params=params; plist = list_of_parameters_calibrated_as_NaN(M); if ~isempty(plist) message = ['dynare_estimation_init:: Some of the parameters are NaN (' ]; @@ -589,7 +597,7 @@ if info(1) message = [message, plist{i} ')']; end end - end + end fprintf('%s\n',message) end print_info(info, 0, options_); diff --git a/matlab/dynare_identification.m b/matlab/dynare_identification.m index 8f9141896..b864e46d7 100644 --- a/matlab/dynare_identification.m +++ b/matlab/dynare_identification.m @@ -1,32 +1,29 @@ -function [pdraws, STO_TAU, STO_MOMENTS, STO_LRE, STO_si_dLRE, STO_si_dTAU, STO_si_J, STO_G, STO_D] = dynare_identification(options_ident, pdraws0) -%function [pdraws, STO_TAU, STO_MOMENTS, STO_LRE, STO_dLRE, STO_dTAU, STO_J, STO_G, STO_D] = dynare_identification(options_ident, pdraws0) +function [pdraws, STO_REDUCEDFORM, STO_MOMENTS, STO_DYNAMIC, STO_si_dDYNAMIC, STO_si_dREDUCEDFORM, STO_si_dMOMENTS, STO_dSPECTRUM, STO_dMINIMAL] = dynare_identification(options_ident, pdraws0) +%function [pdraws, STO_REDUCEDFORM, STO_MOMENTS, STO_DYNAMIC, STO_si_dDYNAMIC, STO_si_dREDUCEDFORM, STO_si_dMOMENTS, STO_dSPECTRUM, STO_dMINIMAL] = dynare_identification(options_ident, pdraws0) % ------------------------------------------------------------------------- -% This function is called, when the user specifies identification(...); in -% the mod file. It prepares all identification analysis, i.e. -% (1) sets options, local/persistent/global variables for a new identification -% analysis either for a single point or MC Sample and displays and plots the results -% or -% (2) loads, displays and plots a previously saved identification analysis +% This function is called, when the user specifies identification(...); in the mod file. It prepares all identification analysis: +% (1) set options, local and persistent variables for a new identification +% analysis either for a single point or a MC Sample. It also displays and plots the results +% (2) load, display and plot a previously saved identification analysis +% +% Note 1: This function does not output the arguments to the workspace, but saves results to the folder identification +% Note 2: If you want to use this function directly in the mod file and workspace, you still have +% to put identification in your mod file, otherwise the preprocessor won't provide all necessary objects % ========================================================================= % INPUTS % * options_ident [structure] identification options % * pdraws0 [SampleSize by totparam_nbr] optional: matrix of MC sample of model parameters % ------------------------------------------------------------------------- % OUTPUTS -% Note: This function does not output the arguments to the workspace if only called by -% "identification" in the mod file, but saves results to the folder identification. -% One can, however, just use -% [pdraws, STO_TAU, STO_MOMENTS, STO_LRE, STO_dLRE, STO_dTAU, STO_J, STO_G, STO_D] = dynare_identification(options_ident, pdraws0) -% in the mod file to get the results directly in the workspace -% * pdraws [matrix] MC sample of model params used -% * STO_TAU, [matrix] MC sample of entries in the model solution (stacked vertically) -% * STO_MOMENTS, [matrix] MC sample of entries in the moments (stacked vertically) -% * STO_LRE, [matrix] MC sample of entries in LRE model (stacked vertically) -% * STO_dLRE, [matrix] MC sample of derivatives of the Jacobian (dLRE) -% * STO_dTAU, [matrix] MC sample of derivatives of the model solution and steady state (dTAU) -% * STO_J [matrix] MC sample of Iskrev (2010)'s J matrix -% * STO_G [matrix] MC sample of Qu and Tkachenko (2012)'s G matrix -% * STO_D [matrix] MC sample of Komunjer and Ng (2011)'s D matrix +% * pdraws [matrix] MC sample of model params used +% * STO_REDUCEDFORM, [matrix] MC sample of entries in steady state and reduced form model solution (stacked vertically) +% * STO_MOMENTS, [matrix] MC sample of entries in theoretical first two moments (stacked vertically) +% * STO_DYNAMIC, [matrix] MC sample of entries in steady state and dynamic model derivatives (stacked vertically) +% * STO_si_dDYNAMIC, [matrix] MC sample of derivatives of steady state and dynamic derivatives +% * STO_si_dREDUCEDFORM, [matrix] MC sample of derivatives of steady state and reduced form model solution +% * STO_si_dMOMENTS [matrix] MC sample of Iskrev (2010)'s J matrix +% * STO_dSPECTRUM [matrix] MC sample of Qu and Tkachenko (2012)'s \bar{G} matrix +% * STO_dMINIMAL [matrix] MC sample of Komunjer and Ng (2011)'s \bar{\Delta} matrix % ------------------------------------------------------------------------- % This function is called by % * driver.m @@ -37,19 +34,19 @@ function [pdraws, STO_TAU, STO_MOMENTS, STO_LRE, STO_si_dLRE, STO_si_dTAU, STO_s % * disp_identification % * dyn_waitbar % * dyn_waitbar_close -% * get_all_parameters +% * get_all_parameters % * get_posterior_parameters -% * get_the_name +% * get_the_name % * identification_analysis % * isoctave % * plot_identification -% * prior_draw +% * prior_draw % * set_default_option % * set_prior % * skipline % * vnorm % ========================================================================= -% Copyright (C) 2010-2019 Dynare Team +% Copyright (C) 2010-2020 Dynare Team % % This file is part of Dynare. % @@ -89,13 +86,14 @@ else warning('off','MATLAB:specgraph:private:specgraph:UsingOnlyRealComponentOfComplexData'); warning('off','MATLAB:handle_graphics:exceptions:SceneNode'); warning('off','MATLAB:divideByZero'); + warning('off','MATLAB:log:logOfZero'); end -%% Set all options and create objects +%% Set all options in options_ident and create objects options_ident = set_default_option(options_ident,'gsa_sample_file',0); - % 0: do not use sample file. - % 1: triggers gsa prior sample. - % 2: triggers gsa Monte-Carlo sample (i.e. loads a sample corresponding to pprior=0 and ppost=0 in dynare_sensitivity options). + % 0: do not use sample file + % 1: triggers gsa prior sample + % 2: triggers gsa Monte-Carlo sample (i.e. loads a sample corresponding to pprior=0 and ppost=0 in dynare_sensitivity options) % FILENAME: use sample file in provided path options_ident = set_default_option(options_ident,'parameter_set','prior_mean'); % 'calibration': use values in M_.params and M_.Sigma_e to update estimated stderr, corr and model parameters (get_all_parameters) @@ -107,86 +105,86 @@ options_ident = set_default_option(options_ident,'parameter_set','prior_mean'); options_ident = set_default_option(options_ident,'load_ident_files',0); % 1: load previously computed analysis from identification/fname_identif.mat options_ident = set_default_option(options_ident,'useautocorr',0); - % 1: use autocorrelations in Iskrev (2010)'s J criteria - % 0: use autocovariances in Iskrev (2010)'s J criteria + % 1: use autocorrelations in Iskrev (2010)'s theoretical second moments criteria + % 0: use autocovariances in Iskrev (2010)'s theoretical second moments criteria options_ident = set_default_option(options_ident,'ar',1); - % number of lags to consider for autocovariances/autocorrelations in Iskrev (2010)'s J criteria + % number of lags to consider for autocovariances/autocorrelations in Iskrev (2010)'s criteria options_ident = set_default_option(options_ident,'prior_mc',1); % size of Monte-Carlo sample of parameter draws options_ident = set_default_option(options_ident,'prior_range',0); % 1: sample uniformly from prior ranges implied by the prior specifications (overwrites prior shape when prior_mc > 1) % 0: sample from specified prior distributions (when prior_mc > 1) options_ident = set_default_option(options_ident,'periods',300); - % length of stochastic simulation to compute simulated moment uncertainty, when analytic Hessian is not available + % length of stochastic simulation to compute simulated moment uncertainty (when analytic Hessian is not available) options_ident = set_default_option(options_ident,'replic',100); - % number of replicas to compute simulated moment uncertainty, when analytic Hessian is not available + % number of replicas to compute simulated moment uncertainty (when analytic Hessian is not available) options_ident = set_default_option(options_ident,'advanced',0); - % 1: show a more detailed analysis based on reduced-form solution and Jacobian of dynamic model (LRE). Further, performs a brute force - % search of the groups of parameters best reproducing the behavior of each single parameter of Iskrev (2010)'s J. + % 1: show a more detailed analysis based on reduced-form model solution and dynamic model derivatives. Further, performs a brute force + % search of the groups of parameters best reproducing the behavior of each single parameter. options_ident = set_default_option(options_ident,'normalize_jacobians',1); - % 1: normalize Jacobians by rescaling each row by its largest element in absolute value + % 1: normalize Jacobians by either rescaling each row by its largest element in absolute value or for Gram (or Hessian-type) matrices by transforming into correlation-type matrices options_ident = set_default_option(options_ident,'grid_nbr',5000); - % number of grid points in [-pi;pi] to approximate the integral to compute Qu and Tkachenko (2012)'s G criteria - % note that grid_nbr needs to be even and actually we use (grid_nbr+1) points, as we add the 0 frequency and use symmetry, i.e. grid_nbr/2 - % negative as well as grid_nbr/2 positive values to speed up the compuations + % number of grid points in [-pi;pi] to approximate the integral to compute Qu and Tkachenko (2012)'s criteria + % note that grid_nbr needs to be even and actually we use (grid_nbr+1) points, as we add the 0 frequency and use symmetry if mod(options_ident.grid_nbr,2) ~= 0 options_ident.grid_nbr = options_ident.grid_nbr+1; + fprintf('IDENTIFICATION: ''grid_nbr'' needs to be even, hence it is reset to %d\n',options_ident.grid_nbr) if mod(options_ident.grid_nbr,2) ~= 0 error('IDENTIFICATION: You need to set an even value for ''grid_nbr'''); end end -options_ident = set_default_option(options_ident,'tol_rank',1.e-10); +options_ident = set_default_option(options_ident,'tol_rank','robust'); % tolerance level used for rank computations options_ident = set_default_option(options_ident,'tol_deriv',1.e-8); % tolerance level for selecting columns of non-zero derivatives options_ident = set_default_option(options_ident,'tol_sv',1.e-3); % tolerance level for selecting non-zero singular values in identification_checks.m - + %check whether to compute identification strength based on information matrix if ~isfield(options_ident,'no_identification_strength') options_ident.no_identification_strength = 0; else options_ident.no_identification_strength = 1; end -%check whether to compute and display identification criteria based on steady state and reduced-form solution +%check whether to compute and display identification criteria based on steady state and reduced-form model solution if ~isfield(options_ident,'no_identification_reducedform') options_ident.no_identification_reducedform = 0; else options_ident.no_identification_reducedform = 1; end -%check whether to compute and display identification criteria based on Iskrev (2010)'s J, i.e. derivative of first two moments +%check whether to compute and display identification criteria based on Iskrev (2010), i.e. derivative of first two moments if ~isfield(options_ident,'no_identification_moments') options_ident.no_identification_moments = 0; else options_ident.no_identification_moments = 1; end -%check whether to compute and display identification criteria based on Komunjer and Ng (2011)'s D, i.e. derivative of first moment, minimal state space system and observational equivalent spectral density transformation +%check whether to compute and display identification criteria based on Komunjer and Ng (2011), i.e. derivative of first moment, minimal state space system and observational equivalent spectral density transformation if ~isfield(options_ident,'no_identification_minimal') options_ident.no_identification_minimal = 0; else - options_ident.no_identification_minimal = 1; + options_ident.no_identification_minimal = 1; end -%Check whether to compute and display identification criteria based on Qu and Tkachenko (2012)'s G, i.e. Gram matrix of derivatives of first moment plus outer product of derivatives of spectral density +%Check whether to compute and display identification criteria based on Qu and Tkachenko (2012), i.e. Gram matrix of derivatives of first moment plus outer product of derivatives of spectral density if ~isfield(options_ident,'no_identification_spectrum') options_ident.no_identification_spectrum = 0; else options_ident.no_identification_spectrum = 1; end -%overwrite setting, as identification strength and advanced need criteria based on both reducedform and moments +%overwrite setting, as identification strength and advanced need both reducedform and moments criteria if (isfield(options_ident,'no_identification_strength') && options_ident.no_identification_strength == 0) || (options_ident.advanced == 1) options_ident.no_identification_reducedform = 0; options_ident.no_identification_moments = 0; end -%overwrite setting, as dynare_sensitivity does not make use of spectrum and minimal system (yet) +%overwrite setting, as dynare_sensitivity does not make use of spectrum and minimal system if isfield(options_,'opt_gsa') && isfield(options_.opt_gsa,'identification') && options_.opt_gsa.identification == 1 options_ident.no_identification_minimal = 1; options_ident.no_identification_spectrum = 1; end %Deal with non-stationary cases -if isfield(options_ident,'diffuse_filter') %set lik_init and options_ +if isfield(options_ident,'diffuse_filter') options_ident.lik_init=3; %overwrites any other lik_init set options_.diffuse_filter=options_ident.diffuse_filter; %make options_ inherit diffuse filter; will overwrite any conflicting lik_init in dynare_estimation_init else @@ -211,8 +209,16 @@ options_ident = set_default_option(options_ident,'lik_init',1); % ii) option 1 for the stationary elements options_ident = set_default_option(options_ident,'analytic_derivation',1); % 1: analytic derivation of gradient and hessian of likelihood in dsge_likelihood.m, only works for stationary models, i.e. kalman_algo<3 +options_ident = set_default_option(options_ident,'order',1); + % 1: first-order perturbation approximation, identification is based on linear state space system + % 2: second-order perturbation approximation, identification is based on second-order pruned state space system + % 3: third-order perturbation approximation, identification is based on third-order pruned state space system %overwrite values in options_, note that options_ is restored at the end of the function +if isfield(options_ident,'prior_trunc') + options_.prior_trunc=options_ident.prior_trunc; + % sets truncation of prior +end if isfield(options_ident,'TeX') options_.TeX=options_ident.TeX; % requests printing of results and graphs in LaTeX @@ -273,7 +279,17 @@ else end % overwrite settings in options_ and prepare to call dynare_estimation_init -options_.order = 1; % Identification does not support order>1 (yet) +options_.order = options_ident.order; +if options_ident.order > 1 + %order>1 is not compatible with analytic derivation in dsge_likelihood.m + options_ident.analytic_derivation=0; + options_.analytic_derivation=0; + %order>1 is based on pruned state space system + options_.pruning = true; +end +if options_ident.order == 3 + options_.k_order_solver = 1; +end options_.ar = options_ident.ar; options_.prior_mc = options_ident.prior_mc; options_.Schur_vec_tol = 1.e-8; @@ -284,16 +300,16 @@ options_ = set_default_option(options_,'datafile',''); options_.mode_compute = 0; options_.plot_priors = 0; options_.smoother = 1; -options_.options_ident = options_ident; %store identification options into global options +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_); -%outputting dataset_ is needed for Octave % 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 - % 0: efficient sylvester equation method to compute analytical derivatives as in Ratto & Iskrev (2011) - % 1: kronecker products method to compute analytical derivatives as in Iskrev (2010) - % -1: numerical two-sided finite difference method to compute numerical derivatives of all Jacobians using function identification_numerical_objective.m (previously thet2tau.m) - % -2: numerical two-sided finite difference method to compute numerically dYss, dg1, d2Yss and d2g1, the Jacobians are then computed analytically as in options 0 + % 0: efficient sylvester equation method to compute analytical derivatives as in Ratto & Iskrev (2012) + % 1: kronecker products method to compute analytical derivatives as in Iskrev (2010) (only for order=1) + % -1: numerical two-sided finite difference method to compute numerical derivatives of all identification Jacobians using function identification_numerical_objective.m (previously thet2tau.m) + % -2: numerical two-sided finite difference method to compute numerically dYss, dg1, dg2, dg3, d2Yss and d2g1, the identification Jacobians are then computed analytically as with 0 +options_.analytic_derivation_mode = options_ident.analytic_derivation_mode; %overwrite setting in options_ % initialize persistent variables in prior_draw if prior_exist @@ -328,14 +344,14 @@ if prior_exist % use estimated_params block indpcorr = estim_params_.corrx(:,1:2); %values correspond to varexo declaration order, row number corresponds to order in estimated_params end totparam_nbr = length(bayestopt_.name); % number of estimated stderr, corr and model parameters as declared in estimated_params - modparam_nbr = estim_params_.np; %number of model parameters as declared in estimated_params - stderrparam_nbr = estim_params_.nvx; % nvx is number of stderr parameters - corrparam_nbr = estim_params_.ncx; % ncx is number of corr parameters + 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 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('Identification does not (yet) support measurement errors. Instead, define them explicitly in measurement equations in model definition.') + error('Identification does not (yet) support measurement errors. Instead, define them explicitly as varexo and provide measurement equations in the model definition.') end - name = cell(totparam_nbr,1); %initialize cell for parameter names - name_tex = cell(totparam_nbr,1); + name = cell(totparam_nbr,1); %initialize cell for parameter names + name_tex = cell(totparam_nbr,1); %initialize cell for TeX parameter names for jj=1:totparam_nbr if options_.TeX [param_name_temp, param_name_tex_temp]= get_the_name(jj,options_.TeX,M_,estim_params_,options_); @@ -347,9 +363,9 @@ if prior_exist % use estimated_params block end end else % no estimated_params block, choose all model parameters and all stderr parameters, but no corr parameters - indpmodel = 1:M_.param_nbr; %all model parameters + indpmodel = 1:M_.param_nbr; %all model parameters indpstderr = 1:M_.exo_nbr; %all stderr parameters - indpcorr = []; %no corr parameters + indpcorr = []; %no corr parameters stderrparam_nbr = M_.exo_nbr; corrparam_nbr = 0; modparam_nbr = M_.param_nbr; @@ -359,35 +375,38 @@ else % no estimated_params block, choose all model parameters and all stderr par name_tex = cellfun(@(x) horzcat('$ SE_{', x, '} $'), M_.exo_names, 'UniformOutput', false); name_tex = vertcat(name_tex, M_.param_names_tex); if ~isequal(M_.H,0) - fprintf('\ndynare_identification:: Identification does not support measurement errors (yet) and will ignore them in the following. To test their identifiability, instead define them explicitly in measurement equations in the model definition.\n') + fprintf('\ndynare_identification:: Identification does not support measurement errors (yet) and will ignore them in the following. To test their identifiability, instead define them explicitly as varexo and provide measurement equations in the model definition.\n') end end options_ident.name_tex = name_tex; -skipline() -disp('==== Identification analysis ====') +fprintf('\n======== Identification Analysis ========\n') +if options_ident.order > 1 + fprintf('Based on Pruned State Space System (order=%d)\n',options_ident.order); +end skipline() if totparam_nbr < 2 options_ident.advanced = 0; - disp('There is only one parameter to study for identitification. The advanced option is re-set to 0.') - skipline() + fprintf('There is only one parameter to study for identitification. The advanced option is re-set to 0.\n') end -% set options_ident dependent ot totparam_nbr +% settings dependent on number of parameters options_ident = set_default_option(options_ident,'max_dim_cova_group',min([2,totparam_nbr-1])); options_ident.max_dim_cova_group = min([options_ident.max_dim_cova_group,totparam_nbr-1]); % In brute force search (ident_bruteforce.m) when advanced=1 this option sets the maximum dimension of groups of parameters that best reproduce the behavior of each single model parameter -options_ident = set_default_option(options_ident,'checks_via_subsets',0); %[ONLY FOR DEBUGGING] - % 1: uses identification_checks_via_subsets.m to compute problematic parameter combinations +options_ident = set_default_option(options_ident,'checks_via_subsets',0); + % 1: uses identification_checks_via_subsets.m to compute problematic parameter combinations % 0: uses identification_checks.m to compute problematic parameter combinations [default] -options_ident = set_default_option(options_ident,'max_dim_subsets_groups',min([4,totparam_nbr-1])); %[ONLY FOR DEBUGGING] - % In identification_checks_via_subsets.m, when checks_via_subsets=1, this - % option sets the maximum dimension of groups of parameters for which - % the corresponding rank criteria is checked - -MaxNumberOfBytes = options_.MaxNumberOfBytes; %threshold when to save from memory to files +options_ident = set_default_option(options_ident,'max_dim_subsets_groups',min([4,totparam_nbr-1])); + % In identification_checks_via_subsets.m, when checks_via_subsets=1, this option sets the maximum dimension of groups of parameters for which the corresponding rank criteria is checked + + +% store identification options +options_.options_ident = options_ident; store_options_ident = options_ident; + +% get some options for quick reference iload = options_ident.load_ident_files; SampleSize = options_ident.prior_mc; @@ -400,149 +419,110 @@ if iload <=0 % only bounds are specified in estimated_params parameters = 'ML_Starting_value'; parameters_TeX = 'ML starting value'; - disp('Testing ML Starting value') + fprintf('Testing ML Starting value\n'); else % use user-defined option switch parameters - case 'calibration' - parameters_TeX = 'Calibration'; - disp('Testing calibration') - params(1,:) = get_all_parameters(estim_params_,M_); - case 'posterior_mode' - parameters_TeX = 'Posterior mode'; - disp('Testing posterior mode') - params(1,:) = get_posterior_parameters('mode',M_,estim_params_,oo_,options_); - case 'posterior_mean' - parameters_TeX = 'Posterior mean'; - disp('Testing posterior mean') - params(1,:) = get_posterior_parameters('mean',M_,estim_params_,oo_,options_); - case 'posterior_median' - parameters_TeX = 'Posterior median'; - disp('Testing posterior median') - params(1,:) = get_posterior_parameters('median',M_,estim_params_,oo_,options_); - case 'prior_mode' - parameters_TeX = 'Prior mode'; - disp('Testing prior mode') - params(1,:) = bayestopt_.p5(:); - case 'prior_mean' - parameters_TeX = 'Prior mean'; - disp('Testing prior mean') - params(1,:) = bayestopt_.p1; - otherwise - disp('The option parameter_set has to be equal to:') - disp(' ''calibration'', ') - disp(' ''posterior_mode'', ') - disp(' ''posterior_mean'', ') - disp(' ''posterior_median'', ') - disp(' ''prior_mode'' or') - disp(' ''prior_mean''.') - error('IDENTIFICATION: The option ''parameter_set'' has and invalid value'); + case 'calibration' + parameters_TeX = 'Calibration'; + fprintf('Testing calibration\n'); + params(1,:) = get_all_parameters(estim_params_,M_); + case 'posterior_mode' + parameters_TeX = 'Posterior mode'; + fprintf('Testing posterior mode\n'); + params(1,:) = get_posterior_parameters('mode',M_,estim_params_,oo_,options_); + case 'posterior_mean' + parameters_TeX = 'Posterior mean'; + fprintf('Testing posterior mean\n'); + params(1,:) = get_posterior_parameters('mean',M_,estim_params_,oo_,options_); + case 'posterior_median' + parameters_TeX = 'Posterior median'; + fprintf('Testing posterior median\n'); + params(1,:) = get_posterior_parameters('median',M_,estim_params_,oo_,options_); + case 'prior_mode' + parameters_TeX = 'Prior mode'; + fprintf('Testing prior mode\n'); + params(1,:) = bayestopt_.p5(:); + case 'prior_mean' + parameters_TeX = 'Prior mean'; + fprintf('Testing prior mean\n'); + params(1,:) = bayestopt_.p1; + otherwise + fprintf('The option parameter_set has to be equal to: ''calibration'', ''posterior_mode'', ''posterior_mean'', ''posterior_median'', ''prior_mode'' or ''prior_mean''.\n'); + error('IDENTIFICATION: The option ''parameter_set'' has an invalid value'); end end else % no estimated_params block is available, all stderr and model parameters, but no corr parameters are chosen - params = [sqrt(diag(M_.Sigma_e))', M_.params']; % use current values + params = [sqrt(diag(M_.Sigma_e))', M_.params']; parameters = 'Current_params'; parameters_TeX = 'Current parameter values'; - disp('Testing all current stderr and model parameter values') + fprintf('Testing all current stderr and model parameter values\n'); 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_lre_point, derivatives_info_point, info, options_ident] = ... + [ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, derivatives_info_point, info, options_ident] = ... identification_analysis(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 - skipline() - disp('----------- ') - disp('Parameter error:') - disp(['The model does not solve for ', parameters, ' with error code info = ', int2str(info(1))]), - skipline() - if info(1)==1 - disp('info==1 %! The model doesn''t determine the current variables uniquely.') - elseif info(1)==2 - disp('info==2 %! MJDGGES returned an error code.') - elseif info(1)==3 - disp('info==3 %! Blanchard & Kahn conditions are not satisfied: no stable equilibrium. ') - elseif info(1)==4 - disp('info==4 %! Blanchard & Kahn conditions are not satisfied: indeterminacy. ') - elseif info(1)==5 - disp('info==5 %! Blanchard & Kahn conditions are not satisfied: indeterminacy due to rank failure. ') - elseif info(1)==6 - disp('info==6 %! The jacobian evaluated at the deterministic steady state is complex.') - elseif info(1)==19 - disp('info==19 %! The steadystate routine has thrown an exception (inconsistent deep parameters). ') - elseif info(1)==20 - disp('info==20 %! Cannot find the steady state, info(2) contains the sum of square residuals (of the static equations). ') - elseif info(1)==21 - disp('info==21 %! The steady state is complex, info(2) contains the sum of square of imaginary parts of the steady state.') - elseif info(1)==22 - disp('info==22 %! The steady has NaNs. ') - elseif info(1)==23 - disp('info==23 %! M_.params has been updated in the steadystate routine and has complex valued scalars. ') - elseif info(1)==24 - disp('info==24 %! M_.params has been updated in the steadystate routine and has some NaNs. ') - elseif info(1)==30 - disp('info==30 %! Ergodic variance can''t be computed. ') - end - disp('----------- ') - skipline() + message = get_error_message(info,options_); + fprintf('-----------\n'); + fprintf('The model does not solve for %s (info = %d: %s)\n', parameters, info(1), message); + fprintf('-----------\n'); if any(bayestopt_.pshape) % if there are errors in the solution algorithm, try to sample a different point from the prior - disp('Try sampling up to 50 parameter sets from the prior.') + fprintf('Try sampling up to 50 parameter sets from the prior.\n'); kk=0; while kk<50 && info(1) kk=kk+1; 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_lre_point, derivatives_info, info, options_ident] = ... - identification_analysis(params,indpmodel,indpstderr,indpcorr,options_ident,dataset_info, prior_exist, 1); + [ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, derivatives_info_point, info, options_ident] = ... + identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); end end if info(1) - skipline() - disp('----------- ') - disp('Identification stopped:') + fprintf('\n-----------\n'); + fprintf('Identification stopped:\n'); if any(bayestopt_.pshape) - disp('The model did not solve for any of 50 attempts of random samples from the prior') + fprintf('The model did not solve for any of 50 attempts of random samples from the prior\n'); end - disp('----------- ') - skipline() + fprintf('-----------\n'); return else % found a (random) point that solves the model - disp('Found a random draw from the priors that solves the model.') - disp(params) - disp('Identification now continues for this draw.'); + fprintf('Found a random draw from the priors that solves the model:\n'); + disp(params); + fprintf('Identification now continues for this draw.'); parameters = 'Random_prior_params'; parameters_TeX = 'Random prior parameter draw'; end end ide_hess_point.params = params; % save all output into identification folder - save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_lre_point','store_options_ident'); - save([IdentifDirectoryName '/' fname '_' parameters '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_lre_point','store_options_ident'); + save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_dynamic_point', 'store_options_ident'); + save([IdentifDirectoryName '/' fname '_' parameters '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_dynamic_point', 'store_options_ident'); % display results of identification analysis disp_identification(params, ide_reducedform_point, ide_moments_point, ide_spectrum_point, ide_minimal_point, name, options_ident); if ~options_ident.no_identification_strength && ~options_.nograph - % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs - plot_identification(params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_lre_point, options_ident.advanced, parameters, name, IdentifDirectoryName, parameters_TeX, name_tex); + % plot (i) identification strength and sensitivity measure based on the moment information matrix and (ii) plot advanced analysis graphs + plot_identification(params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, options_ident.advanced, parameters, name, IdentifDirectoryName, parameters_TeX, name_tex); end - + if SampleSize > 1 % initializations for Monte Carlo Analysis - skipline() - disp('Monte Carlo Testing') + fprintf('\nMonte Carlo Testing\n'); h = dyn_waitbar(0,'Monte Carlo identification checks ...'); iteration = 0; % initialize counter for admissable draws run_index = 0; % initialize counter for admissable draws after saving previous draws to file(s) - file_index = 0; % initialize counter for files (if MaxNumberOfBytes is reached, we store results in files) + file_index = 0; % initialize counter for files (if options_.MaxNumberOfBytes is reached, we store results in files) options_MC = options_ident; %store options structure for Monte Carlo analysis - options_MC.advanced = 0; %do not run advanced checking in a Monte Carlo analysis + options_MC.advanced = 0; %do not run advanced checking in a Monte Carlo analysis options_ident.checks_via_subsets = 0; % for Monte Carlo analysis currently only identification_checks and not identification_checks_via_subsets is supported else iteration = 1; % iteration equals SampleSize and we are finished - pdraws = []; % to have output object otherwise map_ident may crash + pdraws = []; % to have output object otherwise map_ident.m may crash end while iteration < SampleSize if external_sample @@ -552,105 +532,111 @@ 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_lre, ide_derivatives_info, info, options_MC] = ... + [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_dynamic, ide_derivatives_info, info, options_MC] = ... identification_analysis(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 delete([IdentifDirectoryName '/' fname '_identif_*.mat']) % delete previously saved results - MAX_RUNS_BEFORE_SAVE_TO_FILE = min(SampleSize,ceil(MaxNumberOfBytes/(size(ide_reducedform.si_dTAU,1)*totparam_nbr)/8)); % set how many runs can be stored before we save to files + MAX_RUNS_BEFORE_SAVE_TO_FILE = min(SampleSize,ceil(options_.MaxNumberOfBytes/(size(ide_reducedform.si_dREDUCEDFORM,1)*totparam_nbr)/8)); % set how many runs can be stored before we save to files pdraws = zeros(SampleSize,totparam_nbr); % preallocate storage for draws in each row - - % preallocate storage for linear rational expectations model - STO_si_dLRE = zeros([size(ide_lre.si_dLRE,1),modparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]); - STO_LRE = zeros(size(ide_lre.LRE,1),SampleSize); - IDE_LRE.ind_dLRE = ide_lre.ind_dLRE; - IDE_LRE.in0 = zeros(SampleSize,modparam_nbr); - IDE_LRE.ind0 = zeros(SampleSize,modparam_nbr); - IDE_LRE.jweak = zeros(SampleSize,modparam_nbr); - IDE_LRE.jweak_pair = zeros(SampleSize,modparam_nbr*(modparam_nbr+1)/2); - IDE_LRE.cond = zeros(SampleSize,1); - IDE_LRE.Mco = zeros(SampleSize,modparam_nbr); - + + % preallocate storage for dynamic model + STO_si_dDYNAMIC = zeros([size(ide_dynamic.si_dDYNAMIC, 1), modparam_nbr, MAX_RUNS_BEFORE_SAVE_TO_FILE]); + STO_DYNAMIC = zeros(size(ide_dynamic.DYNAMIC, 1), SampleSize); + IDE_DYNAMIC.ind_dDYNAMIC = ide_dynamic.ind_dDYNAMIC; + IDE_DYNAMIC.in0 = zeros(SampleSize, modparam_nbr); + IDE_DYNAMIC.ind0 = zeros(SampleSize, modparam_nbr); + IDE_DYNAMIC.jweak = zeros(SampleSize, modparam_nbr); + IDE_DYNAMIC.jweak_pair = zeros(SampleSize, modparam_nbr*(modparam_nbr+1)/2); + IDE_DYNAMIC.cond = zeros(SampleSize, 1); + IDE_DYNAMIC.Mco = zeros(SampleSize, modparam_nbr); + % preallocate storage for reduced form if ~options_MC.no_identification_reducedform - STO_si_dTAU = zeros([size(ide_reducedform.si_dTAU,1),totparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]); - STO_TAU = zeros(size(ide_reducedform.TAU,1),SampleSize); - IDE_REDUCEDFORM.ind_dTAU = ide_reducedform.ind_dTAU; - IDE_REDUCEDFORM.in0 = zeros(SampleSize,1); - IDE_REDUCEDFORM.ind0 = zeros(SampleSize,totparam_nbr); - IDE_REDUCEDFORM.jweak = zeros(SampleSize,totparam_nbr); - IDE_REDUCEDFORM.jweak_pair = zeros(SampleSize,totparam_nbr*(totparam_nbr+1)/2); - IDE_REDUCEDFORM.cond = zeros(SampleSize,1); - IDE_REDUCEDFORM.Mco = zeros(SampleSize,totparam_nbr); + STO_si_dREDUCEDFORM = zeros([size(ide_reducedform.si_dREDUCEDFORM, 1), totparam_nbr, MAX_RUNS_BEFORE_SAVE_TO_FILE]); + STO_REDUCEDFORM = zeros(size(ide_reducedform.REDUCEDFORM, 1), SampleSize); + IDE_REDUCEDFORM.ind_dREDUCEDFORM = ide_reducedform.ind_dREDUCEDFORM; + IDE_REDUCEDFORM.in0 = zeros(SampleSize, 1); + IDE_REDUCEDFORM.ind0 = zeros(SampleSize, totparam_nbr); + IDE_REDUCEDFORM.jweak = zeros(SampleSize, totparam_nbr); + IDE_REDUCEDFORM.jweak_pair = zeros(SampleSize, totparam_nbr*(totparam_nbr+1)/2); + IDE_REDUCEDFORM.cond = zeros(SampleSize, 1); + IDE_REDUCEDFORM.Mco = zeros(SampleSize, totparam_nbr); else - IDE_REDUCEDFORM = {}; + STO_si_dREDUCEDFORM = {}; + STO_REDUCEDFORM = {}; + IDE_REDUCEDFORM = {}; end - + % preallocate storage for moments if ~options_MC.no_identification_moments - STO_si_J = zeros([size(ide_moments.si_J,1),totparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]); - STO_MOMENTS = zeros(size(ide_moments.MOMENTS,1),SampleSize); - IDE_MOMENTS.ind_J = ide_moments.ind_J; - IDE_MOMENTS.in0 = zeros(SampleSize,1); - IDE_MOMENTS.ind0 = zeros(SampleSize,totparam_nbr); - IDE_MOMENTS.jweak = zeros(SampleSize,totparam_nbr); - IDE_MOMENTS.jweak_pair = zeros(SampleSize,totparam_nbr*(totparam_nbr+1)/2); - IDE_MOMENTS.cond = zeros(SampleSize,1); - IDE_MOMENTS.Mco = zeros(SampleSize,totparam_nbr); - IDE_MOMENTS.S = zeros(SampleSize,min(8,totparam_nbr)); - IDE_MOMENTS.V = zeros(SampleSize,totparam_nbr,min(8,totparam_nbr)); + STO_si_dMOMENTS = zeros([size(ide_moments.si_dMOMENTS, 1), totparam_nbr, MAX_RUNS_BEFORE_SAVE_TO_FILE]); + STO_MOMENTS = zeros(size(ide_moments.MOMENTS, 1), SampleSize); + IDE_MOMENTS.ind_dMOMENTS = ide_moments.ind_dMOMENTS; + IDE_MOMENTS.in0 = zeros(SampleSize, 1); + IDE_MOMENTS.ind0 = zeros(SampleSize, totparam_nbr); + IDE_MOMENTS.jweak = zeros(SampleSize, totparam_nbr); + IDE_MOMENTS.jweak_pair = zeros(SampleSize, totparam_nbr*(totparam_nbr+1)/2); + IDE_MOMENTS.cond = zeros(SampleSize, 1); + IDE_MOMENTS.Mco = zeros(SampleSize, totparam_nbr); + IDE_MOMENTS.S = zeros(SampleSize, min(8, totparam_nbr)); + IDE_MOMENTS.V = zeros(SampleSize, totparam_nbr, min(8, totparam_nbr)); else - IDE_MOMENTS = {}; + STO_si_dMOMENTS = {}; + STO_MOMENTS = {}; + IDE_MOMENTS = {}; end - + % preallocate storage for spectrum if ~options_MC.no_identification_spectrum - STO_G = zeros([size(ide_spectrum.G,1),size(ide_spectrum.G,2), MAX_RUNS_BEFORE_SAVE_TO_FILE]); - IDE_SPECTRUM.ind_G = ide_spectrum.ind_G; - IDE_SPECTRUM.in0 = zeros(SampleSize,1); - IDE_SPECTRUM.ind0 = zeros(SampleSize,totparam_nbr); - IDE_SPECTRUM.jweak = zeros(SampleSize,totparam_nbr); - IDE_SPECTRUM.jweak_pair = zeros(SampleSize,totparam_nbr*(totparam_nbr+1)/2); - IDE_SPECTRUM.cond = zeros(SampleSize,1); - IDE_SPECTRUM.Mco = zeros(SampleSize,totparam_nbr); + STO_dSPECTRUM = zeros([size(ide_spectrum.dSPECTRUM, 1), size(ide_spectrum.dSPECTRUM, 2), MAX_RUNS_BEFORE_SAVE_TO_FILE]); + IDE_SPECTRUM.ind_dSPECTRUM = ide_spectrum.ind_dSPECTRUM; + IDE_SPECTRUM.in0 = zeros(SampleSize, 1); + IDE_SPECTRUM.ind0 = zeros(SampleSize, totparam_nbr); + IDE_SPECTRUM.jweak = zeros(SampleSize, totparam_nbr); + IDE_SPECTRUM.jweak_pair = zeros(SampleSize, totparam_nbr*(totparam_nbr+1)/2); + IDE_SPECTRUM.cond = zeros(SampleSize, 1); + IDE_SPECTRUM.Mco = zeros(SampleSize, totparam_nbr); else - IDE_SPECTRUM = {}; + STO_dSPECTRUM = {}; + IDE_SPECTRUM = {}; end - + % preallocate storage for minimal system if ~options_MC.no_identification_minimal - STO_D = zeros([size(ide_minimal.D,1),size(ide_minimal.D,2), MAX_RUNS_BEFORE_SAVE_TO_FILE]); - IDE_MINIMAL.ind_D = ide_minimal.ind_D; - IDE_MINIMAL.in0 = zeros(SampleSize,1); - IDE_MINIMAL.ind0 = zeros(SampleSize,totparam_nbr); - IDE_MINIMAL.jweak = zeros(SampleSize,totparam_nbr); - IDE_MINIMAL.jweak_pair = zeros(SampleSize,totparam_nbr*(totparam_nbr+1)/2); - IDE_MINIMAL.cond = zeros(SampleSize,1); - IDE_MINIMAL.Mco = zeros(SampleSize,totparam_nbr); + STO_dMINIMAL = zeros([size(ide_minimal.dMINIMAL, 1), size(ide_minimal.dMINIMAL, 2), MAX_RUNS_BEFORE_SAVE_TO_FILE]); + IDE_MINIMAL.ind_dMINIMAL = ide_minimal.ind_dMINIMAL; + IDE_MINIMAL.in0 = zeros(SampleSize, 1); + IDE_MINIMAL.ind0 = zeros(SampleSize, totparam_nbr); + IDE_MINIMAL.jweak = zeros(SampleSize, totparam_nbr); + IDE_MINIMAL.jweak_pair = zeros(SampleSize, totparam_nbr*(totparam_nbr+1)/2); + IDE_MINIMAL.cond = zeros(SampleSize, 1); + IDE_MINIMAL.Mco = zeros(SampleSize, totparam_nbr); else - IDE_MINIMAL = {}; + STO_dMINIMAL = {}; + IDE_MINIMAL = {}; end end - + if info(1)==0 % if admissable draw iteration = iteration + 1; %increase total index of admissable draws run_index = run_index + 1; %increase index of admissable draws after saving to files pdraws(iteration,:) = params; % store draw - - % store results for linear rational expectations model - STO_LRE(:,iteration) = ide_lre.LRE; - STO_si_dLRE(:,:,run_index) = ide_lre.si_dLRE; - IDE_LRE.cond(iteration,1) = ide_lre.cond; - IDE_LRE.ino(iteration,1) = ide_lre.ino; - IDE_LRE.ind0(iteration,:) = ide_lre.ind0; - IDE_LRE.jweak(iteration,:) = ide_lre.jweak; - IDE_LRE.jweak_pair(iteration,:) = ide_lre.jweak_pair; - IDE_LRE.Mco(iteration,:) = ide_lre.Mco; - - % store results for reduced form solution + + % store results for steady state and dynamic model derivatives + STO_DYNAMIC(:,iteration) = ide_dynamic.DYNAMIC; + STO_si_dDYNAMIC(:,:,run_index) = ide_dynamic.si_dDYNAMIC; + IDE_DYNAMIC.cond(iteration,1) = ide_dynamic.cond; + IDE_DYNAMIC.ino(iteration,1) = ide_dynamic.ino; + IDE_DYNAMIC.ind0(iteration,:) = ide_dynamic.ind0; + IDE_DYNAMIC.jweak(iteration,:) = ide_dynamic.jweak; + IDE_DYNAMIC.jweak_pair(iteration,:) = ide_dynamic.jweak_pair; + IDE_DYNAMIC.Mco(iteration,:) = ide_dynamic.Mco; + + % store results for reduced form if ~options_MC.no_identification_reducedform - STO_TAU(:,iteration) = ide_reducedform.TAU; - STO_si_dTAU(:,:,run_index) = ide_reducedform.si_dTAU; + STO_REDUCEDFORM(:,iteration) = ide_reducedform.REDUCEDFORM; + STO_si_dREDUCEDFORM(:,:,run_index) = ide_reducedform.si_dREDUCEDFORM; IDE_REDUCEDFORM.cond(iteration,1) = ide_reducedform.cond; IDE_REDUCEDFORM.ino(iteration,1) = ide_reducedform.ino; IDE_REDUCEDFORM.ind0(iteration,:) = ide_reducedform.ind0; @@ -658,11 +644,11 @@ if iload <=0 IDE_REDUCEDFORM.jweak_pair(iteration,:) = ide_reducedform.jweak_pair; IDE_REDUCEDFORM.Mco(iteration,:) = ide_reducedform.Mco; end - + % store results for moments if ~options_MC.no_identification_moments STO_MOMENTS(:,iteration) = ide_moments.MOMENTS; - STO_si_J(:,:,run_index) = ide_moments.si_J; + STO_si_dMOMENTS(:,:,run_index) = ide_moments.si_dMOMENTS; IDE_MOMENTS.cond(iteration,1) = ide_moments.cond; IDE_MOMENTS.ino(iteration,1) = ide_moments.ino; IDE_MOMENTS.ind0(iteration,:) = ide_moments.ind0; @@ -670,156 +656,156 @@ if iload <=0 IDE_MOMENTS.jweak_pair(iteration,:) = ide_moments.jweak_pair; IDE_MOMENTS.Mco(iteration,:) = ide_moments.Mco; IDE_MOMENTS.S(iteration,:) = ide_moments.S; - IDE_MOMENTS.V(iteration,:,:) = ide_moments.V; + IDE_MOMENTS.V(iteration,:,:) = ide_moments.V; end - + % store results for spectrum if ~options_MC.no_identification_spectrum - STO_G(:,:,run_index) = ide_spectrum.G; + STO_dSPECTRUM(:,:,run_index) = ide_spectrum.dSPECTRUM; IDE_SPECTRUM.cond(iteration,1) = ide_spectrum.cond; IDE_SPECTRUM.ino(iteration,1) = ide_spectrum.ino; IDE_SPECTRUM.ind0(iteration,:) = ide_spectrum.ind0; IDE_SPECTRUM.jweak(iteration,:) = ide_spectrum.jweak; IDE_SPECTRUM.jweak_pair(iteration,:) = ide_spectrum.jweak_pair; - IDE_SPECTRUM.Mco(iteration,:) = ide_spectrum.Mco; + IDE_SPECTRUM.Mco(iteration,:) = ide_spectrum.Mco; end - + % store results for minimal system if ~options_MC.no_identification_minimal - STO_D(:,:,run_index) = ide_minimal.D; + STO_dMINIMAL(:,:,run_index) = ide_minimal.dMINIMAL; IDE_MINIMAL.cond(iteration,1) = ide_minimal.cond; IDE_MINIMAL.ino(iteration,1) = ide_minimal.ino; IDE_MINIMAL.ind0(iteration,:) = ide_minimal.ind0; IDE_MINIMAL.jweak(iteration,:) = ide_minimal.jweak; IDE_MINIMAL.jweak_pair(iteration,:) = ide_minimal.jweak_pair; - IDE_MINIMAL.Mco(iteration,:) = ide_minimal.Mco; + IDE_MINIMAL.Mco(iteration,:) = ide_minimal.Mco; end - + % save results to file: either to avoid running into memory issues, i.e. (run_index==MAX_RUNS_BEFORE_SAVE_TO_FILE) or if finished (iteration==SampleSize) if run_index==MAX_RUNS_BEFORE_SAVE_TO_FILE || iteration==SampleSize file_index = file_index + 1; - if run_index 1 - dyn_waitbar(iteration/SampleSize,h,['MC identification checks ',int2str(iteration),'/',int2str(SampleSize)]) + dyn_waitbar(iteration/SampleSize, h, ['MC identification checks ', int2str(iteration), '/', int2str(SampleSize)]); end end end if SampleSize > 1 dyn_waitbar_close(h); - normalize_STO_LRE = std(STO_LRE,0,2); + normalize_STO_DYNAMIC = std(STO_DYNAMIC,0,2); if ~options_MC.no_identification_reducedform - normalize_STO_TAU = std(STO_TAU,0,2); + normalize_STO_REDUCEDFORM = std(STO_REDUCEDFORM,0,2); end if ~options_MC.no_identification_moments normalize_STO_MOMENTS = std(STO_MOMENTS,0,2); end if ~options_MC.no_identification_minimal - normalize_STO_MINIMAL = 1; %not yet used + normalize_STO_MINIMAL = 1; %not used (yet) end if ~options_MC.no_identification_spectrum - normalize_STO_SPECTRUM = 1; %not yet used + normalize_STO_SPECTRUM = 1; %not used (yet) end normaliz1 = std(pdraws); iter = 0; for ifile_index = 1:file_index - load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dLRE'); - maxrun_dLRE = size(STO_si_dLRE,3); + load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dDYNAMIC'); + maxrun_dDYNAMIC = size(STO_si_dDYNAMIC,3); if ~options_MC.no_identification_reducedform - load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dTAU'); - maxrun_dTAU = size(STO_si_dTAU,3); + load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dREDUCEDFORM'); + maxrun_dREDUCEDFORM = size(STO_si_dREDUCEDFORM,3); else - maxrun_dTAU = 0; + maxrun_dREDUCEDFORM = 0; end if ~options_MC.no_identification_moments - load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_J'); - maxrun_J = size(STO_si_J,3); + load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dMOMENTS'); + maxrun_dMOMENTS = size(STO_si_dMOMENTS,3); else - maxrun_J = 0; + maxrun_dMOMENTS = 0; end if ~options_MC.no_identification_spectrum - load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_G'); - maxrun_G = size(STO_G,3); + load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_dSPECTRUM'); + maxrun_dSPECTRUM = size(STO_dSPECTRUM,3); else - maxrun_G = 0; + maxrun_dSPECTRUM = 0; end if ~options_MC.no_identification_minimal - load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_D'); - maxrun_D = size(STO_D,3); + load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_dMINIMAL'); + maxrun_dMINIMAL = size(STO_dMINIMAL,3); else - maxrun_D = 0; + maxrun_dMINIMAL = 0; end - for irun=1:max([maxrun_dLRE, maxrun_dTAU, maxrun_J, maxrun_G, maxrun_D]) + for irun=1:max([maxrun_dDYNAMIC, maxrun_dREDUCEDFORM, maxrun_dMOMENTS, maxrun_dSPECTRUM, maxrun_dMINIMAL]) iter=iter+1; - % note that this is not the same si_dLREnorm as computed in identification_analysis + % note that this is not the same si_dDYNAMICnorm as computed in identification_analysis % given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure - si_dLREnorm(iter,:) = vnorm(STO_si_dLRE(:,:,irun)./repmat(normalize_STO_LRE,1,totparam_nbr-(stderrparam_nbr+corrparam_nbr))).*normaliz1((stderrparam_nbr+corrparam_nbr)+1:end); + si_dDYNAMICnorm(iter,:) = vnorm(STO_si_dDYNAMIC(:,:,irun)./repmat(normalize_STO_DYNAMIC,1,totparam_nbr-(stderrparam_nbr+corrparam_nbr))).*normaliz1((stderrparam_nbr+corrparam_nbr)+1:end); if ~options_MC.no_identification_reducedform - % note that this is not the same si_dTAUnorm as computed in identification_analysis + % note that this is not the same si_dREDUCEDFORMnorm as computed in identification_analysis % given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure - si_dTAUnorm(iter,:) = vnorm(STO_si_dTAU(:,:,irun)./repmat(normalize_STO_TAU,1,totparam_nbr)).*normaliz1; + si_dREDUCEDFORMnorm(iter,:) = vnorm(STO_si_dREDUCEDFORM(:,:,irun)./repmat(normalize_STO_REDUCEDFORM,1,totparam_nbr)).*normaliz1; end if ~options_MC.no_identification_moments - % note that this is not the same si_Jnorm as computed in identification_analysis + % note that this is not the same si_dMOMENTSnorm as computed in identification_analysis % given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure - si_Jnorm(iter,:) = vnorm(STO_si_J(:,:,irun)./repmat(normalize_STO_MOMENTS,1,totparam_nbr)).*normaliz1; + si_dMOMENTSnorm(iter,:) = vnorm(STO_si_dMOMENTS(:,:,irun)./repmat(normalize_STO_MOMENTS,1,totparam_nbr)).*normaliz1; end if ~options_MC.no_identification_spectrum - % note that this is not the same Gnorm as computed in identification_analysis - Gnorm(iter,:) = vnorm(STO_G(:,:,irun)); %not yet used + % note that this is not the same dSPECTRUMnorm as computed in identification_analysis + dSPECTRUMnorm(iter,:) = vnorm(STO_dSPECTRUM(:,:,irun)); %not yet used end if ~options_MC.no_identification_minimal - % note that this is not the same Dnorm as computed in identification_analysis - Dnorm(iter,:) = vnorm(STO_D(:,:,irun)); %not yet used + % note that this is not the same dMINIMALnorm as computed in identification_analysis + dMINIMALnorm(iter,:) = vnorm(STO_dMINIMAL(:,:,irun)); %not yet used end end end - IDE_LRE.si_dLREnorm = si_dLREnorm; - save([IdentifDirectoryName '/' fname '_identif.mat'], 'pdraws', 'IDE_LRE','STO_LRE','-append'); + IDE_DYNAMIC.si_dDYNAMICnorm = si_dDYNAMICnorm; + save([IdentifDirectoryName '/' fname '_identif.mat'], 'pdraws', 'IDE_DYNAMIC','STO_DYNAMIC','-append'); if ~options_MC.no_identification_reducedform - IDE_REDUCEDFORM.si_dTAUnorm = si_dTAUnorm; - save([IdentifDirectoryName '/' fname '_identif.mat'], 'IDE_REDUCEDFORM', 'STO_TAU','-append'); + IDE_REDUCEDFORM.si_dREDUCEDFORMnorm = si_dREDUCEDFORMnorm; + save([IdentifDirectoryName '/' fname '_identif.mat'], 'IDE_REDUCEDFORM', 'STO_REDUCEDFORM','-append'); end if ~options_MC.no_identification_moments - IDE_MOMENTS.si_Jnorm = si_Jnorm; + IDE_MOMENTS.si_dMOMENTSnorm = si_dMOMENTSnorm; save([IdentifDirectoryName '/' fname '_identif.mat'], 'IDE_MOMENTS', 'STO_MOMENTS','-append'); - end - + end + end else @@ -835,43 +821,42 @@ end %% if dynare_identification is called as it own function (not through identification command) and if we load files if nargout>3 && iload filnam = dir([IdentifDirectoryName '/' fname '_identif_*.mat']); - STO_si_dLRE = []; - STO_si_dTAU=[]; - STO_si_J = []; - STO_G = []; - STO_D = []; + STO_si_dDYNAMIC = []; + STO_si_dREDUCEDFORM = []; + STO_si_dMOMENTS = []; + STO_dSPECTRUM = []; + STO_dMINIMAL = []; for j=1:length(filnam) load([IdentifDirectoryName '/' fname '_identif_',int2str(j),'.mat']); - STO_si_dLRE = cat(3,STO_si_dLRE, STO_si_dLRE(:,abs(iload),:)); + STO_si_dDYNAMIC = cat(3,STO_si_dDYNAMIC, STO_si_dDYNAMIC(:,abs(iload),:)); if ~options_ident.no_identification_reducedform - STO_si_dTAU = cat(3,STO_si_dTAU, STO_si_dTAU(:,abs(iload),:)); + STO_si_dREDUCEDFORM = cat(3,STO_si_dREDUCEDFORM, STO_si_dREDUCEDFORM(:,abs(iload),:)); end if ~options_ident.no_identification_moments - STO_si_J = cat(3,STO_si_J, STO_si_J(:,abs(iload),:)); + STO_si_dMOMENTS = cat(3,STO_si_dMOMENTS, STO_si_dMOMENTS(:,abs(iload),:)); end if ~options_ident.no_identification_spectrum - STO_G = cat(3,STO_G, STO_G(:,abs(iload),:)); + STO_dSPECTRUM = cat(3,STO_dSPECTRUM, STO_dSPECTRUM(:,abs(iload),:)); end if ~options_ident.no_identification_minimal - STO_D = cat(3,STO_D, STO_D(:,abs(iload),:)); + STO_dMINIMAL = cat(3,STO_dMINIMAL, STO_dMINIMAL(:,abs(iload),:)); end end end if iload %if previous analysis is loaded - disp(['Testing ',parameters]) + fprintf(['Testing %s\n',parameters]); disp_identification(ide_hess_point.params, ide_reducedform_point, ide_moments_point, ide_spectrum_point, ide_minimal_point, name, options_ident); if ~options_.nograph % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs - plot_identification(ide_hess_point.params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_lre_point, options_ident.advanced, parameters, name, IdentifDirectoryName, [],name_tex); + plot_identification(ide_hess_point.params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, options_ident.advanced, parameters, name, IdentifDirectoryName, [], name_tex); end end %displaying and plotting of results for MC sample -if SampleSize > 1 - fprintf('\n') - disp('Testing MC sample') +if SampleSize > 1 + fprintf('\nTesting MC sample\n'); %print results to console but make sure advanced=0 advanced0 = options_ident.advanced; options_ident.advanced = 0; @@ -879,10 +864,10 @@ if SampleSize > 1 options_ident.advanced = advanced0; % reset advanced setting if ~options_.nograph % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs - plot_identification(pdraws, IDE_MOMENTS, ide_hess_point, IDE_REDUCEDFORM, IDE_LRE, options_ident.advanced, 'MC sample ', name, IdentifDirectoryName, [], name_tex); + plot_identification(pdraws, IDE_MOMENTS, ide_hess_point, IDE_REDUCEDFORM, IDE_DYNAMIC, options_ident.advanced, 'MC sample ', name, IdentifDirectoryName, [], name_tex); end %advanced display and plots for MC Sample, i.e. look at draws with highest/lowest condition number - if options_ident.advanced + if options_ident.advanced jcrit = find(IDE_MOMENTS.ino); if length(jcrit) < SampleSize if isempty(jcrit) @@ -890,43 +875,39 @@ if SampleSize > 1 store_nodisplay = options_.nodisplay; options_.nodisplay = 1; % HIGHEST CONDITION NUMBER - [~, jmax] = max(IDE_MOMENTS.cond); - fprintf('\n') + [~, jmax] = max(IDE_MOMENTS.cond); tittxt = 'Draw with HIGHEST condition number'; - fprintf('\n') - disp(['Testing ',tittxt, '.']), + 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_lre_max, derivatives_info_max, info_max, options_ident] = ... + [ide_moments_max, ide_spectrum_max, ide_minimal_max, ide_hess_max, ide_reducedform_max, ide_dynamic_max, derivatives_info_max, info_max, options_ident] = ... identification_analysis(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_lre_max', 'jmax', '-append'); - end + 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 advanced0 = options_ident.advanced; options_ident.advanced = 1; % make sure advanced setting is on disp_identification(pdraws(jmax,:), ide_reducedform_max, ide_moments_max, ide_spectrum_max, ide_minimal_max, name, options_ident); - options_ident.advanced = advanced0; %reset advanced setting + options_ident.advanced = advanced0; %reset advanced setting if ~options_.nograph % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs - plot_identification(pdraws(jmax,:), ide_moments_max, ide_hess_max, ide_reducedform_max, ide_lre_max, 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex); + plot_identification(pdraws(jmax,:), ide_moments_max, ide_hess_max, ide_reducedform_max, ide_dynamic_max, 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex); end - + % SMALLEST condition number [~, jmin] = min(IDE_MOMENTS.cond); - fprintf('\n') tittxt = 'Draw with SMALLEST condition number'; - fprintf('\n') - disp(['Testing ',tittxt, '.']), + fprintf('Testing %s.\n',tittxt); if ~iload options_ident.tittxt = tittxt; %title text for graphs and figures - [ide_moments_min, ide_spectrum_min, ide_minimal_min, ide_hess_min, ide_reducedform_min, ide_lre_min, derivatives_info_min, info_min, options_ident] = ... + [ide_moments_min, ide_spectrum_min, ide_minimal_min, ide_hess_min, ide_reducedform_min, ide_dynamic_min, derivatives_info_min, info_min, options_ident] = ... identification_analysis(pdraws(jmin,:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end initializes persistent variables - save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_min', 'ide_moments_min','ide_spectrum_min','ide_minimal_min','ide_reducedform_min', 'ide_lre_min', 'jmin', '-append'); + save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_min', 'ide_moments_min','ide_spectrum_min','ide_minimal_min','ide_reducedform_min', 'ide_dynamic_min', 'jmin', '-append'); end advanced0 = options_ident.advanced; options_ident.advanced = 1; % make sure advanced setting is on disp_identification(pdraws(jmin,:), ide_reducedform_min, ide_moments_min, ide_spectrum_min, ide_minimal_min, name, options_ident); options_ident.advanced = advanced0; %reset advanced setting if ~options_.nograph % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs - plot_identification(pdraws(jmin,:),ide_moments_min,ide_hess_min,ide_reducedform_min,ide_lre_min,1,tittxt,name,IdentifDirectoryName,tittxt,name_tex); + plot_identification(pdraws(jmin,:),ide_moments_min,ide_hess_min,ide_reducedform_min,ide_dynamic_min,1,tittxt,name,IdentifDirectoryName,tittxt,name_tex); end % reset nodisplay option options_.nodisplay = store_nodisplay; @@ -935,27 +916,26 @@ if SampleSize > 1 store_nodisplay = options_.nodisplay; options_.nodisplay = 1; for j=1:length(jcrit) - tittxt = ['Rank deficient draw n. ',int2str(j)]; - fprintf('\n') - disp(['Testing ',tittxt, '.']), + tittxt = ['Rank deficient draw nr. ',int2str(j)]; + fprintf('\nTesting %s.\n',tittxt); if ~iload options_ident.tittxt = tittxt; %title text for graphs and figures - [ide_moments_(j), ide_spectrum_(j), ide_minimal_(j), ide_hess_(j), ide_reducedform_(j), ide_lre_(j), derivatives_info_(j), info_resolve, options_ident] = ... + [ide_moments_(j), ide_spectrum_(j), ide_minimal_(j), ide_hess_(j), ide_reducedform_(j), ide_dynamic_(j), derivatives_info_(j), info_resolve, options_ident] = ... identification_analysis(pdraws(jcrit(j),:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); end advanced0 = options_ident.advanced; options_ident.advanced = 1; %make sure advanced setting is on disp_identification(pdraws(jcrit(j),:), ide_reducedform_(j), ide_moments_(j), ide_spectrum_(j), ide_minimal_(j), name, options_ident); - options_ident.advanced = advanced0; % reset advanced + options_ident.advanced = advanced0; % reset advanced if ~options_.nograph % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs - plot_identification(pdraws(jcrit(j),:), ide_moments_(j), ide_hess_(j), ide_reducedform_(j), ide_lre_(j), 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex); + plot_identification(pdraws(jcrit(j),:), ide_moments_(j), ide_hess_(j), ide_reducedform_(j), ide_dynamic_(j), 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex); end end if ~iload - save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_', 'ide_moments_', 'ide_reducedform_', 'ide_lre_', 'ide_spectrum_', 'ide_minimal_', 'jcrit', '-append'); + save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_', 'ide_moments_', 'ide_reducedform_', 'ide_dynamic_', 'ide_spectrum_', 'ide_minimal_', 'jcrit', '-append'); end % reset nodisplay option - options_.nodisplay = store_nodisplay; + options_.nodisplay = store_nodisplay; end end end @@ -968,8 +948,6 @@ else warning on end -skipline() -disp('==== Identification analysis completed ====') -skipline(2) +fprintf('\n==== Identification analysis completed ====\n\n') -options_ = store_options_; %restore options set +options_ = store_options_; %restore options set \ No newline at end of file diff --git a/matlab/dynare_resolve.m b/matlab/dynare_resolve.m index 5fcbc7151..6e4b5b217 100644 --- a/matlab/dynare_resolve.m +++ b/matlab/dynare_resolve.m @@ -49,7 +49,7 @@ function [A,B,ys,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model, %! @end deftypefn %@eod: -% Copyright (C) 2001-2017 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -66,8 +66,7 @@ function [A,B,ys,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model, % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -[dr,info,Model,DynareOptions,DynareResults] = resol(0,Model,DynareOptions,DynareResults); -DynareResults.dr = dr; +[dr,info,Model,DynareOptions,DynareResults] =compute_decision_rules(Model,DynareOptions,DynareResults); if info(1) > 0 A = []; diff --git a/matlab/dynare_solve.m b/matlab/dynare_solve.m index 835d55d51..e50ea6670 100644 --- a/matlab/dynare_solve.m +++ b/matlab/dynare_solve.m @@ -86,6 +86,10 @@ if jacobian_flag wrong_initial_guess_flag = false; if ~all(isfinite(fvec)) || any(isinf(fjac(:))) || any(isnan((fjac(:)))) ... || any(~isreal(fvec)) || any(~isreal(fjac(:))) + if max(abs(fvec)) < tolf %return if initial value solves problem + info = 0; + return; + end disp('Randomize initial guess...') % Let's try random numbers for the variables initialized with the default value. wrong_initial_guess_flag = true; diff --git a/matlab/dynare_solve_block_or_bytecode.m b/matlab/dynare_solve_block_or_bytecode.m index c995c93c7..f991f54f5 100644 --- a/matlab/dynare_solve_block_or_bytecode.m +++ b/matlab/dynare_solve_block_or_bytecode.m @@ -1,5 +1,5 @@ function [x,info] = dynare_solve_block_or_bytecode(y, exo, params, options, M) -% Copyright (C) 2010-2017 Dynare Team +% Copyright (C) 2010-2020 Dynare Team % % This file is part of Dynare. % @@ -51,9 +51,10 @@ if options.block && ~options.bytecode end elseif options.bytecode if options.solve_algo > 4 - [check, x] = bytecode('static', x, exo, params); - % mexErrCheck('bytecode', check); - if check + try + x = bytecode('static', x, exo, params); + catch ME + disp(ME.message); info = 1; return end @@ -73,10 +74,12 @@ elseif options.bytecode end x(M.block_structure_stat.block(b).variable) = y; else - [chk, nulldev, nulldev1, x] = bytecode( x, exo, params, ... - x, 1, x, 'evaluate', 'static', ... - ['block = ' int2str(b)]); - if chk + try + [nulldev, nulldev1, x] = bytecode(x, exo, params, ... + x, 1, x, 'evaluate', 'static', ... + ['block = ' int2str(b)]); + catch ME + disp(ME.message); info = 1; return end diff --git a/matlab/dynasave.m b/matlab/dynasave.m index 45642a8ca..d80aa98ab 100644 --- a/matlab/dynasave.m +++ b/matlab/dynasave.m @@ -1,6 +1,6 @@ -function dynasave(s, var_list) +function dynasave(s,var_list) % function dynasave(s,var_list) -% This optional command saves the simulation results in a .MAT file. +% This command saves the simulation results in a .MAT file. % % INPUTS % s: filename @@ -12,7 +12,7 @@ function dynasave(s, var_list) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2018 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -39,20 +39,19 @@ if ~isfield(oo_, 'endo_simul') || isempty(oo_.endo_simul) error('dynasave:: The results structure does not contain simulated series. Maybe the periods option has not been set.') end -n = length(var_list); -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') ; +for i = 1:length(var_list) + idx = strcmp(var_list{i}, M_.endo_names); + if any(idx) + SaveStruct.(var_list{i}) = oo_.endo_simul(idx,:); else - ivar(i) = i_tmp; + idx = strcmp(var_list{i}, M_.exo_names); + if any(idx) + SaveStruct.(var_list{i}) = oo_.exo_simul(:,idx); + else + error(['Should not arrive here: ' var_list{i} ' not found in M_.endo_names or M_.exo_names']) ; + end end end -eval([var_list{1} ' = oo_.endo_simul(ivar(1),:)'';']) -eval(['save ' s ' ' var_list{1} ' -mat']) -for dynare__i_ = 2:n - eval([var_list{dynare__i_} ' = oo_.endo_simul(ivar(dynare__i_),:)'';']) - eval(['save ' s ' ' var_list{dynare__i_} ' -append -mat']) +save(s, '-struct', 'SaveStruct'); end diff --git a/matlab/dynatype.m b/matlab/dynatype.m index 33f318267..c0fe8c4d3 100644 --- a/matlab/dynatype.m +++ b/matlab/dynatype.m @@ -1,6 +1,6 @@ function dynatype (s,var_list) % function dynatype (s,var_list) -% This optional command saves the simulation results in a text file. The name of each +% This command saves the simulation results in a text file. The name of each % variable preceeds the corresponding results. This command must follow SIMUL. % % INPUTS @@ -13,7 +13,7 @@ function dynatype (s,var_list) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2018 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -32,29 +32,27 @@ function dynatype (s,var_list) global M_ oo_ -fid=fopen(s,'w') ; +fid = fopen(s, 'w'); if isempty(var_list) var_list = M_.endo_names(1:M_.orig_endo_nbr); end -n = length(var_list); -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') ; +for i = 1:length(var_list) + idx = strcmp(var_list{i}, M_.endo_names); + if any(idx) + fprintf(fid, '%s\n', M_.endo_names{idx}); + fprintf(fid, '%15.8g\n', oo_.endo_simul(idx,:)'); else - ivar(i) = i_tmp; + idx = strcmp(var_list{i}, M_.exo_names); + if any(idx) + fprintf(fid, '%s\n', M_.exo_names{idx}); + fprintf(fid, '%15.8g\n', oo_.exo_simul(:,idx)); + else + error(['Should not arrive here: ' var_list{i} ' not found in M_.endo_names or M_.exo_names']) ; + end end end -for i = 1:n - fprintf(fid,M_.endo_names{ivar(i)},'\n') ; - fprintf(fid,'\n') ; - fprintf(fid,'%15.8g\n',oo_.endo_simul(ivar(i),:)') ; +fclose(fid); end -fclose(fid) ; - -return ; diff --git a/matlab/dyntable.m b/matlab/dyntable.m index 27a8305f8..d04504fa6 100644 --- a/matlab/dyntable.m +++ b/matlab/dyntable.m @@ -2,7 +2,7 @@ function dyntable(options_, title, headers, labels, values, label_width, val_wid % Prints a table of results in main command window. % -% INPUTS +% INPUTS % - options_ [structure] Dynare options structure % - title [string] Table title % - headers [cell] labels for header row (each element is a row characater array) @@ -12,7 +12,7 @@ function dyntable(options_, title, headers, labels, values, label_width, val_wid % - val_width [integer] scalar, width of value column % - val_precis [integer] scalar, precision of displayed values % -% OUTPUTS +% OUTPUTS % none % Copyright (C) 2002-2018 Dynare Team diff --git a/matlab/ep/euler_equation_error.m b/matlab/ep/euler_equation_error.m index ea2f6a934..f2b9a896e 100644 --- a/matlab/ep/euler_equation_error.m +++ b/matlab/ep/euler_equation_error.m @@ -15,7 +15,7 @@ function e = euler_equation_error(y0,x,innovations,M,options,oo,pfm,nodes,weight % 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 . +% along with Dynare. If not, see . dynamic_model = str2func([M.fname '.dynamic']); ep = options.ep; diff --git a/matlab/ep/extended_path.m b/matlab/ep/extended_path.m index f0d6b0e0f..c7bfdb23e 100644 --- a/matlab/ep/extended_path.m +++ b/matlab/ep/extended_path.m @@ -80,7 +80,7 @@ while (t <= samplesize) warning(msg) break end -end% (while) loop over t +end % (while) loop over t % Close waitbar. dyn_waitbar_close(hh); diff --git a/matlab/ep/extended_path_core.m b/matlab/ep/extended_path_core.m index 1768c0bbd..eb8b2454d 100644 --- a/matlab/ep/extended_path_core.m +++ b/matlab/ep/extended_path_core.m @@ -4,7 +4,7 @@ function [y, info_convergence, endogenousvariablespaths] = extended_path_core(pe debug,bytecode_flag,order,M,pfm,algo,solve_algo,stack_solve_algo,... olmmcp,options,oo,initialguess) -% Copyright (C) 2016-2019 Dynare Team +% Copyright (C) 2016-2020 Dynare Team % % This file is part of Dynare. % @@ -41,7 +41,13 @@ if debug end if bytecode_flag && ~ep.stochastic.order - [flag, tmp] = bytecode('dynamic', endo_simul, exo_simul, M_.params, endo_simul, periods); + try + tmp = bytecode('dynamic', endo_simul, exo_simul, M_.params, endo_simul, periods); + flag = false; + catch ME + disp(ME.message); + flag = true; + end else flag = true; end @@ -86,4 +92,4 @@ else y = NaN(size(endo_nbr,1)); end -endogenousvariablespaths = tmp.endo_simul; \ No newline at end of file +endogenousvariablespaths = tmp.endo_simul; diff --git a/matlab/epilogue_shock_decomposition.m b/matlab/epilogue_shock_decomposition.m new file mode 100644 index 000000000..4a76cd2de --- /dev/null +++ b/matlab/epilogue_shock_decomposition.m @@ -0,0 +1,41 @@ +function [zout, zss] = epilogue_shock_decomposition(zout ,M_, oo_) + +ivar = varlist_indices(M_.epilogue_var_list_,M_.endo_names); +y = nan(length(M_.epilogue_names),size(zout,2),size(zout,3)); +z=zout(ivar,:,:); +if isfield(oo_.dr,'ys') + zss = oo_.dr.ys; +else + zss = oo_.steady_state; +end + +ztmp = dseries(zss(ivar),'',M_.epilogue_var_list_); +fname = M_.fname; +h_dynamic = str2func([fname '.epilogue_dynamic']); +h_static = str2func([fname '.epilogue_static']); +yss = extract(h_static(M_.params, ztmp),M_.epilogue_names{:}); +yss = yss.data; +yss1 = repmat(yss(:),[1,1,size(y,3)]); +for k=1:size(z,2) + ztmp = dseries(squeeze(z(:,k,:))+zss(ivar),'',M_.epilogue_var_list_); + tmp = extract(h_dynamic(M_.params, ztmp),M_.epilogue_names{:}); + y(:,k,:) = tmp.data'; + y(:,k,:) = y(:,k,:)-yss1; +end + +nterms = size(z,2); +for k=1:size(y,1) + ytmp = squeeze(y(k,:,:)); + yres = ytmp(end,:) - sum(ytmp(1:end-1,:)); + if ~isoctave && matlab_ver_less_than('9.1') % Automatic broadcasting was introduced in MATLAB R2016b + w = bsxfun(@rdivide, abs(ytmp(1:end-1,:)), sum(abs(ytmp(1:end-1,:)))) + else + w = abs(ytmp(1:end-1,:))./sum(abs(ytmp(1:end-1,:))); + end + % ytmp(1:end-1,:) = ytmp(1:end-1,:) + repmat(yres,[nterms-1 1])/(nterms-1); + ytmp(1:end-1,:) = ytmp(1:end-1,:) + repmat(yres,[nterms-1 1]).*w; + y(k,:,:) = ytmp; +end + +zout = cat(1,zout,y); +zss = [zss; yss(:)]; diff --git a/matlab/evaluate_planner_objective.m b/matlab/evaluate_planner_objective.m index d0a06d771..63ec0ab6a 100644 --- a/matlab/evaluate_planner_objective.m +++ b/matlab/evaluate_planner_objective.m @@ -11,7 +11,7 @@ function planner_objective_value = evaluate_planner_objective(M,options,oo) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2007-2018 Dynare Team +% Copyright (C) 2007-2020 Dynare Team % % This file is part of Dynare. % @@ -28,14 +28,17 @@ function planner_objective_value = evaluate_planner_objective(M,options,oo) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +if options.order>1 + fprintf('\nevaluate_planner_objective: order>1 not yet supported\n') + planner_objective_value = NaN; + return +end dr = oo.dr; exo_nbr = M.exo_nbr; nstatic = M.nstatic; nspred = M.nspred; if nspred > 180 - disp(' ') - disp(['WARNING in evaluate_planner_objective: model too large, can''t evaluate planner ' ... - 'objective']) + fprintf('\nevaluate_planner_objective: model too large, can''t evaluate planner objective\n') planner_objective_value = NaN; return end @@ -54,21 +57,16 @@ ys = oo.dr.ys; %second order terms Uyy = full(Uyy); -[Uyygygy, err] = A_times_B_kronecker_C(Uyy,gy,gy); -mexErrCheck('A_times_B_kronecker_C', err); -[Uyygugu, err] = A_times_B_kronecker_C(Uyy,gu,gu); -mexErrCheck('A_times_B_kronecker_C', err); -[Uyygygu, err] = A_times_B_kronecker_C(Uyy,gy,gu); -mexErrCheck('A_times_B_kronecker_C', err); +Uyygygy = A_times_B_kronecker_C(Uyy,gy,gy); +Uyygugu = A_times_B_kronecker_C(Uyy,gu,gu); +Uyygygu = A_times_B_kronecker_C(Uyy,gy,gu); Wbar =U/(1-beta); %steady state welfare Wy = Uy*gy/(eye(nspred)-beta*Gy); Wu = Uy*gu+beta*Wy*Gu; Wyy = Uyygygy/(eye(nspred*nspred)-beta*kron(Gy,Gy)); -[Wyygugu, err] = A_times_B_kronecker_C(Wyy,Gu,Gu); -mexErrCheck('A_times_B_kronecker_C', err); -[Wyygygu,err] = A_times_B_kronecker_C(Wyy,Gy,Gu); -mexErrCheck('A_times_B_kronecker_C', err); +Wyygugu = A_times_B_kronecker_C(Wyy,Gu,Gu); +Wyygygu = A_times_B_kronecker_C(Wyy,Gy,Gu); Wuu = Uyygugu+beta*Wyygugu; Wyu = Uyygygu+beta*Wyygygu; Wss = beta*Wuu*M.Sigma_e(:)/(1-beta); % at period 0, we are in steady state, so the deviation term only starts in period 1, thus the beta in front @@ -90,34 +88,27 @@ end yhat1 = yhat1(dr.order_var(nstatic+(1:nspred)),1)-dr.ys(dr.order_var(nstatic+(1:nspred))); u = oo.exo_simul(1,:)'; -[Wyyyhatyhat1, err] = A_times_B_kronecker_C(Wyy,yhat1,yhat1); -mexErrCheck('A_times_B_kronecker_C', err); -[Wuuuu, err] = A_times_B_kronecker_C(Wuu,u,u); -mexErrCheck('A_times_B_kronecker_C', err); -[Wyuyhatu1, err] = A_times_B_kronecker_C(Wyu,yhat1,u); -mexErrCheck('A_times_B_kronecker_C', err); +Wyyyhatyhat1 = A_times_B_kronecker_C(Wyy,yhat1,yhat1); +Wuuuu = A_times_B_kronecker_C(Wuu,u,u); +Wyuyhatu1 = A_times_B_kronecker_C(Wyu,yhat1,u); planner_objective_value(1) = Wbar+Wy*yhat1+Wu*u+Wyuyhatu1 ... + 0.5*(Wyyyhatyhat1 + Wuuuu+Wss); if options.ramsey_policy yhat2 = yhat2(dr.order_var(nstatic+(1:nspred)),1)-dr.ys(dr.order_var(nstatic+(1:nspred))); - [Wyyyhatyhat2, err] = A_times_B_kronecker_C(Wyy,yhat2,yhat2); - mexErrCheck('A_times_B_kronecker_C', err); - [Wyuyhatu2, err] = A_times_B_kronecker_C(Wyu,yhat2,u); - mexErrCheck('A_times_B_kronecker_C', err); + Wyyyhatyhat2 = A_times_B_kronecker_C(Wyy,yhat2,yhat2); + Wyuyhatu2 = A_times_B_kronecker_C(Wyu,yhat2,u); planner_objective_value(2) = Wbar+Wy*yhat2+Wu*u+Wyuyhatu2 ... + 0.5*(Wyyyhatyhat2 + Wuuuu+Wss); end if ~options.noprint - skipline() - disp('Approximated value of planner objective function') + fprintf('\nApproximated value of planner objective function\n') if options.ramsey_policy - disp([' - with initial Lagrange multipliers set to 0: ' ... - num2str(planner_objective_value(2)) ]) - disp([' - with initial Lagrange multipliers set to steady state: ' ... - num2str(planner_objective_value(1)) ]) + fprintf(' - with initial Lagrange multipliers set to 0: %10.8f\n', ... + planner_objective_value(2)) + fprintf(' - with initial Lagrange multipliers set to steady state: %10.8f\n\n', ... + planner_objective_value(1)) elseif options.discretionary_policy - fprintf('with discretionary policy: %10.8f',planner_objective_value(1)) + fprintf('with discretionary policy: %10.8f\n\n',planner_objective_value(1)) end - skipline() end diff --git a/matlab/evaluate_smoother.m b/matlab/evaluate_smoother.m index c22cc0635..62d5b3531 100644 --- a/matlab/evaluate_smoother.m +++ b/matlab/evaluate_smoother.m @@ -37,7 +37,7 @@ function [oo_,M_,options_,bayestopt_,Smoothed_variables_declaration_order_deviat % [1] This function use persistent variables for the dataset and the description of the missing observations. Consequently, if this function % is called more than once (by changing the value of parameters) the sample *must not* change. -% Copyright (C) 2010-2017 Dynare Team +% Copyright (C) 2010-2020 Dynare Team % % This file is part of Dynare. % @@ -111,3 +111,4 @@ end %reset qz_criterium options_.qz_criterium=qz_criterium_old; +oo_.gui.ran_calib_smoother = true; diff --git a/matlab/evaluate_static_model.m b/matlab/evaluate_static_model.m index d15005aa2..fbcfa235c 100644 --- a/matlab/evaluate_static_model.m +++ b/matlab/evaluate_static_model.m @@ -20,7 +20,7 @@ function [residuals,check1,jacob] = evaluate_static_model(ys,exo_ss,params,M,opt % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2017 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -39,9 +39,8 @@ function [residuals,check1,jacob] = evaluate_static_model(ys,exo_ss,params,M,opt check1 = 0; if options.bytecode - [check1, residuals] = bytecode('evaluate','static',ys,... - exo_ss, params, ys, 1); - mexErrCheck('bytecode', check1); + residuals = bytecode('evaluate','static',ys,... + exo_ss, params, ys, 1); else fh_static = str2func([M.fname '.static']); if options.block diff --git a/matlab/evaluate_steady_state.m b/matlab/evaluate_steady_state.m index 12507a2b4..8fc5826c8 100644 --- a/matlab/evaluate_steady_state.m +++ b/matlab/evaluate_steady_state.m @@ -22,7 +22,7 @@ function [ys,params,info] = evaluate_steady_state(ys_init,M,options,oo,steadysta % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2018 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -307,8 +307,7 @@ if M.static_and_dynamic_models_differ z = repmat(ys,1,M.maximum_lead + M.maximum_lag + 1); zx = repmat([exo_ss'], M.maximum_lead + M.maximum_lag + 1, 1); if options.bytecode - [chck, r, ~]= bytecode('dynamic','evaluate', z, zx, params, ys, 1); - mexErrCheck('bytecode', chck); + [r, ~]= bytecode('dynamic','evaluate', z, zx, params, ys, 1); elseif options.block [r, oo.dr] = feval([M.fname '.dynamic'], z', zx, params, ys, M.maximum_lag+1, oo.dr); else diff --git a/matlab/expand_group.m b/matlab/expand_group.m index 4700de889..0992e4967 100644 --- a/matlab/expand_group.m +++ b/matlab/expand_group.m @@ -51,6 +51,7 @@ for j=1:length(shocks) M.shock_groups.(options.plot_shock_decomp.use_shock_groups).(['group' int2str(j)]).label=shocks{j}; M.shock_groups.(options.plot_shock_decomp.use_shock_groups).(['group' int2str(j)]).shocks=shocks(j); end +M.exo_names = mydata.exo_names; options.plot_shock_decomp.interactive=0; options.plot_shock_decomp.expand=1; @@ -66,4 +67,4 @@ options.plot_shock_decomp.colormap = MAP; options.plot_shock_decomp.endo_names = mydata.endo_names; options.plot_shock_decomp.endo_names_tex = mydata.endo_names_tex; -plot_shock_decomposition(M,oo,options,var_list_); +plot_shock_decomposition(M,oo,options,{var_list_}); diff --git a/matlab/fjaco.m b/matlab/fjaco.m index 9b6f68abc..566d2b729 100644 --- a/matlab/fjaco.m +++ b/matlab/fjaco.m @@ -10,7 +10,7 @@ function fjac = fjaco(f,x,varargin) % OUTPUT % fjac : finite difference Jacobian % -% Copyright (C) 2010-2017 Dynare Team +% Copyright (C) 2010-2017,2019-2020 Dynare Team % % This file is part of Dynare. % @@ -29,7 +29,10 @@ function fjac = fjaco(f,x,varargin) ff=feval(f,x,varargin{:}); -tol = eps.^(1/3); +tol = eps.^(1/3); %some default value +if strcmp(func2str(f),'get_perturbation_params_derivs_numerical_objective') || strcmp(func2str(f),'identification_numerical_objective') + tol= varargin{5}.dynatol.x; +end h = tol.*max(abs(x),1); xh1=x+h; xh0=x-h; h=xh1-xh0; @@ -37,8 +40,34 @@ fjac = NaN(length(ff),length(x)); for j=1:length(x) xx = x; xx(j) = xh1(j); f1=feval(f,xx,varargin{:}); + if isempty(f1) && (strcmp(func2str(f),'get_perturbation_params_derivs_numerical_objective') || strcmp(func2str(f),'identification_numerical_objective') ) + [~,info]=feval(f,xx,varargin{:}); + disp_info_error_identification_perturbation(info,j); + end xx(j) = xh0(j); f0=feval(f,xx,varargin{:}); + if isempty(f0) && (strcmp(func2str(f),'get_perturbation_params_derivs_numerical_objective') || strcmp(func2str(f),'identification_numerical_objective') ) + [~,info]=feval(f,xx,varargin{:}); + disp_info_error_identification_perturbation(info,j) + end fjac(:,j) = (f1-f0)/h(j); end feval(f,x,varargin{:}); + +%Auxiliary functions +function disp_info_error_identification_perturbation(info,j) + % there are errors in the solution algorithm + probl_par = get_the_name(j,varargin{5}.TeX,varargin{3},varargin{2},varargin{5}); + skipline() + message = get_error_message(info,varargin{5}); + fprintf('Parameter error in numerical two-sided difference method:\n') + fprintf('Cannot solve the model for %s (info = %d, %s)\n', probl_par, info(1), message); + fprintf('Possible solutions:\n') + fprintf(' -- check your mod file, calibration and steady state computations carefully\n'); + fprintf(' -- use analytic derivatives, i.e. set analytic_derivation_mode=0\n'); + fprintf(' -- use an estimated_params block without %s or change its value\n', probl_par); + fprintf(' -- change numerical tolerance level in fjaco.m (you can tune ''options_.dynatol.x'' or change fjaco.m function directly)\n'); + error('fjaco.m: numerical two-sided difference method yields errors in solution algorithm'); +end + +end %main function end \ No newline at end of file diff --git a/matlab/get_error_message.m b/matlab/get_error_message.m new file mode 100644 index 000000000..c4ed1148a --- /dev/null +++ b/matlab/get_error_message.m @@ -0,0 +1,171 @@ +function message = get_error_message(info, DynareOptions) +% Returns error messages +% +% INPUTS +% info [double] vector returned by resol.m +% DynareOptions [structure] --> options_ +% OUTPUTS +% message [string] corresponding error message +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2005-2020 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 . + +switch info(1) + case 0 + message = ''; + case 1 + message = 'The model doesn''t determine the current variable uniquely.'; + case 2 + message = sprintf('The generalized Schur (QZ) decomposition failed. For more information, see the documentation for Lapack function dgges: info=%d, n=%d. You can also run model_diagnostics to get more information on what may cause this problem.', info(2), info(3)); + case 3 + message = 'Blanchard & Kahn conditions are not satisfied: no stable equilibrium.'; + case 4 + message = 'Blanchard & Kahn conditions are not satisfied: indeterminacy.'; + case 5 + message = 'Blanchard & Kahn conditions are not satisfied: indeterminacy due to rank failure.'; + case 6 + message = 'The Jacobian matrix evaluated at the steady state contains elements that are not real or are infinite.'; + case 7 + message = sprintf('One of the eigenvalues is close to 0/0 (the absolute value of numerator and denominator is smaller than %5.4f!\n If you believe that the model has a unique solution you can try to reduce the value of qz_zero_threshold.',DynareOptions.qz_zero_threshold); + case 8 + if size(info,2)>=2 + global M_; + disp_string = M_.param_names{info(2)}; + for ii=1:length(info)-2 + disp_string = [disp_string, ', ', M_.param_names{info(2+ii)}]; + end + message = ['The Jacobian contains NaNs because the following parameters are NaN: ' disp_string]; + else + message = 'The Jacobian contains NaNs. For more information, use options_.debug.'; + end + case 9 + message = 'k_order_pert was unable to compute the solution'; + case 10 + message = 'The Jacobian of the dynamic model contains Inf. For more information, use options_.debug.'; + case 11 + message = 'The Hessian of the dynamic model used for second order solutions must not contain Inf'; + case 12 + message = 'The Hessian of the dynamic model used for second order solutions must not contain NaN'; + case 19 + message = 'The steadystate file did not compute the steady state'; + case 20 + if DynareOptions.linear + message = sprintf('Impossible to find the steady state (the sum of square residuals of the static equations is %5.4f). Either the model doesn''t have a steady state or there are an infinity of steady states Check whether your model is truly linear or whether there is a mistake in linearization.', info(2)); + else + message = sprintf('Impossible to find the steady state (the sum of square residuals of the static equations is %5.4f). Either the model doesn''t have a steady state, there are an infinity of steady states, or the guess values are too far from the solution', info(2)); + end + case 21 + message = sprintf('The steady state is complex (the sum of square residuals of imaginary parts of the steady state is %5.4f)', info(2)); + case 22 + message = 'The steady state has NaNs or Inf.'; + case 23 + message = 'Parameters have been updated in the steadystate routine and some have complex values.'; + case 24 + message = 'Parameters have been updated in the steadystate routine and some are NaNs or Inf.'; + case 25 + message = 'The solution to the static equations is not a steady state of the dynamic model: verify that the equations tagged by [static] and [dynamic] are consistent'; + case 26 + message = 'The loglinearization of the model cannot be performed, because the steady state is not strictly positive.'; + case 30 + message = 'Ergodic variance can''t be computed.'; + case 41 + message = 'one (many) parameter(s) do(es) not satisfy the lower bound'; + case 42 + message = 'one (many) parameter(s) do(es) not satisfy the upper bound'; + case 43 + message = 'Covariance matrix of structural shocks is not positive definite'; + case 44 %DsgeLikelihood_hh / dsge_likelihood + message = 'The covariance matrix of the measurement errors is not positive definite.'; + case 45 %DsgeLikelihood_hh / dsge_likelihood + message = 'Likelihood is not a number (NaN) or a complex number'; + case 46 %DsgeLikelihood_hh / dsge_likelihood + message = 'Likelihood is a complex number'; + case 47 %DsgeLikelihood_hh / dsge_likelihood + message = 'Prior density is not a number (NaN)'; + case 48 %DsgeLikelihood_hh / dsge_likelihood + message = 'Prior density is a complex number'; + case 49 + message = 'The model violates one (many) endogenous prior restriction(s)'; + case 50 + message = 'Likelihood is Inf'; + case 51 + message = sprintf('\n The dsge_prior_weight is dsge_var=%5.4f, but must be at least %5.4f for the prior to be proper.\n You are estimating a DSGE-VAR model, but the value of the dsge prior weight is too low!', info(2), info(3)); + case 52 %dsge_var_likelihood + message = 'You are estimating a DSGE-VAR model, but the implied covariance matrix of the VAR''s innovations, based on artificial and actual sample is not positive definite!'; + case 53 %dsge_var_likelihood + message = 'You are estimating a DSGE-VAR model, but the implied covariance matrix of the VAR''s innovations, based on the artificial sample, is not positive definite!'; + case 55 + message = 'Fast Kalman filter only works with stationary models [lik_init=1] or stationary observables for non-stationary models [lik_init=3]'; + case 61 %Discretionary policy + message = 'Discretionary policy: maximum number of iterations has been reached. Procedure failed.'; + case 62 + message = 'Discretionary policy: some eigenvalues greater than options_.qz_criterium. Model potentially unstable.'; + case 63 + message = 'Discretionary policy: NaN elements are present in the solution. Procedure failed.'; + case 64 + message = 'discretionary_policy: the derivatives of the objective function contain NaN.'; + case 65 + message = 'discretionary_policy: the model must be written in deviation form and not have constant terms.'; + case 66 + message = 'discretionary_policy: the objective function must have zero first order derivatives.'; + case 71 + message = 'Calibrated covariance of the structural errors implies correlation larger than +-1.'; + case 72 + message = 'Calibrated covariance of the measurement errors implies correlation larger than +-1.'; + % Aim Code Conversions by convertAimCodeToInfo.m + case 81 + message = ['Ramsey: The solution to the static first order conditions for optimal policy could not be found. Either the model' ... + ' doesn''t have a steady state, there are an infinity of steady states, ' ... + ' or the guess values are too far from the solution']; + case 82 + message = 'Ramsey: The steady state computation resulted in NaN in the static first order conditions for optimal policy'; + case 83 + message = 'Ramsey: The steady state computation resulted in NaN in the auxiliary equations for optimal policy'; + case 84 + message = 'Ramsey: The steady state file computation for the Ramsey problem resulted in NaNs at the initial values of the instruments'; + case 85 + message = 'Ramsey: The steady state file does not solve the static first order conditions conditional on the instruments.'; + case 86 + message = 'Ramsey: The steady state file provides complex numbers conditional on the instruments.'; + case 87 + message = 'Ramsey: The maximum number of iterations has been reached. Try increasing maxit.'; + case 102 + message = 'Aim: roots not correctly computed by real_schur'; + case 103 + message = 'Aim: too many explosive roots: no stable equilibrium'; + case 135 + message = 'Aim: too many explosive roots, and q(:,right) is singular'; + case 104 + message = 'Aim: too few explosive roots: indeterminacy'; + case 145 + message = 'Aim: too few explosive roots, and q(:,right) is singular'; + case 105 + message = 'Aim: q(:,right) is singular'; + case 161 + message = 'Aim: too many exact shiftrights'; + case 162 + message = 'Aim: too many numeric shiftrights'; + case 163 + message = 'Aim: A is NAN or INF.'; + case 164 + message = 'Aim: Problem in SPEIG.'; + otherwise + message = 'This case shouldn''t happen. Contact the authors of Dynare'; +end \ No newline at end of file diff --git a/matlab/get_first_order_solution_params_deriv.m b/matlab/get_first_order_solution_params_deriv.m deleted file mode 100644 index 6cf4b0cc5..000000000 --- a/matlab/get_first_order_solution_params_deriv.m +++ /dev/null @@ -1,959 +0,0 @@ -function [dA, dB, dSigma_e, dOm, dYss, dg1, d2A, d2Om, d2Yss] = get_first_order_solution_params_deriv(A, B, estim_params, M, oo, options, kronflag, indpmodel, indpstderr, indpcorr, indvar) -%[dA, dB, dSigma_e, dOm, dYss, dg1, d2A, d2Om, d2Yss] = get_first_order_solution_params_deriv(A, B, estim_params, M, oo, options, kronflag, indpmodel, indpstderr, indpcorr, indvar) -% previously getH.m -% ------------------------------------------------------------------------- -% Computes first and second derivatives (with respect to parameters) of -% (1) reduced-form solution (dA, dB, dSigma_e, dOm, d2A, d2Om) -% (1) steady-state (dYss, d2Yss) -% (3) Jacobian (wrt to dynamic variables) of dynamic model (dg1) -% Note that the order in the parameter Jacobians is the following: -% first stderr parameters, second corr parameters, third model parameters -% ========================================================================= -% INPUTS -% A: [endo_nbr by endo_nbr] Transition matrix from Kalman filter -% for all endogenous declared variables, in DR order -% B: [endo_nbr by exo_nbr] Transition matrix from Kalman filter -% mapping shocks today to endogenous variables today, in DR order -% estim_params: [structure] storing the estimation information -% M: [structure] storing the model information -% oo: [structure] storing the reduced-form solution results -% options: [structure] storing the options -% kronflag: [scalar] method to compute Jacobians (equal to analytic_derivation_mode in options_ident). Default:0 -% * 0: efficient sylvester equation method to compute -% analytical derivatives as in Ratto & Iskrev (2011) -% * 1: kronecker products method to compute analytical -% derivatives as in Iskrev (2010) -% * -1: numerical two-sided finite difference method to -% compute numerical derivatives of all output arguments -% using function identification_numerical_objective.m -% (previously thet2tau.m) -% * -2: numerical two-sided finite difference method to -% compute numerically dYss, dg1, d2Yss and d2g1, the other -% output arguments are computed analytically as in kronflag=0 -% indpmodel: [modparam_nbr by 1] index of estimated parameters in M_.params; -% corresponds to model parameters (no stderr and no corr) -% in estimated_params block; if estimated_params block is -% not available, then all model parameters are selected -% indpstderr: [stderrparam_nbr by 1] index of estimated standard errors, -% i.e. for all exogenous variables where "stderr" is given -% in the estimated_params block; if estimated_params block -% is not available, then all stderr parameters are selected -% indpcorr: [corrparam_nbr by 2] matrix of estimated correlations, -% i.e. for all exogenous variables where "corr" is given -% in the estimated_params block; if estimated_params block -% is not available, then no corr parameters are selected -% indvar: [var_nbr by 1] index of considered (or observed) variables -% ------------------------------------------------------------------------- -% OUTPUTS -% dA: [var_nbr by var_nbr by totparam_nbr] in DR order -% Jacobian (wrt to all parameters) of transition matrix A -% dB: [var_nbr by exo_nbr by totparam_nbr] in DR order -% Jacobian (wrt to all parameters) of transition matrix B -% dSigma_e: [exo_nbr by exo_nbr by totparam_nbr] in declaration order -% Jacobian (wrt to all paramters) of M_.Sigma_e -% dOm: [var_nbr by var_nbr by totparam_nbr] in DR order -% Jacobian (wrt to all paramters) of Om = (B*M_.Sigma_e*B') -% dYss: [var_nbr by modparam_nbr] in DR order -% Jacobian (wrt model parameters only) of steady state -% dg1: [endo_nbr by (dynamicvar_nbr + exo_nbr) by modparam_nbr] in DR order -% Jacobian (wrt to model parameters only) of Jacobian of dynamic model -% d2A: [var_nbr*var_nbr by totparam_nbr*(totparam_nbr+1)/2] in DR order -% Unique entries of Hessian (wrt all parameters) of transition matrix A -% d2Om: [var_nbr*(var_nbr+1)/2 by totparam_nbr*(totparam_nbr+1)/2] in DR order -% Unique entries of Hessian (wrt all parameters) of Omega -% d2Yss: [var_nbr by modparam_nbr by modparam_nbr] in DR order -% Unique entries of Hessian (wrt model parameters only) of steady state -% ------------------------------------------------------------------------- -% This function is called by -% * dsge_likelihood.m -% * get_identification_jacobians.m (previously getJJ.m) -% ------------------------------------------------------------------------- -% This function calls -% * [fname,'.dynamic'] -% * [fname,'.dynamic_params_derivs'] -% * [fname,'.static'] -% * [fname,'.static_params_derivs'] -% * commutation -% * dyn_vech -% * dyn_unvech -% * fjaco -% * get_2nd_deriv (embedded) -% * get_2nd_deriv_mat(embedded) -% * get_all_parameters -% * get_all_resid_2nd_derivs (embedded) -% * get_hess_deriv (embedded) -% * hessian_sparse -% * sylvester3 -% * sylvester3a -% * identification_numerical_objective.m (previously thet2tau.m) -% ========================================================================= -% Copyright (C) 2010-2019 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 . -% ========================================================================= -fname = M.fname; -dname = M.dname; -maximum_exo_lag = M.maximum_exo_lag; -maximum_exo_lead = M.maximum_exo_lead; -maximum_endo_lag = M.maximum_endo_lag; -maximum_endo_lead = M.maximum_endo_lead; -lead_lag_incidence = M.lead_lag_incidence; -[I,~] = find(lead_lag_incidence'); %I is used to select nonzero columns of the Jacobian of endogenous variables in dynamic model files - -ys = oo.dr.ys; %steady state of endogenous variables in declaration order -yy0 = oo.dr.ys(I); %steady state of dynamic (endogenous and auxiliary variables) in DR order -ex0 = oo.exo_steady_state'; %steady state of exogenous variables in declaration order -params0 = M.params; %values at which to evaluate dynamic, static and param_derivs files -Sigma_e0 = M.Sigma_e; %covariance matrix of exogenous shocks -Corr_e0 = M.Correlation_matrix; %correlation matrix of exogenous shocks -stderr_e0 = sqrt(diag(Sigma_e0)); %standard errors of exogenous shocks - -param_nbr = M.param_nbr; %number of all declared model parameters in mod file -modparam_nbr = length(indpmodel); %number of model parameters to be used -stderrparam_nbr = length(indpstderr); %number of stderr parameters to be used -corrparam_nbr = size(indpcorr,1); %number of stderr parameters to be used -totparam_nbr = modparam_nbr + stderrparam_nbr + corrparam_nbr; %total number of parameters to be used - -if nargout > 6 - modparam_nbr2 = modparam_nbr*(modparam_nbr+1)/2; %number of unique entries of model parameters only in second-order derivative matrix - totparam_nbr2 = totparam_nbr*(totparam_nbr+1)/2; %number of unique entries of all parameters in second-order derivative matrix - %get indices of elements in second derivatives of parameters - indp2tottot = reshape(1:totparam_nbr^2,totparam_nbr,totparam_nbr); - indp2stderrstderr = indp2tottot(1:stderrparam_nbr , 1:stderrparam_nbr); - indp2stderrcorr = indp2tottot(1:stderrparam_nbr , stderrparam_nbr+1:stderrparam_nbr+corrparam_nbr); - indp2modmod = indp2tottot(stderrparam_nbr+corrparam_nbr+1:stderrparam_nbr+corrparam_nbr+modparam_nbr , stderrparam_nbr+corrparam_nbr+1:stderrparam_nbr+corrparam_nbr+modparam_nbr); - if totparam_nbr ~=1 - indp2tottot2 = dyn_vech(indp2tottot); %index of unique second-order derivatives - else - indp2tottot2 = indp2tottot; - end - if modparam_nbr ~= 1 - indp2modmod2 = dyn_vech(indp2modmod); %get rid of cross derivatives - else - indp2modmod2 = indp2modmod; - end -end -endo_nbr = size(A,1); %number of all declared endogenous variables -var_nbr = length(indvar); %number of considered variables -exo_nbr = size(B,2); %number of exogenous shocks in model - -if kronflag == -1 -% numerical two-sided finite difference method using function identification_numerical_objective.m (previously thet2tau.m) for Jacobian (wrt parameters) of A, B, Sig, Om, Yss, and g1 - para0 = get_all_parameters(estim_params, M); %get all selected parameters in estimated_params block, stderr and corr come first, then model parameters - if isempty(para0) - %if there is no estimated_params block, consider all stderr and all model parameters, but no corr parameters - para0 = [stderr_e0', params0']; - end - %Jacobians (wrt paramters) of steady state, solution matrices A and B, as well as Sigma_e for ALL variables [outputflag=0] - dYssABSige = fjaco('identification_numerical_objective', para0, 0, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvar); - M.params = params0; %make sure values are set back - M.Sigma_e = Sigma_e0; %make sure values are set back - M.Correlation_matrix = Corr_e0 ; %make sure values are set back - % get Jacobians for Yss, A, and B from dYssABSige - indYss = 1:var_nbr; - indA = (var_nbr+1):(var_nbr+var_nbr^2); - indB = (var_nbr+var_nbr^2+1):(var_nbr+var_nbr^2+var_nbr*exo_nbr); - indSigma_e = (var_nbr+var_nbr^2+var_nbr*exo_nbr+1):(var_nbr+var_nbr^2+var_nbr*exo_nbr+exo_nbr*(exo_nbr+1)/2); - dYss = dYssABSige(indYss , stderrparam_nbr+corrparam_nbr+1:end); %in tensor notation only wrt model parameters - dA = reshape(dYssABSige(indA , :) , [var_nbr var_nbr totparam_nbr]); %in tensor notation - dB = reshape(dYssABSige(indB , :) , [var_nbr exo_nbr totparam_nbr]); %in tensor notation - - dOm = zeros(var_nbr,var_nbr,totparam_nbr); %initialize in tensor notation - dSigma_e = zeros(exo_nbr,exo_nbr,totparam_nbr); %initialize in tensor notation - % get Jacobians of Sigma_e and Om wrt stderr parameters - if ~isempty(indpstderr) - for jp=1:stderrparam_nbr - dSigma_e(:,:,jp) = dyn_unvech(dYssABSige(indSigma_e , jp)); - dOm(:,:,jp) = B*dSigma_e(:,:,jp)*B'; %note that derivatives of B wrt stderr parameters are zero by construction - end - end - % get Jacobians of Sigma_e and Om wrt corr parameters - if ~isempty(indpcorr) - for jp=1:corrparam_nbr - dSigma_e(:,:,stderrparam_nbr+jp) = dyn_unvech(dYssABSige(indSigma_e , stderrparam_nbr+jp)); - dOm(:,:,stderrparam_nbr+jp) = B*dSigma_e(:,:,stderrparam_nbr+jp)*B'; %note that derivatives of B wrt corr parameters are zero by construction - end - end - % get Jacobian of Om wrt model parameters - if ~isempty(indpmodel) - for jp=1:modparam_nbr - dOm(:,:,stderrparam_nbr+corrparam_nbr+jp) = dB(:,:,stderrparam_nbr+corrparam_nbr+jp)*Sigma_e0*B' + B*Sigma_e0*dB(:,:,stderrparam_nbr+corrparam_nbr+jp)'; %note that derivatives of Sigma_e wrt model parameters are zero by construction - end - end - - %Jacobian (wrt model parameters ONLY) of steady state and of Jacobian of all dynamic model equations [outputflag=-1] - dYssg1 = fjaco('identification_numerical_objective', params0(indpmodel), -1, estim_params, M, oo, options, indpmodel, [], [], (1:endo_nbr)'); - M.params = params0; %make sure values are set back - M.Sigma_e = Sigma_e0; %make sure values are set back - M.Correlation_matrix = Corr_e0 ; %make sure values are set back - dg1 = reshape(dYssg1(endo_nbr+1:end,:),[endo_nbr, length(yy0)+length(ex0), modparam_nbr]); %get rid of steady state and in tensor notation - - if nargout > 6 - %Hessian (wrt paramters) of steady state, solution matrices A and Om [outputflag=-2] - % note that hessian_sparse does not take symmetry into account, i.e. compare hessian_sparse.m to hessian.m, but focuses already on unique values, which are duplicated below - d2YssAOm = hessian_sparse('identification_numerical_objective', para0', options.gstep, -2, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvar); - M.params = params0; %make sure values are set back - M.Sigma_e = Sigma_e0; %make sure values are set back - M.Correlation_matrix = Corr_e0 ; %make sure values are set back - - d2A = d2YssAOm(indA , indp2tottot2); %only unique elements - d2Om = d2YssAOm(indA(end)+1:end , indp2tottot2); %only unique elements - d2Yss = zeros(var_nbr,modparam_nbr,modparam_nbr); %initialize - for j = 1:var_nbr - d2Yss(j,:,:) = dyn_unvech(full(d2YssAOm(j,indp2modmod2))); %full Hessian for d2Yss, note that here we duplicate unique values for model parameters - end - clear d2YssAOm - end - - return %[END OF MAIN FUNCTION]!!!!! -end - -if kronflag == -2 -% numerical two-sided finite difference method to compute numerically -% dYss, dg1, d2Yss and d2g1, the rest is computed analytically (kronflag=0) below - modpara0 = params0(indpmodel); %focus only on model parameters for dYss, d2Yss and dg1 - [~, g1] = feval([fname,'.dynamic'], yy0, ex0, params0, ys, 1); - %g1 is [endo_nbr by (dynamicvar_nbr+exo_nbr)] first derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. df/d[yy0;ex0], in DR order - if nargout > 6 - % computation of d2Yss and d2g1, i.e. second derivative (wrt. parameters) of Jacobian (wrt endogenous and auxilary variables) of dynamic model [outputflag = -1] - % note that hessian_sparse does not take symmetry into account, i.e. compare hessian_sparse.m to hessian.m, but focuses already on unique values, which are duplicated below - d2Yssg1 = hessian_sparse('identification_numerical_objective', modpara0, options.gstep, -1, estim_params, M, oo, options, indpmodel, [], [], (1:endo_nbr)'); - M.params = params0; %make sure values are set back - M.Sigma_e = Sigma_e0; %make sure values are set back - M.Correlation_matrix = Corr_e0 ; %make sure values are set back - - d2Yss = reshape(full(d2Yssg1(1:endo_nbr,:)), [endo_nbr modparam_nbr modparam_nbr]); %put into tensor notation - for j=1:endo_nbr - d2Yss(j,:,:) = dyn_unvech(dyn_vech(d2Yss(j,:,:))); %add duplicate values to full hessian - end - d2g1_full = d2Yssg1(endo_nbr+1:end,:); - %store only nonzero unique entries and the corresponding indices of d2g1: - % rows: respective derivative term - % 1st column: equation number of the term appearing - % 2nd column: column number of variable in Jacobian of the dynamic model - % 3rd column: number of the first parameter in derivative - % 4th column: number of the second parameter in derivative - % 5th column: value of the Hessian term - ind_d2g1 = find(d2g1_full); - d2g1 = zeros(length(ind_d2g1),5); - for j=1:length(ind_d2g1) - [i1, i2] = ind2sub(size(d2g1_full),ind_d2g1(j)); - [ig1, ig2] = ind2sub(size(g1),i1); - [ip1, ip2] = ind2sub([modparam_nbr modparam_nbr],i2); - d2g1(j,:) = [ig1 ig2 ip1 ip2 d2g1_full(ind_d2g1(j))]; - end - clear d2g1_full; - end - %Jacobian (wrt parameters) of steady state and Jacobian of dynamic model equations [outputflag=-1] - dg1 = fjaco('identification_numerical_objective', modpara0, -1, estim_params, M, oo, options, indpmodel, [], [], (1:endo_nbr)'); - M.params = params0; %make sure values are set back - M.Sigma_e = Sigma_e0; %make sure values are set back - M.Correlation_matrix = Corr_e0 ; %make sure values are set back - dYss = dg1(1:endo_nbr , :); - dg1 = reshape(dg1(endo_nbr+1 : end , :),[endo_nbr, length(yy0)+length(ex0), modparam_nbr]); %get rid of steady state -elseif (kronflag == 0 || kronflag == 1) -% Analytical method to compute dYss, dg1, d2Yss and d2g1 - [~, g1_static] = feval([fname,'.static'], ys, ex0, params0); - %g1_static is [endo_nbr by endo_nbr] first-derivative (wrt variables) of static model equations f, i.e. df/dys, in declaration order - rp_static = feval([fname,'.static_params_derivs'], ys, repmat(ex0, maximum_exo_lag+maximum_exo_lead+1), params0); - %rp_static is [endo_nbr by param_nbr] first-derivative (wrt parameters) of static model equations f, i.e. df/dparams, in declaration order - dys = -g1_static\rp_static; - %use implicit function theorem (equation 5 of Ratto and Iskrev (2011) to compute [endo_nbr by param_nbr] first-derivative (wrt parameters) of steady state analytically, note that dys is in declaration order - d2ys = zeros(length(ys), param_nbr, param_nbr); %initialize in tensor notation - if nargout > 6 - [~, ~, g2_static] = feval([fname,'.static'], ys, ex0, params0); - %g2_static is [endo_nbr by endo_nbr^2] second derivative (wrt variables) of static model equations f, i.e. d(df/dys)/dys, in declaration order - [~, g1, g2, g3] = feval([fname,'.dynamic'], yy0, ex0, params0, ys, 1); - %g1 is [endo_nbr by (dynamicvar_nbr+exo_nbr)] first derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. df/d[yy0;ex0], in DR order - %g2 is [endo_nbr by (dynamicvar_nbr+exo_nbr)^2] second derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. d(df/d[yy0;ex0])/d[yy0;ex0], in DR order - %g3 is [endo_nbr by (dynamicvar_nbr+exo_nbr)^2] third-derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. d(df/d[yy0;ex0])/d[yy0;ex0], in DR order - [~, gp_static, rpp_static] = feval([fname,'.static_params_derivs'], ys, ex0, params0); - %gp_static is [endo_nbr by endo_nbr by param_nbr] first derivative (wrt parameters) of first-derivative (wrt variables) of static model equations f, i.e. (df/dys)/dparams, in declaration order - %rpp_static are nonzero values and corresponding indices of second derivative (wrt parameters) of static model equations f, i.e. d(df/dparams)/dparams, in declaration order - rpp_static = get_all_resid_2nd_derivs(rpp_static, length(ys), param_nbr); %make full matrix out of nonzero values and corresponding indices - %rpp_static is [endo_nbr by param_nbr by param_nbr] second derivative (wrt parameters) of static model equations, i.e. d(df/dparams)/dparams, in declaration order - if isempty(find(g2_static)) - %auxiliary expression on page 8 of Ratto and Iskrev (2011) is zero, i.e. gam = 0 - for j = 1:param_nbr - %using the implicit function theorem, equation 15 on page 7 of Ratto and Iskrev (2011) - d2ys(:,:,j) = -g1_static\rpp_static(:,:,j); - %d2ys is [endo_nbr by param_nbr by param_nbr] second-derivative (wrt parameters) of steady state, i.e. d(dys/dparams)/dparams, in declaration order - end - else - gam = rpp_static*0; %initialize auxiliary expression on page 8 of Ratto and Iskrev (2011) - for j = 1:endo_nbr - tmp_gp_static_dys = (squeeze(gp_static(j,:,:))'*dys); - gam(j,:,:) = transpose(reshape(g2_static(j,:),[endo_nbr endo_nbr])*dys)*dys + tmp_gp_static_dys + tmp_gp_static_dys'; - end - for j = 1:param_nbr - %using the implicit function theorem, equation 15 on page 7 of Ratto and Iskrev (2011) - d2ys(:,:,j) = -g1_static\(rpp_static(:,:,j)+gam(:,:,j)); - %d2ys is [endo_nbr by param_nbr by param_nbr] second-derivative (wrt parameters) of steady state, i.e. d(dys/dparams)/dparams, in declaration order - end - clear gp_static g2_static tmp_gp_static_dys gam - end - end - %handling of steady state for nonstationary variables - if any(any(isnan(dys))) - [U,T] = schur(g1_static); - qz_criterium = options.qz_criterium; - e1 = abs(ordeig(T)) < qz_criterium-1; - k = sum(e1); % Number of non stationary variables. - % Number of stationary variables: n = length(e1)-k - [U,T] = ordschur(U,T,e1); - T = T(k+1:end,k+1:end); - %using implicit function theorem, equation 5 of Ratto and Iskrev (2011), in declaration order - dys = -U(:,k+1:end)*(T\U(:,k+1:end)')*rp_static; - if nargout > 6 - disp('Computation of d2ys for nonstationary variables is not yet correctly handled if g2_static is nonempty, but continue anyways...') - for j = 1:param_nbr - %using implicit function theorem, equation 15 of Ratto and Iskrev (2011), in declaration order - d2ys(:,:,j) = -U(:,k+1:end)*(T\U(:,k+1:end)')*rpp_static(:,:,j); %THIS IS NOT CORRECT, IF g2_static IS NONEMPTY. WE NEED TO ADD GAM [willi] - end - end - end - if nargout > 6 - [~, gp, ~, gpp, hp] = feval([fname,'.dynamic_params_derivs'], yy0, ex0, params0, ys, 1, dys, d2ys); - %gp is [endo_nbr by (dynamicvar_nbr + exo_nbr) by param_nbr] first-derivative (wrt parameters) of first-derivative (wrt all endogenous, auxiliary and exogenous variables) of dynamic model equations, i.e. d(df/dvars)/dparam, in DR order - %gpp are nonzero values and corresponding indices of second-derivative (wrt parameters) of first-derivative (wrt all endogenous, auxiliary and exogenous variables) of dynamic model equations, i.e. d(d(df/dvars)/dparam)/dparam, in DR order - %hp are nonzero values and corresponding indices of first-derivative (wrt parameters) of second-derivative (wrt all endogenous, auxiliary and exogenous variables) of dynamic model equations, i.e. d(d(df/dvars)/dvars)/dparam, in DR order - d2Yss = d2ys(oo.dr.order_var,indpmodel,indpmodel); - %[endo_nbr by mod_param_nbr by mod_param_nbr], i.e. put into DR order and focus only on model parameters - else - [~, gp] = feval([fname,'.dynamic_params_derivs'], yy0, repmat(ex0, [maximum_exo_lag+maximum_exo_lead+1,1]), params0, ys, 1, dys, d2ys); - %gp is [endo_nbr by (dynamicvar_nbr + exo_nbr) by param_nbr] first-derivative (wrt parameters) of first-derivative (wrt all endogenous, auxiliary and exogenous variables) of dynamic model equations, i.e. d(df/dvars)/dparam, in DR order - [~, g1, g2 ] = feval([fname,'.dynamic'], yy0, repmat(ex0, [maximum_exo_lag+maximum_exo_lead+1,1]), params0, ys, 1); - %g1 is [endo_nbr by (dynamicvar_nbr+exo_nbr)] first derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. df/d[yy0;ex0], in DR order - %g2 is [endo_nbr by (dynamicvar_nbr+exo_nbr)^2] second derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. d(df/d[yy0;ex0])/d[yy0;ex0], in DR order - end - yy0ex0_nbr = sqrt(size(g2,2)); % number of dynamic variables + exogenous variables (length(yy0)+length(ex0)) - dYss = dys(oo.dr.order_var, indpmodel); %focus only on model parameters, note dys is in declaration order, dYss is in DR-order - dyy0 = dys(I,:); - yy0_nbr = max(max(lead_lag_incidence)); % retrieve the number of states excluding columns for shocks - % Computation of dg1, i.e. first derivative (wrt. parameters) of Jacobian (wrt endogenous and auxilary variables) of dynamic model using the implicit function theorem - % Let g1 denote the Jacobian of dynamic model equations, i.e. g1 = df/d[yy0ex0], evaluated at the steady state - % Let dg1 denote the first-derivative (wrt parameters) of g1 evaluated at the steady state - % Note that g1 is a function of both the parameters and of the steady state, which also depends on the parameters. - % Hence, implicitly g1=g1(p,yy0ex0(p)) and dg1 consists of two parts (see Ratto and Iskrev (2011) formula 7): - % (1) direct derivative wrt to parameters given by the preprocessor, i.e. gp - % and - % (2) contribution of derivative of steady state (wrt parameters), i.e. g2*dyy0 - % Note that in a stochastic context ex0 is always zero and hence can be skipped in the computations - dg1_part2 = gp*0; %initialize part 2, it has dimension [endo_nbr by (dynamicvar_nbr+exo_nbr) by param_nbr] - for j = 1:endo_nbr - [II, JJ] = ind2sub([yy0ex0_nbr yy0ex0_nbr], find(g2(j,:))); - %g2 is [endo_nbr by (dynamicvar_nbr+exo_nbr)^2] - for i = 1:yy0ex0_nbr - is = find(II==i); - is = is(find(JJ(is)<=yy0_nbr)); %focus only on yy0 derivatives as ex0 variables are 0 in a stochastic context - if ~isempty(is) - tmp_g2 = full(g2(j,find(g2(j,:)))); - dg1_part2(j,i,:) = tmp_g2(is)*dyy0(JJ(is),:); %put into tensor notation - end - end - end - dg1 = gp + dg1_part2; %dg is sum of two parts due to implicit function theorem - dg1 = dg1(:,:,indpmodel); %focus only on model parameters - - if nargout > 6 - % Computation of d2g1, i.e. second derivative (wrt. parameters) of Jacobian (wrt endogenous and auxilary variables) of dynamic model using the implicit function theorem - % Let g1 denote the Jacobian of dynamic model equations, i.e. g1 = df/d[yy0ex0], evaluated at the steady state - % Let d2g1 denote the second-derivative (wrt parameters) of g1 - % Note that g1 is a function of both the parameters and of the steady state, which also depends on the parameters. - % Hence, implicitly g1=g1(p,yy0ex0(p)) and the first derivative is given by dg1 = gp + g2*dyy0ex0 (see above) - % Accordingly, d2g1, the second-derivative (wrt parameters), consists of five parts (ignoring transposes, see Ratto and Iskrev (2011) formula 16) - % (1) d(gp)/dp = gpp - % (2) d(gp)/dyy0ex0*d(yy0ex0)/dp = hp * dyy0ex0 - % (3) d(g2)/dp * dyy0ex0 = hp * dyy0ex0 - % (4) d(g2)/dyy0ex0*d(dyy0ex0)/dp * dyy0ex0 = g3 * dyy0ex0 * dyy0ex0 - % (5) g2 * d(dyy0ex0)/dp = g2 * d2yy0ex0 - % Note that part 2 and 3 are equivalent besides the use of transpose (see Ratto and Iskrev (2011) formula 16) - d2g1_full = sparse(endo_nbr*yy0ex0_nbr, param_nbr*param_nbr); %initialize - dyy0ex0 = sparse([dyy0; zeros(yy0ex0_nbr-yy0_nbr,param_nbr)]); %Jacobian (wrt model parameters) of steady state of dynamic (endogenous and auxiliary) and exogenous variables - - g3 = unfold_g3(g3, yy0ex0_nbr); - g3_tmp = reshape(g3,[endo_nbr*yy0ex0_nbr*yy0ex0_nbr yy0ex0_nbr]); - d2g1_part4_left = sparse(endo_nbr*yy0ex0_nbr*yy0ex0_nbr,param_nbr); - for j = 1:param_nbr - %compute first two terms of part 4 - d2g1_part4_left(:,j) = g3_tmp*dyy0ex0(:,j); - end - - for j=1:endo_nbr - %Note that in the following we focus only on dynamic variables as exogenous variables are 0 by construction in a stochastic setting - d2g1_part5 = reshape(g2(j,:), [yy0ex0_nbr yy0ex0_nbr]); - d2g1_part5 = d2g1_part5(:,1:yy0_nbr)*reshape(d2ys(I,:,:),[yy0_nbr,param_nbr*param_nbr]); - for i=1:yy0ex0_nbr - ind_part4 = sub2ind([endo_nbr yy0ex0_nbr yy0ex0_nbr], ones(yy0ex0_nbr,1)*j ,ones(yy0ex0_nbr,1)*i, (1:yy0ex0_nbr)'); - d2g1_part4 = (d2g1_part4_left(ind_part4,:))'*dyy0ex0; - d2g1_part2_and_part3 = (get_hess_deriv(hp,j,i,yy0ex0_nbr,param_nbr))'*dyy0ex0; - d2g1_part1 = get_2nd_deriv_mat(gpp,j,i,param_nbr); - d2g1_tmp = d2g1_part1 + d2g1_part2_and_part3 + d2g1_part2_and_part3' + d2g1_part4 + reshape(d2g1_part5(i,:,:),[param_nbr param_nbr]); - d2g1_tmp = d2g1_tmp(indpmodel,indpmodel); %focus only on model parameters - if any(any(d2g1_tmp)) - ind_d2g1_tmp = find(triu(d2g1_tmp)); - d2g1_full(sub2ind([endo_nbr yy0ex0_nbr],j,i), ind_d2g1_tmp) = transpose(d2g1_tmp(ind_d2g1_tmp)); - end - end - end - clear d2g1_tmp d2g1_part1 d2g1_part2_and_part3 d2g1_part4 d2g1_part4_left d2g1_part5 - %store only nonzero entries and the corresponding indices of d2g1: - % rows: respective derivative term - % 1st column: equation number of the term appearing - % 2nd column: column number of variable in Jacobian of the dynamic model - % 3rd column: number of the first parameter in derivative - % 4th column: number of the second parameter in derivative - % 5th column: value of the Hessian term - ind_d2g1 = find(d2g1_full); - d2g1 = zeros(length(ind_d2g1),5); - for j=1:length(ind_d2g1) - [i1, i2] = ind2sub(size(d2g1_full),ind_d2g1(j)); - [ig1, ig2] = ind2sub(size(g1),i1); - [ip1, ip2] = ind2sub([modparam_nbr modparam_nbr],i2); - d2g1(j,:) = [ig1 ig2 ip1 ip2 d2g1_full(ind_d2g1(j))]; - end - clear d2g1_full; - end -end -% clear variables that are not used any more -clear rp_static g1_static -clear ys dys dyy0 dyy0ex0 -clear dg1_part2 tmp_g2 -clear g2 gp rpp_static g2_static gp_static d2ys -clear hp g3 g3_tmp gpp -clear ind_d2g1 ind_d2g1_tmp ind_part4 i j i1 i2 ig1 ig2 I II JJ ip1 ip2 is - -% Construct nonzero derivatives wrt to t+1, t, and t-1 variables using kstate -klen = maximum_endo_lag + maximum_endo_lead + 1; %total length -k11 = lead_lag_incidence(find([1:klen] ~= maximum_endo_lag+1),:); -g1nonzero = g1(:,nonzeros(k11')); -dg1nonzero = dg1(:,nonzeros(k11'),:); -if nargout > 6 - indind = ismember(d2g1(:,2),nonzeros(k11')); - tmp = d2g1(indind,:); - d2g1nonzero = tmp; - for j = 1:size(tmp,1) - inxinx = find(nonzeros(k11')==tmp(j,2)); - d2g1nonzero(j,2) = inxinx; - end -end -kstate = oo.dr.kstate; - -% Construct nonzero derivatives wrt to t+1, i.e. GAM1=-f_{y^+} in Villemot (2011) -GAM1 = zeros(endo_nbr,endo_nbr); -dGAM1 = zeros(endo_nbr,endo_nbr,modparam_nbr); -k1 = find(kstate(:,2) == maximum_endo_lag+2 & kstate(:,3)); -GAM1(:, kstate(k1,1)) = -g1nonzero(:,kstate(k1,3)); -dGAM1(:, kstate(k1,1), :) = -dg1nonzero(:,kstate(k1,3),:); -if nargout > 6 - indind = ismember(d2g1nonzero(:,2),kstate(k1,3)); - tmp = d2g1nonzero(indind,:); - tmp(:,end)=-tmp(:,end); - d2GAM1 = tmp; - for j = 1:size(tmp,1) - inxinx = (kstate(k1,3)==tmp(j,2)); - d2GAM1(j,2) = kstate(k1(inxinx),1); - end -end - -% Construct nonzero derivatives wrt to t, i.e. GAM0=f_{y^0} in Villemot (2011) -[~,cols_b,cols_j] = find(lead_lag_incidence(maximum_endo_lag+1, oo.dr.order_var)); -GAM0 = zeros(endo_nbr,endo_nbr); -dGAM0 = zeros(endo_nbr,endo_nbr,modparam_nbr); -GAM0(:,cols_b) = g1(:,cols_j); -dGAM0(:,cols_b,:) = dg1(:,cols_j,:); -if nargout > 6 - indind = ismember(d2g1(:,2),cols_j); - tmp = d2g1(indind,:); - d2GAM0 = tmp; - for j = 1:size(tmp,1) - inxinx = (cols_j==tmp(j,2)); - d2GAM0(j,2) = cols_b(inxinx); - end -end - -% Construct nonzero derivatives wrt to t-1, i.e. GAM2=-f_{y^-} in Villemot (2011) -k2 = find(kstate(:,2) == maximum_endo_lag+1 & kstate(:,4)); -GAM2 = zeros(endo_nbr,endo_nbr); -dGAM2 = zeros(endo_nbr,endo_nbr,modparam_nbr); -GAM2(:, kstate(k2,1)) = -g1nonzero(:,kstate(k2,4)); -dGAM2(:, kstate(k2,1), :) = -dg1nonzero(:,kstate(k2,4),:); -if nargout > 6 - indind = ismember(d2g1nonzero(:,2),kstate(k2,4)); - tmp = d2g1nonzero(indind,:); - tmp(:,end) = -tmp(:,end); - d2GAM2 = tmp; - for j = 1:size(tmp,1) - inxinx = (kstate(k2,4)==tmp(j,2)); - d2GAM2(j,2) = kstate(k2(inxinx),1); - end -end - -% Construct nonzero derivatives wrt to u_t, i.e. GAM3=-f_{u} in Villemot (2011) -GAM3 = -g1(:,length(yy0)+1:end); -dGAM3 = -dg1(:,length(yy0)+1:end,:); -if nargout > 6 - cols_ex = [length(yy0)+1:size(g1,2)]; - indind = ismember(d2g1(:,2),cols_ex); - tmp = d2g1(indind,:); - tmp(:,end) = -tmp(:,end); - d2GAM3 = tmp; - for j = 1:size(tmp,1) - inxinx = find(cols_ex==tmp(j,2)); - d2GAM3(j,2) = inxinx; - end - clear d2g1 d2g1nonzero tmp -end -clear cols_b cols_ex cols_j k1 k11 k2 klen kstate -clear g1nonzero dg1nonzero g1 yy0 - -%% Construct first derivative of Sigma_e -dSigma_e = zeros(exo_nbr,exo_nbr,totparam_nbr); %initialize -% note that derivatives wrt model parameters are zero by construction -% Compute first derivative of Sigma_e wrt stderr parameters (these come first) -if ~isempty(indpstderr) - for jp = 1:stderrparam_nbr - dSigma_e(indpstderr(jp),indpstderr(jp),jp) = 2*stderr_e0(indpstderr(jp)); - if isdiag(Sigma_e0) == 0 % if there are correlated errors add cross derivatives - indotherex0 = 1:exo_nbr; - indotherex0(indpstderr(jp)) = []; - for kk = indotherex0 - dSigma_e(indpstderr(jp), kk, jp) = Corr_e0(indpstderr(jp),kk)*stderr_e0(kk); - dSigma_e(kk, indpstderr(jp), jp) = dSigma_e(indpstderr(jp), kk, jp); %symmetry - end - end - end -end -% Compute first derivative of Sigma_e wrt corr parameters (these come second) -if ~isempty(indpcorr) - for jp = 1:corrparam_nbr - dSigma_e(indpcorr(jp,1),indpcorr(jp,2),stderrparam_nbr+jp) = stderr_e0(indpcorr(jp,1))*stderr_e0(indpcorr(jp,2)); - dSigma_e(indpcorr(jp,2),indpcorr(jp,1),stderrparam_nbr+jp) = dSigma_e(indpcorr(jp,1),indpcorr(jp,2),stderrparam_nbr+jp); %symmetry - end -end - -%% Construct second derivative of Sigma_e -if nargout > 6 - % note that derivatives wrt (mod x mod) and (corr x corr) parameters - % are zero by construction; hence we only need to focus on (stderr x stderr), and (stderr x corr) - d2Sigma_e = zeros(exo_nbr,exo_nbr,totparam_nbr^2); %initialize full matrix, even though we'll reduce it later on to unique upper triangular values - % Compute upper triangular values of Hessian of Sigma_e wrt (stderr x stderr) parameters - if ~isempty(indp2stderrstderr) - for jp = 1:stderrparam_nbr - for ip = 1:jp - if jp == ip %same stderr parameters - d2Sigma_e(indpstderr(jp),indpstderr(jp),indp2stderrstderr(ip,jp)) = 2; - else %different stderr parameters - if isdiag(Sigma_e0) == 0 % if there are correlated errors - d2Sigma_e(indpstderr(jp),indpstderr(ip),indp2stderrstderr(ip,jp)) = Corr_e0(indpstderr(jp),indpstderr(ip)); - d2Sigma_e(indpstderr(ip),indpstderr(jp),indp2stderrstderr(ip,jp)) = Corr_e0(indpstderr(jp),indpstderr(ip)); %symmetry - end - end - end - end - end - % Compute upper triangular values of Hessian of Sigma_e wrt (stderr x corr) parameters - if ~isempty(indp2stderrcorr) - for jp = 1:stderrparam_nbr - for ip = 1:corrparam_nbr - if indpstderr(jp) == indpcorr(ip,1) %if stderr equal to first index of corr parameter, derivative is equal to stderr corresponding to second index - d2Sigma_e(indpstderr(jp),indpcorr(ip,2),indp2stderrcorr(jp,ip)) = stderr_e0(indpcorr(ip,2)); - d2Sigma_e(indpcorr(ip,2),indpstderr(jp),indp2stderrcorr(jp,ip)) = stderr_e0(indpcorr(ip,2)); % symmetry - end - if indpstderr(jp) == indpcorr(ip,2) %if stderr equal to second index of corr parameter, derivative is equal to stderr corresponding to first index - d2Sigma_e(indpstderr(jp),indpcorr(ip,1),indp2stderrcorr(jp,ip)) = stderr_e0(indpcorr(ip,1)); - d2Sigma_e(indpcorr(ip,1),indpstderr(jp),indp2stderrcorr(jp,ip)) = stderr_e0(indpcorr(ip,1)); % symmetry - end - end - end - end - d2Sigma_e = d2Sigma_e(:,:,indp2tottot2); %focus on upper triangular hessian values -end - - -if kronflag == 1 - % The following derivations are based on Iskrev (2010) and its online appendix A. - % Basic idea is to make use of the implicit function theorem. - % Let F = GAM0*A - GAM1*A*A - GAM2 = 0 - % Note that F is a function of parameters p and A, which is also a - % function of p,therefore, F = F(p,A(p)), and hence, - % dF = Fp + dF_dA*dA or dA = - Fp/dF_dA - - % Some auxiliary matrices - I_endo = speye(endo_nbr); - I_exo = speye(exo_nbr); - - % Reshape to write derivatives in the Magnus and Neudecker style, i.e. dvec(X)/dp - dGAM0 = reshape(dGAM0, endo_nbr^2, modparam_nbr); - dGAM1 = reshape(dGAM1, endo_nbr^2, modparam_nbr); - dGAM2 = reshape(dGAM2, endo_nbr^2, modparam_nbr); - dGAM3 = reshape(dGAM3, endo_nbr*exo_nbr, modparam_nbr); - dSigma_e = reshape(dSigma_e, exo_nbr^2, totparam_nbr); - - % Compute dA via implicit function - dF_dA = kron(I_endo,GAM0) - kron(A',GAM1) - kron(I_endo,GAM1*A); %equation 31 in Appendix A of Iskrev (2010) - Fp = kron(A',I_endo)*dGAM0 - kron( (A')^2,I_endo)*dGAM1 - dGAM2; %equation 32 in Appendix A of Iskrev (2010) - dA = -dF_dA\Fp; - - % Compute dB from expressions 33 in Iskrev (2010) Appendix A - MM = GAM0-GAM1*A; %this corresponds to matrix M in Ratto and Iskrev (2011, page 6) and will be used if nargout > 6 below - invMM = MM\eye(endo_nbr); - dB = - kron( (invMM*GAM3)' , invMM ) * ( dGAM0 - kron( A' , I_endo ) * dGAM1 - kron( I_endo , GAM1 ) * dA ) + kron( I_exo, invMM ) * dGAM3 ; - dBt = commutation(endo_nbr, exo_nbr)*dB; %transose of derivative using the commutation matrix - - % Add derivatives for stderr and corr parameters, which are zero by construction - dA = [zeros(endo_nbr^2, stderrparam_nbr+corrparam_nbr) dA]; - dB = [zeros(endo_nbr*exo_nbr, stderrparam_nbr+corrparam_nbr) dB]; - dBt = [zeros(endo_nbr*exo_nbr, stderrparam_nbr+corrparam_nbr) dBt]; - - % Compute dOm = dvec(B*Sig*B') from expressions 34 in Iskrev (2010) Appendix A - dOm = kron(I_endo,B*Sigma_e0)*dBt + kron(B,B)*dSigma_e + kron(B*Sigma_e0,I_endo)*dB; - - % Put into tensor notation - dA = reshape(dA, endo_nbr, endo_nbr, totparam_nbr); - dB = reshape(dB, endo_nbr, exo_nbr, totparam_nbr); - dOm = reshape(dOm, endo_nbr, endo_nbr, totparam_nbr); - dSigma_e = reshape(dSigma_e, exo_nbr, exo_nbr, totparam_nbr); - if nargout > 6 - % Put back into tensor notation as these will be reused later - dGAM0 = reshape(dGAM0, endo_nbr, endo_nbr, modparam_nbr); - dGAM1 = reshape(dGAM1, endo_nbr, endo_nbr, modparam_nbr); - dGAM2 = reshape(dGAM2, endo_nbr, endo_nbr, modparam_nbr); - dGAM3 = reshape(dGAM3, endo_nbr, exo_nbr, modparam_nbr); - dAA = dA(:, :, stderrparam_nbr+corrparam_nbr+1:end); %this corresponds to matrix dA in Ratto and Iskrev (2011, page 6), i.e. derivative of A with respect to model parameters only in tensor notation - dBB = dB(:, :, stderrparam_nbr+corrparam_nbr+1:end); %dBB is for all endogenous variables, whereas dB is only for selected variables - N = -GAM1; %this corresponds to matrix N in Ratto and Iskrev (2011, page 6) - P = A; %this corresponds to matrix P in Ratto and Iskrev (2011, page 6) - end - - % Focus only on selected variables - dYss = dYss(indvar,:); - dA = dA(indvar,indvar,:); - dB = dB(indvar,:,:); - dOm = dOm(indvar,indvar,:); - -elseif (kronflag == 0 || kronflag == -2) - % generalized sylvester equation solves MM*dAA+N*dAA*P=Q from Ratto and Iskrev (2011) equation 11 where - % dAA is derivative of A with respect to model parameters only in tensor notation - MM = (GAM0-GAM1*A); - N = -GAM1; - P = A; - Q_rightpart = zeros(endo_nbr,endo_nbr,modparam_nbr); %initialize - Q = Q_rightpart; %initialize and compute matrix Q in Ratto and Iskrev (2011, page 6) - for j = 1:modparam_nbr - Q_rightpart(:,:,j) = (dGAM0(:,:,j)-dGAM1(:,:,j)*A); - Q(:,:,j) = dGAM2(:,:,j)-Q_rightpart(:,:,j)*A; - end - %use iterated generalized sylvester equation to compute dAA - dAA = sylvester3(MM,N,P,Q); - flag = 1; icount = 0; - while flag && icount < 4 - [dAA, flag] = sylvester3a(dAA,MM,N,P,Q); - icount = icount+1; - end - - %stderr parameters come first, then corr parameters, model parameters come last - %note that stderr and corr derivatives are: - % - zero by construction for A and B - % - depend only on dSig for Om - dOm = zeros(var_nbr, var_nbr, totparam_nbr); - dA = zeros(var_nbr, var_nbr, totparam_nbr); - dB = zeros(var_nbr, exo_nbr, totparam_nbr); - if nargout > 6 - dBB = zeros(endo_nbr, exo_nbr, modparam_nbr); %dBB is always for all endogenous variables, whereas dB is only for selected variables - end - - %compute derivative of Om=B*Sig*B' that depends on Sig (other part is added later) - if ~isempty(indpstderr) - for j = 1:stderrparam_nbr - BSigjBt = B*dSigma_e(:,:,j)*B'; - dOm(:,:,j) = BSigjBt(indvar,indvar); - end - end - if ~isempty(indpcorr) - for j = 1:corrparam_nbr - BSigjBt = B*dSigma_e(:,:,stderrparam_nbr+j)*B'; - dOm(:,:,stderrparam_nbr+j) = BSigjBt(indvar,indvar); - end - end - - %compute derivative of B and the part of Om=B*Sig*B' that depends on B (other part is computed above) - invMM = inv(MM); - for j = 1:modparam_nbr - dAAj = dAA(:,:,j); - dBj = invMM * ( dGAM3(:,:,j) - (Q_rightpart(:,:,j) -GAM1*dAAj ) * B ); %equation 14 in Ratto and Iskrev (2011), except in the paper there is a typo as the last B is missing - dOmj = dBj*Sigma_e0*B'+B*Sigma_e0*dBj'; - %store derivatives in tensor notation - dA(:, :, stderrparam_nbr+corrparam_nbr+j) = dAAj(indvar,indvar); - dB(:, :, stderrparam_nbr+corrparam_nbr+j) = dBj(indvar,:); - dOm(:, :, stderrparam_nbr+corrparam_nbr+j) = dOmj(indvar,indvar); - if nargout > 6 - dBB(:, :, j) = dBj; - end - end - dYss = dYss(indvar,:); % Focus only on relevant variables -end - -%% Compute second-order derivatives (wrt params) of solution matrices using generalized sylvester equations, see equations 17 and 18 in Ratto and Iskrev (2011) -if nargout > 6 - % solves MM*d2AA+N*d2AA*P = QQ where d2AA are second order derivatives (wrt model parameters) of A - d2Yss = d2Yss(indvar,:,:); - QQ = zeros(endo_nbr,endo_nbr,floor(sqrt(modparam_nbr2))); - jcount=0; - cumjcount=0; - jinx = []; - x2x=sparse(endo_nbr*endo_nbr,modparam_nbr2); - for i=1:modparam_nbr - for j=1:i - elem1 = (get_2nd_deriv(d2GAM0,endo_nbr,endo_nbr,j,i)-get_2nd_deriv(d2GAM1,endo_nbr,endo_nbr,j,i)*A); - elem1 = get_2nd_deriv(d2GAM2,endo_nbr,endo_nbr,j,i)-elem1*A; - elemj0 = dGAM0(:,:,j)-dGAM1(:,:,j)*A; - elemi0 = dGAM0(:,:,i)-dGAM1(:,:,i)*A; - elem2 = -elemj0*dAA(:,:,i)-elemi0*dAA(:,:,j); - elem2 = elem2 + ( dGAM1(:,:,j)*dAA(:,:,i) + dGAM1(:,:,i)*dAA(:,:,j) )*A; - elem2 = elem2 + GAM1*( dAA(:,:,i)*dAA(:,:,j) + dAA(:,:,j)*dAA(:,:,i)); - jcount=jcount+1; - jinx = [jinx; [j i]]; - QQ(:,:,jcount) = elem1+elem2; - if jcount==floor(sqrt(modparam_nbr2)) || (j*i)==modparam_nbr^2 - if (j*i)==modparam_nbr^2 - QQ = QQ(:,:,1:jcount); - end - xx2=sylvester3(MM,N,P,QQ); - flag=1; - icount=0; - while flag && icount<4 - [xx2, flag]=sylvester3a(xx2,MM,N,P,QQ); - icount = icount + 1; - end - x2x(:,cumjcount+1:cumjcount+jcount)=reshape(xx2,[endo_nbr*endo_nbr jcount]); - cumjcount=cumjcount+jcount; - jcount = 0; - jinx = []; - end - end - end - clear d xx2; - jcount = 0; - icount = 0; - cumjcount = 0; - MAX_DIM_MAT = 100000000; - ncol = max(1,floor(MAX_DIM_MAT/(8*var_nbr*(var_nbr+1)/2))); - ncol = min(ncol, totparam_nbr2); - d2A = sparse(var_nbr*var_nbr,totparam_nbr2); - d2Om = sparse(var_nbr*(var_nbr+1)/2,totparam_nbr2); - d2A_tmp = zeros(var_nbr*var_nbr,ncol); - d2Om_tmp = zeros(var_nbr*(var_nbr+1)/2,ncol); - tmpDir = CheckPath('tmp_derivs',dname); - offset = stderrparam_nbr+corrparam_nbr; - % d2B = zeros(m,n,tot_param_nbr,tot_param_nbr); - for j=1:totparam_nbr - for i=1:j - jcount=jcount+1; - if j<=offset %stderr and corr parameters - y = B*d2Sigma_e(:,:,jcount)*B'; - d2Om_tmp(:,jcount) = dyn_vech(y(indvar,indvar)); - else %model parameters - jind = j-offset; - iind = i-offset; - if i<=offset - y = dBB(:,:,jind)*dSigma_e(:,:,i)*B'+B*dSigma_e(:,:,i)*dBB(:,:,jind)'; - % y(abs(y)<1.e-8)=0; - d2Om_tmp(:,jcount) = dyn_vech(y(indvar,indvar)); - else - icount=icount+1; - dAAj = reshape(x2x(:,icount),[endo_nbr endo_nbr]); - % x = get_2nd_deriv(x2x,m,m,iind,jind);%xx2(:,:,jcount); - elem1 = (get_2nd_deriv(d2GAM0,endo_nbr,endo_nbr,iind,jind)-get_2nd_deriv(d2GAM1,endo_nbr,endo_nbr,iind,jind)*A); - elem1 = elem1 -( dGAM1(:,:,jind)*dAA(:,:,iind) + dGAM1(:,:,iind)*dAA(:,:,jind) ); - elemj0 = dGAM0(:,:,jind)-dGAM1(:,:,jind)*A-GAM1*dAA(:,:,jind); - elemi0 = dGAM0(:,:,iind)-dGAM1(:,:,iind)*A-GAM1*dAA(:,:,iind); - elem0 = elemj0*dBB(:,:,iind)+elemi0*dBB(:,:,jind); - y = invMM * (get_2nd_deriv(d2GAM3,endo_nbr,exo_nbr,iind,jind)-elem0-(elem1-GAM1*dAAj)*B); - % d2B(:,:,j+length(indexo),i+length(indexo)) = y; - % d2B(:,:,i+length(indexo),j+length(indexo)) = y; - y = y*Sigma_e0*B'+B*Sigma_e0*y'+ ... - dBB(:,:,jind)*Sigma_e0*dBB(:,:,iind)'+dBB(:,:,iind)*Sigma_e0*dBB(:,:,jind)'; - % x(abs(x)<1.e-8)=0; - d2A_tmp(:,jcount) = vec(dAAj(indvar,indvar)); - % y(abs(y)<1.e-8)=0; - d2Om_tmp(:,jcount) = dyn_vech(y(indvar,indvar)); - end - end - if jcount==ncol || i*j==totparam_nbr^2 - d2A(:,cumjcount+1:cumjcount+jcount) = d2A_tmp(:,1:jcount); - % d2A(:,:,j+length(indexo),i+length(indexo)) = x; - % d2A(:,:,i+length(indexo),j+length(indexo)) = x; - d2Om(:,cumjcount+1:cumjcount+jcount) = d2Om_tmp(:,1:jcount); - % d2Om(:,:,j+length(indexo),i+length(indexo)) = y; - % d2Om(:,:,i+length(indexo),j+length(indexo)) = y; - save([tmpDir filesep 'd2A_' int2str(cumjcount+1) '_' int2str(cumjcount+jcount) '.mat'],'d2A') - save([tmpDir filesep 'd2Om_' int2str(cumjcount+1) '_' int2str(cumjcount+jcount) '.mat'],'d2Om') - cumjcount = cumjcount+jcount; - jcount=0; - % d2A = sparse(m1*m1,tot_param_nbr*(tot_param_nbr+1)/2); - % d2Om = sparse(m1*(m1+1)/2,tot_param_nbr*(tot_param_nbr+1)/2); - d2A_tmp = zeros(var_nbr*var_nbr,ncol); - d2Om_tmp = zeros(var_nbr*(var_nbr+1)/2,ncol); - end - end - end -end - -return - -function g22 = get_2nd_deriv(gpp,m,n,i,j) -% inputs: -% - gpp: [#second_order_Jacobian_terms by 5] double Hessian matrix (wrt parameters) of a matrix -% rows: respective derivative term -% 1st column: equation number of the term appearing -% 2nd column: column number of variable in Jacobian -% 3rd column: number of the first parameter in derivative -% 4th column: number of the second parameter in derivative -% 5th column: value of the Hessian term -% - m: scalar number of equations -% - n: scalar number of variables -% - i: scalar number for which first parameter -% - j: scalar number for which second parameter - -g22=zeros(m,n); -is=find(gpp(:,3)==i); -is=is(find(gpp(is,4)==j)); - -if ~isempty(is) - g22(sub2ind([m,n],gpp(is,1),gpp(is,2)))=gpp(is,5)'; -end -return - -function g22 = get_2nd_deriv_mat(gpp,i,j,npar) -% inputs: -% - gpp: [#second_order_Jacobian_terms by 5] double Hessian matrix of (wrt parameters) of dynamic Jacobian -% rows: respective derivative term -% 1st column: equation number of the term appearing -% 2nd column: column number of variable in Jacobian of the dynamic model -% 3rd column: number of the first parameter in derivative -% 4th column: number of the second parameter in derivative -% 5th column: value of the Hessian term -% - i: scalar number for which model equation -% - j: scalar number for which variable in Jacobian of dynamic model -% - npar: scalar Number of model parameters, i.e. equals M_.param_nbr -% -% output: -% g22: [npar by npar] Hessian matrix (wrt parameters) of Jacobian of dynamic model for equation i -% rows: first parameter in Hessian -% columns: second paramater in Hessian - -g22=zeros(npar,npar); -is=find(gpp(:,1)==i); -is=is(find(gpp(is,2)==j)); - -if ~isempty(is) - g22(sub2ind([npar,npar],gpp(is,3),gpp(is,4)))=gpp(is,5)'; -end -return - -function g22 = get_all_2nd_derivs(gpp,m,n,npar,fsparse) - -if nargin==4 || isempty(fsparse) - fsparse=0; -end -if fsparse - g22=sparse(m*n,npar*npar); -else - g22=zeros(m,n,npar,npar); -end -% c=ones(npar,npar); -% c=triu(c); -% ic=find(c); - -for is=1:length(gpp) - % d=zeros(npar,npar); - % d(gpp(is,3),gpp(is,4))=1; - % indx = find(ic==find(d)); - if fsparse - g22(sub2ind([m,n],gpp(is,1),gpp(is,2)),sub2ind([npar,npar],gpp(is,3),gpp(is,4)))=gpp(is,5); - else - g22(gpp(is,1),gpp(is,2),gpp(is,3),gpp(is,4))=gpp(is,5); - end -end - -return - -function r22 = get_all_resid_2nd_derivs(rpp,m,npar) -% inputs: -% - rpp: [#second_order_residual_terms by 4] double Hessian matrix (wrt paramters) of model equations -% rows: respective derivative term -% 1st column: equation number of the term appearing -% 2nd column: number of the first parameter in derivative -% 3rd column: number of the second parameter in derivative -% 4th column: value of the Hessian term -% - m: scalar Number of residuals (or model equations), i.e. equals endo_nbr -% - npar: scalar Number of model parameters, i.e. equals param_nbr -% -% output: -% r22: [endo_nbr by param_nbr by param_nbr] Hessian matrix of model equations with respect to parameters -% rows: equations in order of declaration -% 1st columns: first parameter number in derivative -% 2nd columns: second parameter in derivative - -r22=zeros(m,npar,npar); - -for is=1:length(rpp) - % Keep symmetry in hessian, hence 2 and 3 as well as 3 and 2, i.e. d2f/(dp1 dp2) = d2f/(dp2 dp1) - r22(rpp(is,1),rpp(is,2),rpp(is,3))=rpp(is,4); - r22(rpp(is,1),rpp(is,3),rpp(is,2))=rpp(is,4); -end - -return - -function h2 = get_all_hess_derivs(hp,r,m,npar) - -h2=zeros(r,m,m,npar); - -for is=1:length(hp) - h2(hp(is,1),hp(is,2),hp(is,3),hp(is,4))=hp(is,5); -end - -return - -function h2 = get_hess_deriv(hp,i,j,m,npar) -% inputs: -% - hp: [#first_order_Hessian_terms by 5] double Jacobian matrix (wrt paramters) of dynamic Hessian -% rows: respective derivative term -% 1st column: equation number of the term appearing -% 2nd column: column number of first variable in Hessian of the dynamic model -% 3rd column: column number of second variable in Hessian of the dynamic model -% 4th column: number of the parameter in derivative -% 5th column: value of the Hessian term -% - i: scalar number for which model equation -% - j: scalar number for which first variable in Hessian of dynamic model variable -% - m: scalar Number of dynamic model variables + exogenous vars, i.e. dynamicvar_nbr + exo_nbr -% - npar: scalar Number of model parameters, i.e. equals M_.param_nbr -% -% output: -% h2: [(dynamicvar_nbr + exo_nbr) by M_.param_nbr] Jacobian matrix (wrt parameters) of dynamic Hessian -% rows: second dynamic or exogenous variables in Hessian of specific model equation of the dynamic model -% columns: parameters - -h2=zeros(m,npar); -is1=find(hp(:,1)==i); -is=is1(find(hp(is1,2)==j)); - -if ~isempty(is) - h2(sub2ind([m,npar],hp(is,3),hp(is,4)))=hp(is,5)'; -end - -return diff --git a/matlab/get_identification_jacobians.m b/matlab/get_identification_jacobians.m index d4f5ebc52..7e7443bfd 100644 --- a/matlab/get_identification_jacobians.m +++ b/matlab/get_identification_jacobians.m @@ -1,69 +1,86 @@ -function [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs) -% [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs) -% previously getJJ.m -% ------------------------------------------------------------------------- -% Sets up the Jacobians needed for identification analysis based on the -% Iskrev's J, Qu and Tkachenko's G and Komunjer and Ng's D matrices as well -% as on the reduced-form model (dTAU) and the dynamic model (dLRE) +function [MEAN, dMEAN, REDUCEDFORM, dREDUCEDFORM, DYNAMIC, dDYNAMIC, MOMENTS, dMOMENTS, dSPECTRUM, dSPECTRUM_NO_MEAN, dMINIMAL, derivatives_info] = get_identification_jacobians(estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs) +% function [MEAN, dMEAN, REDUCEDFORM, dREDUCEDFORM, DYNAMIC, dDYNAMIC, MOMENTS, dMOMENTS, dSPECTRUM, dMINIMAL, derivatives_info] = get_identification_jacobians(estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs) +% previously getJJ.m in Dynare 4.5 +% Sets up the Jacobians needed for identification analysis % ========================================================================= % INPUTS -% A: [endo_nbr by endo_nbr] in DR order -% Transition matrix from Kalman filter for all endogenous declared variables, -% B: [endo_nbr by exo_nbr] in DR order -% Transition matrix from Kalman filter mapping shocks today to endogenous variables today % estim_params: [structure] storing the estimation information % M: [structure] storing the model information % oo: [structure] storing the reduced-form solution results % options: [structure] storing the options % options_ident: [structure] storing the options for identification -% indpmodel: [modparam_nbr by 1] index of estimated parameters in M_.params; -% corresponds to model parameters (no stderr and no corr) +% indpmodel: [modparam_nbr by 1] index of estimated parameters in M_.params; +% corresponds to model parameters (no stderr and no corr) % in estimated_params block; if estimated_params block is % not available, then all model parameters are selected -% indpstderr: [stderrparam_nbr by 1] index of estimated standard errors, -% i.e. for all exogenous variables where "stderr" is given +% indpstderr: [stderrparam_nbr by 1] index of estimated standard errors, +% i.e. for all exogenous variables where "stderr" is given % in the estimated_params block; if estimated_params block % is not available, then all stderr parameters are selected % indpcorr: [corrparam_nbr by 2] matrix of estimated correlations, -% i.e. for all exogenous variables where "corr" is given +% i.e. for all exogenous variables where "corr" is given % in the estimated_params block; if estimated_params block % is not available, then no corr parameters are selected % indvobs: [obs_nbr by 1] index of observed (VAROBS) variables % ------------------------------------------------------------------------- % OUTPUTS -% J: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by totparam_nbr] in DR Order -% Jacobian of 1st and 2nd order moments of observables wrt, -% all parameters, i.e. dgam (see below for definition of gam). -% Corresponds to Iskrev (2010)'s J matrix. -% G: [totparam_nbr by totparam_nbr] in DR Order -% Sum of (1) Gram Matrix of Jacobian of spectral density -% wrt to all parameters plus (2) Gram Matrix of Jacobian -% of steady state wrt to all parameters. -% Corresponds to Qu and Tkachenko (2012)'s G matrix. -% D: [obs_nbr+minstate_nbr^2+minstate_nbr*exo_nbr+obs_nbr*minstate_nbr+obs_nbr*exo_nbr+exo_nbr*(exo_nbr+1)/2 by totparam_nbr+minstate_nbr^2+exo_nbr^2] in DR order -% Jacobian of minimal System Matrices and unique Transformation -% of steady state and spectral density matrix. -% Corresponds to Komunjer and Ng (2011)'s Delta matrix. -% dTAU: [(endo_nbr+endo_nbr^2+endo_nbr*(endo_nbr+1)/2) by totparam_nbr] in DR order -% Jacobian of linearized reduced form state space model, given Yss [steady state], -% A [transition matrix], B [matrix of shocks], Sigma [covariance of shocks] -% tau = [ys; vec(A); dyn_vech(B*Sigma*B')] with respect to all parameters. -% dLRE: [endo_nbr+endo_nbr*(dynamicvar_nbr+exo_nbr) by modparam_nbr] in DR order -% Jacobian of steady state and linear rational expectation matrices -% (i.e. Jacobian of dynamic model) with respect to estimated model parameters only (indpmodel) -% dA: [endo_nbr by endo_nbr by totparam_nbr] in DR order -% Jacobian (wrt to all parameters) of transition matrix A -% dOm: [endo_nbr by endo_nbr by totparam_nbr] in DR order -% Jacobian (wrt to all paramters) of Om = (B*Sigma_e*B') -% dYss [endo_nbr by modparam_nbr] in DR order -% Jacobian (wrt model parameters only) of steady state -% MOMENTS: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by 1] -% vector of theoretical moments of observed (VAROBS) -% variables. Note that J is the Jacobian of MOMENTS. -% MOMENTS = [ys(indvobs); dyn_vech(GAM{1}); vec(GAM{j+1})]; for j=1:ar and where -% GAM is the first output of th_autocovariances +% +% MEAN [endo_nbr by 1], in DR order. Expectation of all model variables +% * order==1: corresponds to steady state +% * order==2|3: corresponds to mean computed from pruned state space system (as in Andreasen, Fernandez-Villaverde, Rubio-Ramirez, 2018) +% dMEAN [endo_nbr by totparam_nbr], in DR Order, Jacobian (wrt all params) of MEAN +% +% REDUCEDFORM [rowredform_nbr by 1] in DR order. Steady state and reduced-form model solution matrices for all model variables +% * order==1: [Yss' vec(ghx)' vech(ghu*Sigma_e*ghu')']', +% where rowredform_nbr = endo_nbr*(1+nspred+(endo_nbr+1)/2) +% * order==2: [Yss' vec(ghx)' vech(ghu*Sigma_e*ghu')' vec(ghxx)' vec(ghxu)' vec(ghuu)' vec(ghs2)']', +% where rowredform_nbr = endo_nbr*(1+nspred+(endo_nbr+1)/2+nspred^2+nspred*exo_nr+exo_nbr^2+1) +% * order==3: [Yss' vec(ghx)' vech(ghu*Sigma_e*ghu')' vec(ghxx)' vec(ghxu)' vec(ghuu)' vec(ghs2)' vec(ghxxx)' vec(ghxxu)' vec(ghxuu)' vec(ghuuu)' vec(ghxss)' vec(ghuss)']', +% where rowredform_nbr = endo_nbr*(1+nspred+(endo_nbr+1)/2+nspred^2+nspred*exo_nr+exo_nbr^2+1+nspred^3+nspred^2*exo_nbr+nspred*exo_nbr^2+exo_nbr^3+nspred+exo_nbr) +% dREDUCEDFORM: [rowredform_nbr by totparam_nbr] in DR order, Jacobian (wrt all params) of REDUCEDFORM +% * order==1: corresponds to Iskrev (2010)'s J_2 matrix +% * order==2: corresponds to Mutschler (2015)'s J matrix +% +% DYNAMIC [rowdyn_nbr by 1] in declaration order. Steady state and dynamic model derivatives for all model variables +% * order==1: [ys' vec(g1)']', rowdyn_nbr=endo_nbr+length(g1) +% * order==2: [ys' vec(g1)' vec(g2)']', rowdyn_nbr=endo_nbr+length(g1)+length(g2) +% * order==3: [ys' vec(g1)' vec(g2)' vec(g3)']', rowdyn_nbr=endo_nbr+length(g1)+length(g2)+length(g3) +% dDYNAMIC [rowdyn_nbr by modparam_nbr] in declaration order. Jacobian (wrt model parameters) of DYNAMIC +% * order==1: corresponds to Ratto and Iskrev (2011)'s J_\Gamma matrix (or LRE) +% +% MOMENTS: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by 1] in DR order. First two theoretical moments for VAROBS variables, i.e. +% [E[varobs]' vech(E[varobs*varobs'])' vec(E[varobs*varobs(-1)'])' ... vec(E[varobs*varobs(-nlag)'])'] +% dMOMENTS: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by totparam_nbr] in DR order. Jacobian (wrt all params) of MOMENTS +% * order==1: corresponds to Iskrev (2010)'s J matrix +% * order==2: corresponds to Mutschler (2015)'s \bar{M}_2 matrix, i.e. theoretical moments from the pruned state space system +% +% dSPECTRUM: [totparam_nbr by totparam_nbr] in DR order. Gram matrix of Jacobian (wrt all params) of mean and of spectral density for VAROBS variables, where +% spectral density at frequency w: f(w) = (2*pi)^(-1)*H(exp(-i*w))*E[Inov*Inov']*ctranspose(H(exp(-i*w)) with H being the Transfer function +% dSPECTRUM = dMEAN*dMEAN + int_{-\pi}^\pi transpose(df(w)/dp')*(df(w)/dp') dw +% * order==1: corresponds to Qu and Tkachenko (2012)'s G matrix, where Inov and H are computed from linear state space system +% * order==2: corresponds to Mutschler (2015)'s G_2 matrix, where Inov and H are computed from second-order pruned state space system +% * order==3: Inov and H are computed from third-order pruned state space system +% +% dSPECTRUM_NO_MEAN:[totparam_nbr by totparam_nbr] in DR order. Gram matrix of Jacobian (wrt all params) of spectral density for VAROBS variables, where +% spectral density at frequency w: f(w) = (2*pi)^(-1)*H(exp(-i*w))*E[Inov*Inov']*ctranspose(H(exp(-i*w)) with H being the Transfer function +% dSPECTRUM = int_{-\pi}^\pi transpose(df(w)/dp')*(df(w)/dp') dw +% * order==1: corresponds to Qu and Tkachenko (2012)'s G matrix, where Inov and H are computed from linear state space system +% * order==2: corresponds to Mutschler (2015)'s G_2 matrix, where Inov and H are computed from second-order pruned state space system +% * order==3: Inov and H are computed from third-order pruned state space system +% +% dMINIMAL: [obs_nbr+minx_nbr^2+minx_nbr*exo_nbr+obs_nbr*minx_nbr+obs_nbr*exo_nbr+exo_nbr*(exo_nbr+1)/2 by totparam_nbr+minx_nbr^2+exo_nbr^2] +% Jacobian (wrt all params, and similarity_transformation_matrices (T and U)) of observational equivalent minimal ABCD system, +% corresponds to Komunjer and Ng (2011)'s Deltabar matrix, where +% MINIMAL = [vec(E[varobs]' vec(minA)' vec(minB)' vec(minC)' vec(minD)' vech(Sigma_e)']' +% minA, minB, minC and minD is the minimal state space system computed in get_minimal_state_representation +% * order==1: E[varobs] is equal to steady state +% * order==2|3: E[varobs] is computed from the pruned state space system (second|third-order accurate), as noted in section 5 of Komunjer and Ng (2011) +% +% derivatives_info [structure] for use in dsge_likelihood to compute Hessian analytically. Only used at order==1. +% Contains dA, dB, and d(B*Sigma_e*B'), where A and B are Kalman filter transition matrice. +% % ------------------------------------------------------------------------- -% This function is called by +% This function is called by % * identification_analysis.m % ------------------------------------------------------------------------- % This function calls @@ -71,15 +88,14 @@ function [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jaco % * get_minimal_state_representation % * duplication % * dyn_vech -% * get_first_order_solution_params_deriv (previously getH) -% * get_all_parameters % * fjaco -% * lyapunov_symm -% * th_autocovariances +% * get_perturbation_params_derivs (previously getH) +% * get_all_parameters % * identification_numerical_objective (previously thet2tau) +% * pruned_state_space_system % * vec % ========================================================================= -% Copyright (C) 2010-2019 Dynare Team +% Copyright (C) 2010-2020 Dynare Team % % This file is part of Dynare. % @@ -97,127 +113,170 @@ function [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jaco % along with Dynare. If not, see . % ========================================================================= -%get options +%get fields from options_ident +no_identification_moments = options_ident.no_identification_moments; +no_identification_minimal = options_ident.no_identification_minimal; +no_identification_spectrum = options_ident.no_identification_spectrum; +order = options_ident.order; nlags = options_ident.ar; useautocorr = options_ident.useautocorr; grid_nbr = options_ident.grid_nbr; kronflag = options_ident.analytic_derivation_mode; -no_identification_moments = options_ident.no_identification_moments; -no_identification_minimal = options_ident.no_identification_minimal; -no_identification_spectrum = options_ident.no_identification_spectrum; -params0 = M.params; %values at which to evaluate dynamic, static and param_derivs files -Sigma_e0 = M.Sigma_e; %covariance matrix of exogenous shocks -Corr_e0 = M.Correlation_matrix; %correlation matrix of exogenous shocks -stderr_e0 = sqrt(diag(Sigma_e0)); %standard errors of exogenous shocks -para0 = get_all_parameters(estim_params, M); %get all selected parameters in estimated_params block, stderr and corr come first, then model parameters -if isempty(para0) + +% get fields from M +endo_nbr = M.endo_nbr; +exo_nbr = M.exo_nbr; +fname = M.fname; +lead_lag_incidence = M.lead_lag_incidence; +nspred = M.nspred; +nstatic = M.nstatic; +params = M.params; +Sigma_e = M.Sigma_e; +stderr_e = sqrt(diag(Sigma_e)); + +% set all selected values: stderr and corr come first, then model parameters +xparam1 = get_all_parameters(estim_params, M); %try using estimated_params block +if isempty(xparam1) %if there is no estimated_params block, consider all stderr and all model parameters, but no corr parameters - para0 = [stderr_e0', params0']; + xparam1 = [stderr_e', params']; end + %get numbers/lengths of vectors modparam_nbr = length(indpmodel); stderrparam_nbr = length(indpstderr); corrparam_nbr = size(indpcorr,1); totparam_nbr = stderrparam_nbr + corrparam_nbr + modparam_nbr; obs_nbr = length(indvobs); -exo_nbr = M.exo_nbr; -endo_nbr = M.endo_nbr; +d2flag = 0; % do not compute second parameter derivatives -%% Construct dTAU, dLRE, dA, dOm, dYss -[dA, dB, dSig, dOm, dYss, dg1] = get_first_order_solution_params_deriv(A, B, estim_params, M, oo, options, kronflag, indpmodel, indpstderr, indpcorr, (1:endo_nbr)'); +% Get Jacobians (wrt selected params) of steady state, dynamic model derivatives and perturbation solution matrices for all endogenous variables +oo.dr.derivs = get_perturbation_params_derivs(M, options, estim_params, oo, indpmodel, indpstderr, indpcorr, d2flag); -% Collect terms for derivative of tau=[Yss; vec(A); vech(Om)] -dTAU = zeros(endo_nbr*endo_nbr+endo_nbr*(endo_nbr+1)/2, totparam_nbr); -for j=1:totparam_nbr - dTAU(:,j) = [vec(dA(:,:,j)); dyn_vech(dOm(:,:,j))]; +[I,~] = find(lead_lag_incidence'); %I is used to select nonzero columns of the Jacobian of endogenous variables in dynamic model files +yy0 = oo.dr.ys(I); %steady state of dynamic (endogenous and auxiliary variables) in lead_lag_incidence order +Yss = oo.dr.ys(oo.dr.order_var); % steady state in DR order +if order == 1 + [~, g1 ] = feval([fname,'.dynamic'], yy0, oo.exo_steady_state', params, oo.dr.ys, 1); + %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + DYNAMIC = [Yss; + vec(g1(oo.dr.order_var,:))]; %add steady state and put rows of g1 in DR order + dDYNAMIC = [oo.dr.derivs.dYss; + reshape(oo.dr.derivs.dg1(oo.dr.order_var,:,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2),size(oo.dr.derivs.dg1,3)) ]; %reshape dg1 in DR order and add steady state + REDUCEDFORM = [Yss; + vec(oo.dr.ghx); + dyn_vech(oo.dr.ghu*Sigma_e*transpose(oo.dr.ghu))]; %in DR order + dREDUCEDFORM = zeros(endo_nbr*nspred+endo_nbr*(endo_nbr+1)/2, totparam_nbr); + for j=1:totparam_nbr + dREDUCEDFORM(:,j) = [vec(oo.dr.derivs.dghx(:,:,j)); + dyn_vech(oo.dr.derivs.dOm(:,:,j))]; + end + dREDUCEDFORM = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) oo.dr.derivs.dYss]; dREDUCEDFORM ]; % add steady state + +elseif order == 2 + [~, g1, g2 ] = feval([fname,'.dynamic'], yy0, oo.exo_steady_state', params, oo.dr.ys, 1); + %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + %g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + DYNAMIC = [Yss; + vec(g1(oo.dr.order_var,:)); + vec(g2(oo.dr.order_var,:))]; %add steady state and put rows of g1 and g2 in DR order + dDYNAMIC = [oo.dr.derivs.dYss; + reshape(oo.dr.derivs.dg1(oo.dr.order_var,:,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2),size(oo.dr.derivs.dg1,3)); %reshape dg1 in DR order + reshape(oo.dr.derivs.dg2(oo.dr.order_var,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2)^2,size(oo.dr.derivs.dg1,3))]; %reshape dg2 in DR order + REDUCEDFORM = [Yss; + vec(oo.dr.ghx); + dyn_vech(oo.dr.ghu*Sigma_e*transpose(oo.dr.ghu)); + vec(oo.dr.ghxx); + vec(oo.dr.ghxu); + vec(oo.dr.ghuu); + vec(oo.dr.ghs2)]; %in DR order + dREDUCEDFORM = zeros(endo_nbr*nspred+endo_nbr*(endo_nbr+1)/2+endo_nbr*nspred^2+endo_nbr*nspred*exo_nbr+endo_nbr*exo_nbr^2+endo_nbr, totparam_nbr); + for j=1:totparam_nbr + dREDUCEDFORM(:,j) = [vec(oo.dr.derivs.dghx(:,:,j)); + dyn_vech(oo.dr.derivs.dOm(:,:,j)); + vec(oo.dr.derivs.dghxx(:,:,j)); + vec(oo.dr.derivs.dghxu(:,:,j)); + vec(oo.dr.derivs.dghuu(:,:,j)); + vec(oo.dr.derivs.dghs2(:,j))]; + end + dREDUCEDFORM = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) oo.dr.derivs.dYss]; dREDUCEDFORM ]; % add steady state +elseif order == 3 + [~, g1, g2, g3 ] = feval([fname,'.dynamic'], yy0, oo.exo_steady_state', params, oo.dr.ys, 1); + %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + %g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + DYNAMIC = [Yss; + vec(g1(oo.dr.order_var,:)); + vec(g2(oo.dr.order_var,:)); + vec(g3(oo.dr.order_var,:))]; %add steady state and put rows of g1 and g2 in DR order + dDYNAMIC = [oo.dr.derivs.dYss; + reshape(oo.dr.derivs.dg1(oo.dr.order_var,:,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2),size(oo.dr.derivs.dg1,3)); %reshape dg1 in DR order + reshape(oo.dr.derivs.dg2(oo.dr.order_var,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2)^2,size(oo.dr.derivs.dg1,3)); + reshape(oo.dr.derivs.dg2(oo.dr.order_var,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2)^2,size(oo.dr.derivs.dg1,3))]; %reshape dg3 in DR order + REDUCEDFORM = [Yss; + vec(oo.dr.ghx); + dyn_vech(oo.dr.ghu*Sigma_e*transpose(oo.dr.ghu)); + vec(oo.dr.ghxx); vec(oo.dr.ghxu); vec(oo.dr.ghuu); vec(oo.dr.ghs2); + vec(oo.dr.ghxxx); vec(oo.dr.ghxxu); vec(oo.dr.ghxuu); vec(oo.dr.ghuuu); vec(oo.dr.ghxss); vec(oo.dr.ghuss)]; %in DR order + dREDUCEDFORM = zeros(size(REDUCEDFORM,1)-endo_nbr, totparam_nbr); + for j=1:totparam_nbr + dREDUCEDFORM(:,j) = [vec(oo.dr.derivs.dghx(:,:,j)); + dyn_vech(oo.dr.derivs.dOm(:,:,j)); + vec(oo.dr.derivs.dghxx(:,:,j)); vec(oo.dr.derivs.dghxu(:,:,j)); vec(oo.dr.derivs.dghuu(:,:,j)); vec(oo.dr.derivs.dghs2(:,j)) + vec(oo.dr.derivs.dghxxx(:,:,j)); vec(oo.dr.derivs.dghxxu(:,:,j)); vec(oo.dr.derivs.dghxuu(:,:,j)); vec(oo.dr.derivs.dghuuu(:,:,j)); vec(oo.dr.derivs.dghxss(:,:,j)); vec(oo.dr.derivs.dghuss(:,:,j))]; + end + dREDUCEDFORM = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) oo.dr.derivs.dYss]; dREDUCEDFORM ]; % add steady state end -dTAU = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) dYss]; dTAU ]; % add steady state -dLRE = [dYss; reshape(dg1,size(dg1,1)*size(dg1,2),size(dg1,3)) ]; %reshape dg1 and add steady state - -%State Space Matrices for VAROBS variables -C = A(indvobs,:); -dC = dA(indvobs,:,:); -D = B(indvobs,:); -dD = dB(indvobs,:,:); - -%% Iskrev (2010) -if ~no_identification_moments - if kronflag == -1 - %numerical derivative of autocovariogram [outputflag=1] - J = fjaco('identification_numerical_objective', para0, 1, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); - M.params = params0; %make sure values are set back - M.Sigma_e = Sigma_e0; %make sure values are set back - M.Correlation_matrix = Corr_e0 ; %make sure values are set back - J = [[zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)]; J]; %add Jacobian of steady state of VAROBS variables + +% Get (pruned) state space representation: +pruned = pruned_state_space_system(M, options, oo.dr, indvobs, nlags, useautocorr, 1); +MEAN = pruned.E_y; +dMEAN = pruned.dE_y; +%storage for Jacobians used in dsge_likelihood.m for analytical Gradient and Hession of likelihood (only at order=1) +derivatives_info = struct(); +if order == 1 + dT = zeros(endo_nbr,endo_nbr,totparam_nbr); + dT(:,(nstatic+1):(nstatic+nspred),:) = oo.dr.derivs.dghx; + derivatives_info.DT = dT; + derivatives_info.DOm = oo.dr.derivs.dOm; + derivatives_info.DYss = oo.dr.derivs.dYss; +end + +%% Compute dMOMENTS +if ~no_identification_moments + if useautocorr + E_yy = pruned.Corr_y; dE_yy = pruned.dCorr_y; + E_yyi = pruned.Corr_yi; dE_yyi = pruned.dCorr_yi; else - J = zeros(obs_nbr + obs_nbr*(obs_nbr+1)/2 + nlags*obs_nbr^2 , totparam_nbr); - J(1:obs_nbr,stderrparam_nbr+corrparam_nbr+1 : totparam_nbr) = dYss(indvobs,:); %add Jacobian of steady state of VAROBS variables - % Denote Ezz0 = E_t(z_t * z_t'), then the following Lyapunov equation defines the autocovariagram: Ezz0 -A*Ezz*A' = B*Sig_e*B' = Om - Gamma_y = lyapunov_symm(A, B*Sigma_e0*B', options.lyapunov_fixed_point_tol, options.qz_criterium, options.lyapunov_complex_threshold, 1, options.debug); - %here method=1 is used, whereas all other calls of lyapunov_symm use method=2. The reason is that T and U are persistent, and input matrix A is the same, so using option 2 for all the rest of iterations spares a lot of computing time while not repeating Schur every time - indzeros = find(abs(Gamma_y) < 1e-12); %find values that are numerical zero - Gamma_y(indzeros) = 0; - % if useautocorr, - sdy = sqrt(diag(Gamma_y)); %theoretical standard deviation - sy = sdy*sdy'; %cross products of standard deviations - % end - for j = 1:(stderrparam_nbr+corrparam_nbr) - %Jacobian of Ezz0 wrt exogenous paramters: dEzz0(:,:,j)-A*dEzz0(:,:,j)*A'=dOm(:,:,j), because dA is zero by construction for stderr and corr parameters - dEzz0 = lyapunov_symm(A,dOm(:,:,j),options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug); - %here method=2 is used to spare a lot of computing time while not repeating Schur every time - indzeros = find(abs(dEzz0) < 1e-12); - dEzz0(indzeros) = 0; - if useautocorr - dsy = 1/2./sdy.*diag(dEzz0); - dsy = dsy*sdy'+sdy*dsy'; - dEzz0corr = (dEzz0.*sy-dsy.*Gamma_y)./(sy.*sy); - dEzz0corr = dEzz0corr-diag(diag(dEzz0corr))+diag(diag(dEzz0)); - J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , j) = dyn_vech(dEzz0corr(indvobs,indvobs)); %focus only on VAROBS variables - else - J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , j) = dyn_vech(dEzz0(indvobs,indvobs)); %focus only on VAROBS variables - end - %Jacobian of Ezzi = E_t(z_t * z_{t-i}'): dEzzi(:,:,j) = A^i*dEzz0(:,:,j) wrt stderr and corr parameters, because dA is zero by construction for stderr and corr parameters + E_yy = pruned.Var_y; dE_yy = pruned.dVar_y; + E_yyi = pruned.Var_yi; dE_yyi = pruned.dVar_yi; + end + MOMENTS = [MEAN; dyn_vech(E_yy)]; + for i=1:nlags + MOMENTS = [MOMENTS; vec(E_yyi(:,:,i))]; + end + + if kronflag == -1 + %numerical derivative of autocovariogram + dMOMENTS = fjaco(str2func('identification_numerical_objective'), xparam1, 1, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); %[outputflag=1] + dMOMENTS = [dMEAN; dMOMENTS]; %add Jacobian of steady state of VAROBS variables + else + dMOMENTS = zeros(obs_nbr + obs_nbr*(obs_nbr+1)/2 + nlags*obs_nbr^2 , totparam_nbr); + dMOMENTS(1:obs_nbr,:) = dMEAN; %add Jacobian of first moments of VAROBS variables + for jp = 1:totparam_nbr + dMOMENTS(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , jp) = dyn_vech(dE_yy(:,:,jp)); for i = 1:nlags - dEzzi = A^i*dEzz0; - if useautocorr - dEzzi = (dEzzi.*sy-dsy.*(A^i*Gamma_y))./(sy.*sy); - end - J(obs_nbr + obs_nbr*(obs_nbr+1)/2 + (i-1)*obs_nbr^2 + 1 : obs_nbr + obs_nbr*(obs_nbr+1)/2 + i*obs_nbr^2, j) = vec(dEzzi(indvobs,indvobs)); %focus only on VAROBS variables - end - end - for j=1:modparam_nbr - %Jacobian of Ezz0 wrt model parameters: dEzz0(:,:,j) - A*dEzz0(:,:,j)*A' = dOm(:,:,j) + dA(:,:,j)*Ezz*A'+ A*Ezz*dA(:,:,j)' - dEzz0 = lyapunov_symm(A,dA(:,:,j+stderrparam_nbr+corrparam_nbr)*Gamma_y*A'+A*Gamma_y*dA(:,:,j+stderrparam_nbr+corrparam_nbr)'+dOm(:,:,j+stderrparam_nbr+corrparam_nbr),options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug); - %here method=2 is used to spare a lot of computing time while not repeating Schur every time - indzeros = find(abs(dEzz0) < 1e-12); - dEzz0(indzeros) = 0; - if useautocorr - dsy = 1/2./sdy.*diag(dEzz0); - dsy = dsy*sdy'+sdy*dsy'; - dEzz0corr = (dEzz0.*sy-dsy.*Gamma_y)./(sy.*sy); - dEzz0corr = dEzz0corr-diag(diag(dEzz0corr))+diag(diag(dEzz0)); - J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , stderrparam_nbr+corrparam_nbr+j) = dyn_vech(dEzz0corr(indvobs,indvobs)); %focus only on VAROBS variables - else - J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , stderrparam_nbr+corrparam_nbr+j) = dyn_vech(dEzz0(indvobs,indvobs)); %focus only on VAROBS variables - end - %Jacobian of Ezzi = E_t(z_t * z_{t-i}'): dEzzi(:,:,j) = A^i*dEzz0(:,:,j) + d(A^i)*dEzz0(:,:,j) wrt model parameters - for i = 1:nlags - dEzzi = A^i*dEzz0; - for ii=1:i - dEzzi = dEzzi + A^(ii-1)*dA(:,:,j+stderrparam_nbr+corrparam_nbr)*A^(i-ii)*Gamma_y; - end - if useautocorr - dEzzi = (dEzzi.*sy-dsy.*(A^i*Gamma_y))./(sy.*sy); - end - J(obs_nbr + obs_nbr*(obs_nbr+1)/2 + (i-1)*obs_nbr^2 + 1 : obs_nbr + obs_nbr*(obs_nbr+1)/2 + i*obs_nbr^2, j+stderrparam_nbr+corrparam_nbr) = vec(dEzzi(indvobs,indvobs)); %focus only on VAROBS variables + dMOMENTS(obs_nbr + obs_nbr*(obs_nbr+1)/2 + (i-1)*obs_nbr^2 + 1 : obs_nbr + obs_nbr*(obs_nbr+1)/2 + i*obs_nbr^2, jp) = vec(dE_yyi(:,:,i,jp)); end end end else - J = []; + MOMENTS = []; + dMOMENTS = []; end - -%% Qu and Tkachenko (2012) + +%% Compute dSPECTRUM +%Note that our state space system for computing the spectrum is the following: +% zhat = A*zhat(-1) + B*xi, where zhat = z - E(z) +% yhat = C*zhat(-1) + D*xi, where yhat = y - E(y) if ~no_identification_spectrum %Some info on the spectral density: Dynare's state space system is given for states (z_{t} = A*z_{t-1} + B*u_{t}) and observables (y_{t} = C*z_{t-1} + D*u_{t}) %The spectral density for y_{t} can be computed using different methods, which are numerically equivalent @@ -226,19 +285,19 @@ if ~no_identification_spectrum % tpos = exp( sqrt(-1)*freqs); %positive Fourier frequencies % tneg = exp(-sqrt(-1)*freqs); %negative Fourier frequencies % IA = eye(size(A,1)); -% IE = eye(M.exo_nbr); +% IE = eye(exo_nbr); % mathp_col1 = NaN(length(freqs),obs_nbr^2); mathp_col2 = mathp_col1; mathp_col3 = mathp_col1; mathp_col4 = mathp_col1; % for ig = 1:length(freqs) % %method 1: as in UnivariateSpectralDensity.m -% f_omega =(1/(2*pi))*( [(IA-A*tneg(ig))\B;IE]*M.Sigma_e*[B'/(IA-A'*tpos(ig)) IE]); % state variables +% f_omega =(1/(2*pi))*( [(IA-A*tneg(ig))\B;IE]*Sigma_e*[B'/(IA-A'*tpos(ig)) IE]); % state variables % g_omega1 = [C*tneg(ig) D]*f_omega*[C'*tpos(ig); D']; % selected variables % %method 2: as in UnivariateSpectralDensity.m but simplified algebraically -% g_omega2 = (1/(2*pi))*( C*((tpos(ig)*IA-A)\(B*M.Sigma_e*B'))*((tneg(ig)*IA-A')\(C')) + D*M.Sigma_e*B'*((tneg(ig)*IA-A')\(C')) + C* ((tpos(ig)*IA-A)\(B*M.Sigma_e*D')) + D*M.Sigma_e*D' ); +% g_omega2 = (1/(2*pi))*( C*((tpos(ig)*IA-A)\(B*Sigma_e*B'))*((tneg(ig)*IA-A')\(C')) + D*Sigma_e*B'*((tneg(ig)*IA-A')\(C')) + C* ((tpos(ig)*IA-A)\(B*Sigma_e*D')) + D*Sigma_e*D' ); % %method 3: use transfer function note that ' is the complex conjugate transpose operator i.e. transpose(ffneg')==ffpos % Transferfct = D+C*((tpos(ig)*IA-A)\B); -% g_omega3 = (1/(2*pi))*(Transferfct*M.Sigma_e*Transferfct'); +% g_omega3 = (1/(2*pi))*(Transferfct*Sigma_e*Transferfct'); % %method 4: kronecker products -% g_omega4 = (1/(2*pi))*( kron( D+C*((tneg(ig)^(-1)*IA-A)\B) , D+C*((tneg(ig)*IA-A)\B) )*M.Sigma_e(:)); +% g_omega4 = (1/(2*pi))*( kron( D+C*((tneg(ig)^(-1)*IA-A)\B) , D+C*((tneg(ig)*IA-A)\B) )*Sigma_e(:)); % % store as matrix row % mathp_col1(ig,:) = (g_omega1(:))'; mathp_col2(ig,:) = (g_omega2(:))'; mathp_col3(ig,:) = (g_omega3(:))'; mathp_col4(ig,:) = g_omega4; % end @@ -251,84 +310,76 @@ if ~no_identification_spectrum freqs = (0 : pi/(grid_nbr/2):pi); % we focus only on positive frequencies tpos = exp( sqrt(-1)*freqs); %positive Fourier frequencies tneg = exp(-sqrt(-1)*freqs); %negative Fourier frequencies - IA = eye(size(A,1)); + IA = eye(size(pruned.A,1)); if kronflag == -1 - %numerical derivative of spectral density [outputflag=2] - dOmega_tmp = fjaco('identification_numerical_objective', para0, 2, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); - M.params = params0; %make sure values are set back - M.Sigma_e = Sigma_e0; %make sure values are set back - M.Correlation_matrix = Corr_e0 ; %make sure values are set back + %numerical derivative of spectral density + dOmega_tmp = fjaco(str2func('identification_numerical_objective'), xparam1, 2, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); %[outputflag=2] kk = 0; for ig = 1:length(freqs) kk = kk+1; dOmega = dOmega_tmp(1 + (kk-1)*obs_nbr^2 : kk*obs_nbr^2,:); if ig == 1 % add zero frequency once - G = dOmega'*dOmega; + dSPECTRUM_NO_MEAN = dOmega'*dOmega; else % due to symmetry to negative frequencies we can add positive frequencies twice - G = G + 2*(dOmega'*dOmega); + dSPECTRUM_NO_MEAN = dSPECTRUM_NO_MEAN + 2*(dOmega'*dOmega); end end - elseif kronflag == 1 + elseif kronflag == 1 %use Kronecker products - dA = reshape(dA,size(dA,1)*size(dA,2),size(dA,3)); - dB = reshape(dB,size(dB,1)*size(dB,2),size(dB,3)); - dC = reshape(dC,size(dC,1)*size(dC,2),size(dC,3)); - dD = reshape(dD,size(dD,1)*size(dD,2),size(dD,3)); - dSig = reshape(dSig,size(dSig,1)*size(dSig,2),size(dSig,3)); - K_obs_exo = commutation(obs_nbr,exo_nbr); + dA = reshape(pruned.dA,size(pruned.dA,1)*size(pruned.dA,2),size(pruned.dA,3)); + dB = reshape(pruned.dB,size(pruned.dB,1)*size(pruned.dB,2),size(pruned.dB,3)); + dC = reshape(pruned.dC,size(pruned.dC,1)*size(pruned.dC,2),size(pruned.dC,3)); + dD = reshape(pruned.dD,size(pruned.dD,1)*size(pruned.dD,2),size(pruned.dD,3)); + dVarinov = reshape(pruned.dVarinov,size(pruned.dVarinov,1)*size(pruned.dVarinov,2),size(pruned.dVarinov,3)); + K_obs_exo = commutation(obs_nbr,size(pruned.Varinov,1)); for ig=1:length(freqs) z = tneg(ig); - zIminusA = (z*IA - A); + zIminusA = (z*IA - pruned.A); zIminusAinv = zIminusA\IA; - Transferfct = D + C*zIminusAinv*B; % Transfer function + Transferfct = pruned.D + pruned.C*zIminusAinv*pruned.B; % Transfer function dzIminusA = -dA; - dzIminusAinv = kron(-(transpose(zIminusA)\IA),zIminusAinv)*dzIminusA; - dTransferfct = dD + DerivABCD(C,dC,zIminusAinv,dzIminusAinv,B,dB); + dzIminusAinv = kron(-(transpose(zIminusA)\IA),zIminusAinv)*dzIminusA; %this takes long + dTransferfct = dD + DerivABCD(pruned.C,dC,zIminusAinv,dzIminusAinv,pruned.B,dB); %this takes long dTransferfct_conjt = K_obs_exo*conj(dTransferfct); - dOmega = (1/(2*pi))*DerivABCD(Transferfct,dTransferfct,Sigma_e0,dSig,Transferfct',dTransferfct_conjt); + dOmega = (1/(2*pi))*DerivABCD(Transferfct,dTransferfct,pruned.Varinov,dVarinov,Transferfct',dTransferfct_conjt); %also long if ig == 1 % add zero frequency once - G = dOmega'*dOmega; + dSPECTRUM_NO_MEAN = dOmega'*dOmega; else % due to symmetry to negative frequencies we can add positive frequencies twice - G = G + 2*(dOmega'*dOmega); + dSPECTRUM_NO_MEAN = dSPECTRUM_NO_MEAN + 2*(dOmega'*dOmega); end end - %put back into tensor notation - dA = reshape(dA,endo_nbr,endo_nbr,totparam_nbr); - dB = reshape(dB,endo_nbr,exo_nbr,totparam_nbr); - dC = reshape(dC,obs_nbr,endo_nbr,totparam_nbr); - dD = reshape(dD,obs_nbr,exo_nbr,totparam_nbr); - dSig = reshape(dSig,exo_nbr,exo_nbr,totparam_nbr); elseif (kronflag==0) || (kronflag==-2) for ig = 1:length(freqs) - IzminusA = tpos(ig)*IA - A; - invIzminusA = IzminusA\eye(endo_nbr); - Transferfct = D + C*invIzminusA*B; + IzminusA = tpos(ig)*IA - pruned.A; + invIzminusA = IzminusA\eye(size(pruned.A,1)); + Transferfct = pruned.D + pruned.C*invIzminusA*pruned.B; dOmega = zeros(obs_nbr^2,totparam_nbr); for j = 1:totparam_nbr if j <= stderrparam_nbr+corrparam_nbr %stderr and corr parameters: only dSig is nonzero - dOmega_tmp = Transferfct*dSig(:,:,j)*Transferfct'; + dOmega_tmp = Transferfct*pruned.dVarinov(:,:,j)*Transferfct'; else %model parameters - dinvIzminusA = -invIzminusA*(-dA(:,:,j))*invIzminusA; - dTransferfct = dD(:,:,j) + dC(:,:,j)*invIzminusA*B + C*dinvIzminusA*B + C*invIzminusA*dB(:,:,j); - dOmega_tmp = dTransferfct*M.Sigma_e*Transferfct' + Transferfct*dSig(:,:,j)*Transferfct' + Transferfct*M.Sigma_e*dTransferfct'; + dinvIzminusA = -invIzminusA*(-pruned.dA(:,:,j))*invIzminusA; + dTransferfct = pruned.dD(:,:,j) + pruned.dC(:,:,j)*invIzminusA*pruned.B + pruned.C*dinvIzminusA*pruned.B + pruned.C*invIzminusA*pruned.dB(:,:,j); + dOmega_tmp = dTransferfct*pruned.Varinov*Transferfct' + Transferfct*pruned.dVarinov(:,:,j)*Transferfct' + Transferfct*pruned.Varinov*dTransferfct'; end dOmega(:,j) = (1/(2*pi))*dOmega_tmp(:); end if ig == 1 % add zero frequency once - G = dOmega'*dOmega; + dSPECTRUM_NO_MEAN = dOmega'*dOmega; else % due to symmetry to negative frequencies we can add positive frequencies twice - G = G + 2*(dOmega'*dOmega); + dSPECTRUM_NO_MEAN = dSPECTRUM_NO_MEAN + 2*(dOmega'*dOmega); end - end - end + end + end % Normalize Matrix and add steady state Jacobian, note that G is real and symmetric by construction - G = 2*pi*G./(2*length(freqs)-1) + [zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)]'*[zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)]; - G = real(G); + dSPECTRUM_NO_MEAN = real(2*pi*dSPECTRUM_NO_MEAN./(2*length(freqs)-1)); + dSPECTRUM = dSPECTRUM_NO_MEAN + dMEAN'*dMEAN; else - G = []; + dSPECTRUM_NO_MEAN = []; + dSPECTRUM = []; end -%% Komunjer and Ng (2012) +%% Compute dMINIMAL if ~no_identification_minimal if obs_nbr < exo_nbr % Check whether criteria can be used @@ -336,36 +387,36 @@ if ~no_identification_minimal warning_KomunjerNg = [warning_KomunjerNg ' There are more shocks and measurement errors than observables, this is not implemented (yet).\n']; warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n']; fprintf(warning_KomunjerNg); - D = []; + dMINIMAL = []; else - % Derive and check minimal state - if isfield(oo.dr,'state_var') - state_var = oo.dr.state_var; %state variables in declaration order - else - % DR-order: static variables first, then purely backward variables, then mixed variables, finally purely forward variables. - % Inside each category, variables are arranged according to the declaration order. - % state variables are the purely backward variables and the mixed variables - state_var = transpose(oo.dr.order_var( (M.nstatic+1):(M.nstatic+M.npred+M.nboth) ) ); %state variables in declaration order - end - state_var_DR = oo.dr.inv_order_var(state_var); %state vector in DR order - minA = A(state_var_DR,state_var_DR); dminA = dA(state_var_DR,state_var_DR,:); - minB = B(state_var_DR,:); dminB = dB(state_var_DR,:,:); - minC = C(:,state_var_DR); dminC = dC(:,state_var_DR,:); - minD = D(:,:); dminD = dD(:,:,:); - [CheckCO,minnx,minA,minB,minC,minD,dminA,dminB,dminC,dminD] = get_minimal_state_representation(minA,minB,minC,minD,dminA,dminB,dminC,dminD); + % Derive and check minimal state vector of first-order + SYS.A = oo.dr.ghx(pruned.indx,:); + SYS.dA = oo.dr.derivs.dghx(pruned.indx,:,:); + SYS.B = oo.dr.ghu(pruned.indx,:); + SYS.dB = oo.dr.derivs.dghu(pruned.indx,:,:); + SYS.C = oo.dr.ghx(pruned.indy,:); + SYS.dC = oo.dr.derivs.dghx(pruned.indy,:,:); + SYS.D = oo.dr.ghu(pruned.indy,:); + SYS.dD = oo.dr.derivs.dghu(pruned.indy,:,:); + [CheckCO,minnx,SYS] = get_minimal_state_representation(SYS,1); + if CheckCO == 0 warning_KomunjerNg = 'WARNING: Komunjer and Ng (2011) failed:\n'; warning_KomunjerNg = [warning_KomunjerNg ' Conditions for minimality are not fullfilled:\n']; warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n']; fprintf(warning_KomunjerNg); %use sprintf to have line breaks - D = []; + dMINIMAL = []; else + minA = SYS.A; dminA = SYS.dA; + minB = SYS.B; dminB = SYS.dB; + minC = SYS.C; dminC = SYS.dC; + minD = SYS.D; dminD = SYS.dD; %reshape into Magnus-Neudecker Jacobians, i.e. dvec(X)/dp dminA = reshape(dminA,size(dminA,1)*size(dminA,2),size(dminA,3)); dminB = reshape(dminB,size(dminB,1)*size(dminB,2),size(dminB,3)); dminC = reshape(dminC,size(dminC,1)*size(dminC,2),size(dminC,3)); dminD = reshape(dminD,size(dminD,1)*size(dminD,2),size(dminD,3)); - dvechSig = reshape(dSig,size(dSig,1)*size(dSig,2),size(dSig,3)); + dvechSig = reshape(oo.dr.derivs.dSigma_e,exo_nbr*exo_nbr,totparam_nbr); indvechSig= find(tril(ones(exo_nbr,exo_nbr))); dvechSig = dvechSig(indvechSig,:); Inx = eye(minnx); @@ -378,67 +429,42 @@ if ~no_identification_minimal zeros(obs_nbr*exo_nbr,minnx^2); zeros(exo_nbr*(exo_nbr+1)/2,minnx^2)]; KomunjerNg_DU = [zeros(minnx^2,exo_nbr^2); - kron(Inu,minB); + kron(Inu,minB); zeros(obs_nbr*minnx,exo_nbr^2); kron(Inu,minD); - -2*Enu*kron(M.Sigma_e,Inu)]; - D = full([KomunjerNg_DL KomunjerNg_DT KomunjerNg_DU]); - %add Jacobian of steady state - D = [[zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)], zeros(obs_nbr,minnx^2+exo_nbr^2); D]; + -2*Enu*kron(Sigma_e,Inu)]; + dMINIMAL = full([KomunjerNg_DL KomunjerNg_DT KomunjerNg_DU]); + %add Jacobian of steady state (here we also allow for higher-order perturbation, i.e. only the mean provides additional restrictions + dMINIMAL = [dMEAN zeros(obs_nbr,minnx^2+exo_nbr^2); dMINIMAL]; end end else - D = []; -end - -if nargout > 8 - options.ar = nlags; - nodecomposition = 1; - [Gamma_y,~] = th_autocovariances(oo.dr,oo.dr.order_var(indvobs),M,options,nodecomposition); %focus only on observed variables - sdy=sqrt(diag(Gamma_y{1})); %theoretical standard deviation - sy=sdy*sdy'; %cross products of standard deviations - if useautocorr - sy=sy-diag(diag(sy))+eye(obs_nbr); - Gamma_y{1}=Gamma_y{1}./sy; - else - for j=1:nlags - Gamma_y{j+1}=Gamma_y{j+1}.*sy; - end - end - %Ezz is vector of theoretical moments of VAROBS variables - MOMENTS = dyn_vech(Gamma_y{1}); - for j=1:nlags - MOMENTS = [MOMENTS; vec(Gamma_y{j+1})]; - end - MOMENTS = [oo.dr.ys(oo.dr.order_var(indvobs)); MOMENTS]; + dMINIMAL = []; end -function [dX] = DerivABCD(A,dA,B,dB,C,dC,D,dD) -% function [dX] = DerivABCD(A,dA,B,dB,C,dC,D,dD) +function [dX] = DerivABCD(X1,dX1,X2,dX2,X3,dX3,X4,dX4) +% function [dX] = DerivABCD(X1,dX1,X2,dX2,X3,dX3,X4,dX4) % ------------------------------------------------------------------------- -% Derivative of X(p)=A(p)*B(p)*C(p)*D(p) w.r.t to p +% Derivative of X(p)=X1(p)*X2(p)*X3(p)*X4(p) w.r.t to p % See Magnus and Neudecker (1999), p. 175 % ------------------------------------------------------------------------- -% Inputs: Matrices A,B,C,D, and the corresponding derivatives w.r.t p. -% Output: Derivative of product of A*B*C*D w.r.t. p +% Inputs: Matrices X1,X2,X3,X4, and the corresponding derivatives w.r.t p. +% Output: Derivative of product of X1*X2*X3*X4 w.r.t. p % ========================================================================= -nparam = size(dA,2); +nparam = size(dX1,2); % If one or more matrices are left out, they are set to zero if nargin == 4 - C=speye(size(B,2)); dC=spalloc(numel(C),nparam,0); - D=speye(size(C,2)); dD=spalloc(numel(D),nparam,0); + X3=speye(size(X2,2)); dX3=spalloc(numel(X3),nparam,0); + X4=speye(size(X3,2)); dX4=spalloc(numel(X4),nparam,0); elseif nargin == 6 - D=speye(size(C,2)); dD=spalloc(numel(D),nparam,0); + X4=speye(size(X3,2)); dX4=spalloc(numel(X4),nparam,0); end -dX1 = kron(transpose(D)*transpose(C)*transpose(B),speye(size(A,1)))*dA; -dX2 = kron(transpose(D)*transpose(C),A)*dB; -dX3 = kron(transpose(D),A*B)*dC; -dX4 = kron(speye(size(D,2)),A*B*C)*dD; -dX= dX1+dX2+dX3+dX4; +dX = kron(transpose(X4)*transpose(X3)*transpose(X2),speye(size(X1,1)))*dX1... + + kron(transpose(X4)*transpose(X3),X1)*dX2... + + kron(transpose(X4),X1*X2)*dX3... + + kron(speye(size(X4,2)),X1*X2*X3)*dX4; end %DerivABCD end -end%main function end - - +end%main function end \ No newline at end of file diff --git a/matlab/get_minimal_state_representation.m b/matlab/get_minimal_state_representation.m index 9069c4134..1ce6da53c 100644 --- a/matlab/get_minimal_state_representation.m +++ b/matlab/get_minimal_state_representation.m @@ -1,49 +1,65 @@ -function [CheckCO,minnx,minA,minB,minC,minD,dminA,dminB,dminC,dminD] = get_minimal_state_representation(A,B,C,D,dA,dB,dC,dD) -% [CheckCO,minnx,minA,minB,minC,minD,dminA,dminB,dminC,dminD] = get_minimal_state_representation(A,B,C,D,dA,dB,dC,dD) -% Derives and checks the minimal state representation of the ABCD -% representation of a state space model +function [CheckCO,minns,minSYS] = get_minimal_state_representation(SYS, derivs_flag) +% Derives and checks the minimal state representation +% Let x = A*x(-1) + B*u and y = C*x(-1) + D*u be a linear state space +% system, then this function computes the following representation +% xmin = minA*xmin(-1) + minB*u and and y=minC*xmin(-1) + minD*u +% % ------------------------------------------------------------------------- % INPUTS -% A: [endo_nbr by endo_nbr] Transition matrix from Kalman filter -% for all endogenous declared variables, in DR order -% B: [endo_nbr by exo_nbr] Transition matrix from Kalman filter -% mapping shocks today to endogenous variables today, in DR order -% C: [obs_nbr by endo_nbr] Measurement matrix from Kalman filter -% linking control/observable variables to states, in DR order -% D: [obs_nbr by exo_nbr] Measurement matrix from Kalman filter -% mapping shocks today to controls/observables today, in DR order -% dA: [endo_nbr by endo_nbr by totparam_nbr] in DR order +% SYS [structure] +% with the following necessary fields: +% A: [nspred by nspred] in DR order +% Transition matrix for all state variables +% B: [nspred by exo_nbr] in DR order +% Transition matrix mapping shocks today to states today +% C: [varobs_nbr by nspred] in DR order +% Measurement matrix linking control/observable variables to states +% D: [varobs_nbr by exo_nbr] in DR order +% Measurement matrix mapping shocks today to controls/observables today +% and optional fields: +% dA: [nspred by nspred by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of transition matrix A -% dB: [endo_nbr by exo_nbr by totparam_nbr] in DR order +% dB: [nspred by exo_nbr by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of transition matrix B -% dC: [obs_nbr by endo_nbr by totparam_nbr] in DR order +% dC: [varobs_nbr by nspred by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of measurement matrix C -% dD: [obs_nbr by exo_nbr by totparam_nbr] in DR order +% dD: [varobs_nbr by exo_nbr by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of measurement matrix D +% derivs_flag [scalar] +% (optional) indicator whether to output parameter derivatives % ------------------------------------------------------------------------- % OUTPUTS -% CheckCO: [scalar] indicator, equals to 1 if minimal state representation is found -% minnx: [scalar] length of minimal state vector -% minA: [minnx by minnx] Transition matrix A for evolution of minimal state vector -% minB: [minnx by exo_nbr] Transition matrix B for evolution of minimal state vector -% minC: [obs_nbr by minnx] Measurement matrix C for evolution of controls, depending on minimal state vector only -% minD: [obs_nbr by minnx] Measurement matrix D for evolution of controls, depending on minimal state vector only -% dminA: [minnx by minnx by totparam_nbr] in DR order +% CheckCO: [scalar] +% equals to 1 if minimal state representation is found +% minns: [scalar] +% length of minimal state vector +% SYS [structure] +% with the following fields: +% minA: [minns by minns] in DR-order +% transition matrix A for evolution of minimal state vector +% minB: [minns by exo_nbr] in DR-order +% transition matrix B for evolution of minimal state vector +% minC: [varobs_nbr by minns] in DR-order +% measurement matrix C for evolution of controls, depending on minimal state vector only +% minD: [varobs_nbr by minns] in DR-order +% measurement matrix D for evolution of controls, depending on minimal state vector only +% dminA: [minns by minns by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of transition matrix minA -% dminB: [minnx by exo_nbr by totparam_nbr] in DR order +% dminB: [minns by exo_nbr by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of transition matrix minB -% dminC: [obs_nbr by minnx by totparam_nbr] in DR order +% dminC: [varobs_nbr by minns by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of measurement matrix minC -% dminD: [obs_nbr by exo_nbr by totparam_nbr] in DR order +% dminD: [varobs_nbr by u_nbr by totparam_nbr] in DR order % Jacobian (wrt to all parameters) of measurement matrix minD % ------------------------------------------------------------------------- -% This function is called by +% This function is called by % * get_identification_jacobians.m (previously getJJ.m) % ------------------------------------------------------------------------- % This function calls % * check_minimality (embedded) +% * minrealold (embedded) % ========================================================================= -% Copyright (C) 2019 Dynare Team +% Copyright (C) 2019-2020 Dynare Team % % This file is part of Dynare. % @@ -60,102 +76,123 @@ function [CheckCO,minnx,minA,minB,minC,minD,dminA,dminB,dminC,dminD] = get_minim % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . % ========================================================================= - -nx = size(A,2); -ny = size(C,1); -nu = size(B,2); +if nargin == 1 + derivs_flag = 0; +end +realsmall = 1e-7; +[nspred,exo_nbr] = size(SYS.B); +varobs_nbr = size(SYS.C,1); % Check controllability and observability conditions for full state vector -CheckCO = check_minimality(A,B,C); - -if CheckCO == 1 % If model is already minimal - minnx = nx; - minA = A; - minB = B; - minC = C; - minD = D; - if nargout > 6 - dminA = dA; - dminB = dB; - dminC = dC; - dminD = dD; - end +CheckCO = check_minimality(SYS.A,SYS.B,SYS.C); +if CheckCO == 1 % If model is already minimal, we are finished + minns = nspred; + minSYS = SYS; else - %Model is not minimal - realsmall = 1e-7; - % create indices for unnecessary states - endogstateindex = find(abs(sum(A,1))realsmall); - minnx = length(exogstateindex); - % remove unnecessary states from solution matrices - A_1 = A(endogstateindex,exogstateindex); - A_2 = A(exogstateindex,exogstateindex); - B_2 = B(exogstateindex,:); - C_1 = C(:,endogstateindex); - C_2 = C(:,exogstateindex); - D = D; - ind_A1 = endogstateindex; - ind_A2 = exogstateindex; - % minimal representation - minA = A_2; - minB = B_2; - minC = C_2; - minD = D; - % Check controllability and observability conditions - CheckCO = check_minimality(minA,minB,minC); - - if CheckCO ~=1 - j=1; - while (CheckCO==0 && j 6 - dminA = dA(ind_A2,ind_A2,:); - dminB = dB(ind_A2,:,:); - dminC = dC(:,ind_A2,:); - dminD = dD; + + if minreal_flag == 0 + fprintf('Use naive brute-force approach to find minimal state space system.\n These computations may be inaccurate/wrong as ''minreal'' is not available, please raise an issue on GitLab or the forum\n') + % create indices for unnecessary states + exogstateindex = find(abs(sum(SYS.A,1))>realsmall); + minns = length(exogstateindex); + % remove unnecessary states from solution matrices + A_2 = SYS.A(exogstateindex,exogstateindex); + B_2 = SYS.B(exogstateindex,:); + C_2 = SYS.C(:,exogstateindex); + D = SYS.D; + ind_A2 = exogstateindex; + % minimal representation + minSYS.A = A_2; + minSYS.B = B_2; + minSYS.C = C_2; + minSYS.D = D; + + % Check controllability and observability conditions + CheckCO = check_minimality(minSYS.A,minSYS.B,minSYS.C); + + if CheckCO ~=1 + % do brute-force search + j=1; + while (CheckCO==0 && j= 2 for indn = 1:1:n-1 - CC = [CC, (A^indn)*B]; % Set up controllability matrix - OO = [OO; C*(A^indn)]; % Set up observability matrix + CC = [CC, (a^indn)*b]; % Set up controllability matrix + OO = [OO; c*(a^indn)]; % Set up observability matrix end end CheckC = (rank(full(CC))==n); % Check rank of controllability matrix @@ -163,4 +200,89 @@ CheckO = (rank(full(OO))==n); % Check rank of observability matrix CheckCO = CheckC&CheckO; % equals 1 if minimal state end % check_minimality end +function [mSYS,U] = minrealold(SYS,tol) + % This is a temporary replacement for minreal, will be replaced by a mex file from SLICOT TB01PD.f soon + a = SYS.A; + b = SYS.B; + c = SYS.C; + [ns,nu] = size(b); + [am,bm,cm,U,k] = ControllabilityStaircaseRosenbrock(a,b,c,tol); + kk = sum(k); + nu = ns - kk; + nn = nu; + am = am(nu+1:ns,nu+1:ns); + bm = bm(nu+1:ns,:); + cm = cm(:,nu+1:ns); + ns = ns - nu; + if ns + [am,bm,cm,t,k] = ObservabilityStaircaseRosenbrock(am,bm,cm,tol); + kk = sum(k); + nu = ns - kk; + nn = nn + nu; + am = am(nu+1:ns,nu+1:ns); + bm = bm(nu+1:ns,:); + cm = cm(:,nu+1:ns); + end + mSYS.A = am; + mSYS.B = bm; + mSYS.C = cm; + mSYS.D = SYS.D; +end + + +function [abar,bbar,cbar,t,k] = ObservabilityStaircaseRosenbrock(a,b,c,tol) + %Observability staircase form + [aa,bb,cc,t,k] = ControllabilityStaircaseRosenbrock(a',c',b',tol); + abar = aa'; bbar = cc'; cbar = bb'; +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); + ptjn1 = eye(ra); + ajn1 = a; + bjn1 = b; + rojn1 = cb; + deltajn1 = 0; + sigmajn1 = ra; + k = zeros(1,ra); + if nargin == 3 + tol = ra*norm(a,1)*eps; + end + for jj = 1 : ra + [uj,sj,vj] = svd(bjn1); + [rsj,csj] = size(sj); + %p = flip(eye(rsj),2); + p = eye(rsj); + p = p(:,end:-1:1); + p = permute(p,[2 1 3:ndims(eye(rsj))]); + uj = uj*p; + bb = uj'*bjn1; + roj = rank(bb,tol); + [rbb,cbb] = size(bb); + sigmaj = rbb - roj; + sigmajn1 = sigmaj; + k(jj) = roj; + if roj == 0, break, end + if sigmaj == 0, break, end + abxy = uj' * ajn1 * uj; + aj = abxy(1:sigmaj,1:sigmaj); + bj = abxy(1:sigmaj,sigmaj+1:sigmaj+roj); + ajn1 = aj; + bjn1 = bj; + [ruj,cuj] = size(uj); + ptj = ptjn1 * ... + [uj zeros(ruj,deltajn1); ... + zeros(deltajn1,cuj) eye(deltajn1)]; + ptjn1 = ptj; + deltaj = deltajn1 + roj; + deltajn1 = deltaj; + end + t = ptjn1'; + abar = t * a * t'; + bbar = t * b; + cbar = c * t'; +end + end % Main function end diff --git a/matlab/get_perturbation_params_derivs.m b/matlab/get_perturbation_params_derivs.m new file mode 100644 index 000000000..2deb29da7 --- /dev/null +++ b/matlab/get_perturbation_params_derivs.m @@ -0,0 +1,1600 @@ +function DERIVS = get_perturbation_params_derivs(M, options, estim_params, oo, indpmodel, indpstderr, indpcorr, d2flag) +% DERIVS = get_perturbation_params_derivs(M, options, estim_params, oo, indpmodel, indpstderr, indpcorr, d2flag) +% previously getH.m in dynare 4.5 +% ------------------------------------------------------------------------- +% Computes derivatives (with respect to parameters) of +% (1) steady-state (ys) and covariance matrix of shocks (Sigma_e) +% (2) dynamic model jacobians (g1, g2, g3) +% (3) perturbation solution matrices: +% * order==1: ghx,ghu +% * order==2: ghx,ghu,ghxx,ghxu,ghuu,ghs2 +% * order==3: ghx,ghu,ghxx,ghxu,ghuu,ghs2,ghxxx,ghxxu,ghxuu,ghuuu,ghxss,ghuss +% Note that the order in the parameter Jacobians is the following: +% (1) stderr parameters (indpstderr) +% (2) corr parameters (indpcorr) +% (3) model parameters (indpmodel) +% +% ========================================================================= +% INPUTS +% M: [structure] storing the model information +% options: [structure] storing the options +% estim_params: [structure] storing the estimation information +% oo: [structure] storing the solution results +% indpmodel: [modparam_nbr by 1] index of selected (estimated) parameters in M.params; +% corresponds to model parameters (no stderr and no corr) in estimated_params block +% indpstderr: [stderrparam_nbr by 1] index of selected (estimated) standard errors, +% i.e. for all exogenous variables where 'stderr' is given in the estimated_params block +% indpcorr: [corrparam_nbr by 2] matrix of selected (estimated) correlations, +% i.e. for all exogenous variables where 'corr' is given in the estimated_params block +% d2flag: [boolean] flag to compute second-order parameter derivatives of steady state and first-order Kalman transition matrices +% ------------------------------------------------------------------------- +% OUTPUTS +% DERIVS: Structure with the following fields: +% dYss: [endo_nbr by modparam_nbr] in DR order +% Jacobian (wrt model parameters only) of steady state, i.e. ys(order_var,:) +% dSigma_e: [exo_nbr by exo_nbr by totparam_nbr] in declaration order +% Jacobian (wrt to all paramters) of covariance matrix of shocks, i.e. Sigma_e +% dg1: [endo_nbr by yy0ex0_nbr by modparam_nbr] in DR order +% Parameter Jacobian of first derivative (wrt dynamic model variables) of dynamic model (wrt to model parameters only) +% dg2: [endo_nbr by yy0ex0_nbr^2*modparam_nbr] in DR order +% Parameter Jacobian of second derivative (wrt dynamic model variables) of dynamic model (wrt to model parameters only) +% Note that instead of tensors we use matrix notation with blocks: dg2 = [dg2_dp1 dg2_dp2 ...], +% where dg2_dpj is [endo_nbr by yy0ex0_nbr^2] and represents the derivative of g2 wrt parameter pj +% dg3: [endo_nbr by yy0ex0_nbr^3*modparam_nbr] in DR order +% Parameter Jacobian of third derivative (wrt dynamic model variables) of dynamic model (wrt to model parameters only) +% Note that instead of tensors we use matrix notation with blocks: dg3 = [dg3_dp1 dg3_dp2 ...], +% where dg3_dpj is [endo_nbr by yy0ex0_nbr^3] and represents the derivative of g3 wrt parameter pj +% dghx: [endo_nbr by nspred by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of first-order perturbation solution matrix ghx +% dghu: [endo_nbr by exo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of first-order perturbation solution matrix ghu +% dOm: [endo_nbr by endo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all paramters) of Om = ghu*Sigma_e*transpose(ghu) +% dghxx [endo_nbr by nspred*nspred by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of second-order perturbation solution matrix ghxx +% dghxu [endo_nbr by nspred*exo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of second-order perturbation solution matrix ghxu +% dghuu [endo_nbr by exo_nbr*exo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of second-order perturbation solution matrix ghuu +% dghs2 [endo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of second-order perturbation solution matrix ghs2 +% dghxxx [endo_nbr by nspred*nspred*nspred by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of third-order perturbation solution matrix ghxxx +% dghxxu [endo_nbr by nspred*nspred*exo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of third-order perturbation solution matrix ghxxu +% dghxuu [endo_nbr by nspred*exo_nbr*exo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of third-order perturbation solution matrix ghxuu +% dghuuu [endo_nbr by exo_nbr*exo_nbr*exo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of third-order perturbation solution matrix ghuuu +% dghxss [endo_nbr by nspred by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of third-order perturbation solution matrix ghxss +% dghuss [endo_nbr by exo_nbr by totparam_nbr] in DR order +% Jacobian (wrt to all parameters) of third-order perturbation solution matrix ghuss +% if d2flag==true, we additional output: +% d2KalmanA: [endo_nbr*endo_nbr by totparam_nbr*(totparam_nbr+1)/2] in DR order +% Unique entries of Hessian (wrt all parameters) of Kalman transition matrix A +% d2Om: [endo_nbr*(endo_nbr+1)/2 by totparam_nbr*(totparam_nbr+1)/2] in DR order +% Unique entries of Hessian (wrt all parameters) of Om=ghu*Sigma_e*transpose(ghu) +% d2Yss: [endo_nbr by modparam_nbr by modparam_nbr] in DR order +% Unique entries of Hessian (wrt model parameters only) of steady state ys(order_var,:) +% +% ------------------------------------------------------------------------- +% This function is called by +% * dsge_likelihood.m +% * get_identification_jacobians.m +% ------------------------------------------------------------------------- +% This function calls +% * [fname,'.dynamic'] +% * [fname,'.dynamic_params_derivs'] +% * [fname,'.static'] +% * [fname,'.static_params_derivs'] +% * commutation +% * dyn_vech +% * dyn_unvech +% * fjaco +% * get_2nd_deriv (embedded) +% * get_2nd_deriv_mat(embedded) +% * get_all_parameters +% * get_all_resid_2nd_derivs (embedded) +% * get_hess_deriv (embedded) +% * hessian_sparse +% * sylvester3 +% * sylvester3a +% * get_perturbation_params_derivs_numerical_objective +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= +% Get fields from M +Correlation_matrix = M.Correlation_matrix; +dname = M.dname; +dynamic_tmp_nbr = M.dynamic_tmp_nbr; +endo_nbr = M.endo_nbr; +exo_nbr = M.exo_nbr; +exo_det_nbr = M.exo_det_nbr; +fname = M.fname; +lead_lag_incidence = M.lead_lag_incidence; +nfwrd = M.nfwrd; +npred = M.npred; +nspred = M.nspred; +nstatic = M.nstatic; +params = M.params; +param_nbr = M.param_nbr; +Sigma_e = M.Sigma_e; + +% Get fields from options +analytic_derivation_mode = options.analytic_derivation_mode; + % analytic_derivation_mode: select method to compute Jacobians, default is 0 + % * 0: efficient sylvester equation method to compute analytical derivatives as in Ratto & Iskrev (2012) + % * 1: kronecker products method to compute analytical derivatives as in Iskrev (2010), only for order=1 + % * -1: numerical two-sided finite difference method to compute numerical derivatives of all output arguments using function get_perturbation_params_derivs_numerical_objective.m + % * -2: numerical two-sided finite difference method to compute numerically dYss, dg1, dg2, dg3, d2Yss and d2g1, the other output arguments are computed analytically as in kronflag=0 +gstep = options.gstep; +order = options.order; +if isempty(options.qz_criterium) + % set default value for qz_criterium: if there are no unit roots one can use 1.0 + % If they are possible, you may have have multiple unit roots and the accuracy + % decreases when computing the eigenvalues in lyapunov_symm. Hence, we normally use 1+1e-6 + options = select_qz_criterium_value(options); +end +qz_criterium = options.qz_criterium; +threads_BC = options.threads.kronecker.sparse_hessian_times_B_kronecker_C; + +% Get fields from oo +exo_steady_state = oo.exo_steady_state; +ghx = oo.dr.ghx; +ghu = oo.dr.ghu; +if order > 1 + ghxx = oo.dr.ghxx; + ghxu = oo.dr.ghxu; + ghuu = oo.dr.ghuu; + ghs2 = oo.dr.ghs2; +end +if order > 2 + ghxxx = oo.dr.ghxxx; + ghxxu = oo.dr.ghxxu; + ghxuu = oo.dr.ghxuu; + ghuuu = oo.dr.ghuuu; + ghxss = oo.dr.ghxss; + ghuss = oo.dr.ghuss; +end +order_var = oo.dr.order_var; +ys = oo.dr.ys; + +% Some checks +if exo_det_nbr > 0 + error('''get_perturbation_params_derivs'': not compatible with deterministic exogenous variables, please declare as endogenous.') +end +if order > 1 && analytic_derivation_mode == 1 + %analytic derivatives using Kronecker products is implemented only at first-order, at higher order we reset to analytic derivatives with sylvester equations + %options.analytic_derivation_mode = 0; fprintf('As order > 1, reset ''analytic_derivation_mode'' to 0\n'); + analytic_derivation_mode = 0; fprintf('As order > 1, reset ''analytic_derivation_mode'' to 0\n'); +end + +numerical_objective_fname = str2func('get_perturbation_params_derivs_numerical_objective'); +idx_states = nstatic+(1:nspred); %index for state variables, in DR order +modparam_nbr = length(indpmodel); %number of selected model parameters +stderrparam_nbr = length(indpstderr); %number of selected stderr parameters +corrparam_nbr = size(indpcorr,1); %number of selected corr parameters +totparam_nbr = modparam_nbr + stderrparam_nbr + corrparam_nbr; %total number of selected parameters +[I,~] = find(lead_lag_incidence'); %I is used to select nonzero columns of the Jacobian of endogenous variables in dynamic model files +yy0_nbr = length(ys(I)); %number of dynamic variables +yy0ex0_nbr = yy0_nbr+exo_nbr; %number of dynamic variables + exogenous variables +kyy0 = nonzeros(lead_lag_incidence(:,order_var)'); %index for nonzero entries in dynamic files at t-1,t,t+1 in DR order +kyy0ex0 = [kyy0; length(kyy0)+(1:exo_nbr)']; %dynamic files include derivatives wrt exogenous variables, note that exo_det is always 0 +if order > 1 + k2yy0ex0 = transpose(reshape(1:yy0ex0_nbr^2,yy0ex0_nbr,yy0ex0_nbr)); %index for the second dynamic derivatives, i.e. to evaluate the derivative of f wrt to yy0ex0(i) and yy0ex0(j), in DR order +end +if order > 2 + k3yy0ex0 = permute(reshape(transpose(reshape(1:yy0ex0_nbr^3,yy0ex0_nbr,yy0ex0_nbr^2)),yy0ex0_nbr,yy0ex0_nbr,yy0ex0_nbr),[2 1 3]); %index for the third dynamic derivative, i.e. df/(dyyex0_i*dyyex0_j*dyyex0_k) +end + +% Check for purely backward or forward looking models +if size(lead_lag_incidence,1)<3 + if nfwrd == 0 %purely backward models + klag = lead_lag_incidence(1,order_var); %indices of lagged (i.e. t-1) variables in dynamic files, columns are in DR order + kcurr = lead_lag_incidence(2,order_var); %indices of current (i.e. t) variables in dynamic files, columns are in DR order + klead = zeros(1,size(lead_lag_incidence,2)); %indices of lead (i.e. t+1) variables in dynamic files, columns are in DR order + elseif npred == 0 %purely forward models + klag = zeros(1,size(lead_lag_incidence,2)); %indices of lagged (i.e. t-1) variables in dynamic files, columns are in DR order + kcurr = lead_lag_incidence(1,order_var); %indices of current (i.e. t) variables in dynamic files, columns are in DR order + klead = lead_lag_incidence(2,order_var); %indices of lead (i.e. t+1) variables in dynamic files, columns are in DR order + end +else %normal models + klag = lead_lag_incidence(1,order_var); %indices of lagged (i.e. t-1) variables in dynamic files, columns are in DR order + kcurr = lead_lag_incidence(2,order_var); %indices of current (i.e. t) variables in dynamic files, columns are in DR order + klead = lead_lag_incidence(3,order_var); %indices of lead (i.e. t+1) variables in dynamic files, columns are in DR order +end + +if analytic_derivation_mode < 0 + %Create auxiliary estim_params blocks if not available for numerical derivatives, estim_params_model contains only model parameters + estim_params_model.np = length(indpmodel); + estim_params_model.param_vals(:,1) = indpmodel; + estim_params_model.nvx = 0; estim_params_model.ncx = 0; estim_params_model.nvn = 0; estim_params_model.ncn = 0; + modparam1 = get_all_parameters(estim_params_model, M); %get all selected model parameters + if ~isempty(indpstderr) && isempty(estim_params.var_exo) %if there are stderr parameters but no estimated_params_block + %provide temporary necessary information for stderr parameters + estim_params.nvx = length(indpstderr); + estim_params.var_exo(:,1) = indpstderr; + end + if ~isempty(indpcorr) && isempty(estim_params.corrx) %if there are corr parameters but no estimated_params_block + %provide temporary necessary information for stderr parameters + estim_params.ncx = size(indpcorr,1); + estim_params.corrx(:,1:2) = indpcorr; + end + if ~isfield(estim_params,'nvn') %stderr of measurement errors not yet + estim_params.nvn = 0; + estim_params.var_endo = []; + end + if ~isfield(estim_params,'ncn') %corr of measurement errors not yet + estim_params.ncn = 0; + estim_params.corrn = []; + end + if ~isempty(indpmodel) && isempty(estim_params.param_vals) %if there are model parameters but no estimated_params_block + %provide temporary necessary information for model parameters + estim_params.np = length(indpmodel); + estim_params.param_vals(:,1) = indpmodel; + end + xparam1 = get_all_parameters(estim_params, M); %get all selected stderr, corr, and model parameters in estimated_params block, stderr and corr come first, then model parameters +end +if d2flag + modparam_nbr2 = modparam_nbr*(modparam_nbr+1)/2; %number of unique entries of selected model parameters only in second-order derivative matrix + totparam_nbr2 = totparam_nbr*(totparam_nbr+1)/2; %number of unique entries of all selected parameters in second-order derivative matrix + %get indices of elements in second derivatives of parameters + indp2tottot = reshape(1:totparam_nbr^2,totparam_nbr,totparam_nbr); + indp2stderrstderr = indp2tottot(1:stderrparam_nbr , 1:stderrparam_nbr); + indp2stderrcorr = indp2tottot(1:stderrparam_nbr , stderrparam_nbr+1:stderrparam_nbr+corrparam_nbr); + indp2modmod = indp2tottot(stderrparam_nbr+corrparam_nbr+1:stderrparam_nbr+corrparam_nbr+modparam_nbr , stderrparam_nbr+corrparam_nbr+1:stderrparam_nbr+corrparam_nbr+modparam_nbr); + if totparam_nbr ~=1 + indp2tottot2 = dyn_vech(indp2tottot); %index of unique second-order derivatives + else + indp2tottot2 = indp2tottot; + end + if modparam_nbr ~= 1 + indp2modmod2 = dyn_vech(indp2modmod); %get rid of cross derivatives + else + indp2modmod2 = indp2modmod; + end + %Kalman transition matrices, as in kalman_transition_matrix.m + KalmanA = zeros(endo_nbr,endo_nbr); + KalmanA(:,idx_states) = ghx; + KalmanB = ghu; +end + +% Store some objects +DERIVS.indpmodel = indpmodel; +DERIVS.indpstderr = indpstderr; +DERIVS.indpcorr = indpcorr; + +if analytic_derivation_mode == -1 +%% numerical two-sided finite difference method using function get_perturbation_params_derivs_numerical_objective.m (previously thet2tau.m in Dynare 4.5) for +% Jacobian (wrt selected stderr, corr and model parameters) of +% - dynamic model derivatives: dg1, dg2, dg3 +% - steady state (in DR order): dYss +% - covariance matrix of shocks: dSigma_e +% - perturbation solution matrices: dghx, dghu, dghxx, dghxu, dghuu, dghs2, dghxxx, dghxxu, dghxuu, dghuuu, dghxss, dghuss + + %Parameter Jacobian of covariance matrix and solution matrices (wrt selected stderr, corr and model paramters) + dSig_gh = fjaco(numerical_objective_fname, xparam1, 'perturbation_solution', estim_params, M, oo, options); + ind_Sigma_e = (1:exo_nbr^2); + ind_ghx = ind_Sigma_e(end) + (1:endo_nbr*nspred); + ind_ghu = ind_ghx(end) + (1:endo_nbr*exo_nbr); + DERIVS.dSigma_e = reshape(dSig_gh(ind_Sigma_e,:),[exo_nbr exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghx = reshape(dSig_gh(ind_ghx,:),[endo_nbr nspred totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghu = reshape(dSig_gh(ind_ghu,:),[endo_nbr exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters + if order > 1 + ind_ghxx = ind_ghu(end) + (1:endo_nbr*nspred^2); + ind_ghxu = ind_ghxx(end) + (1:endo_nbr*nspred*exo_nbr); + ind_ghuu = ind_ghxu(end) + (1:endo_nbr*exo_nbr*exo_nbr); + ind_ghs2 = ind_ghuu(end) + (1:endo_nbr); + DERIVS.dghxx = reshape(dSig_gh(ind_ghxx,:), [endo_nbr nspred^2 totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghxu = reshape(dSig_gh(ind_ghxu,:), [endo_nbr nspred*exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghuu = reshape(dSig_gh(ind_ghuu,:), [endo_nbr exo_nbr*exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghs2 = reshape(dSig_gh(ind_ghs2,:), [endo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters + end + if order > 2 + ind_ghxxx = ind_ghs2(end) + (1:endo_nbr*nspred^3); + ind_ghxxu = ind_ghxxx(end) + (1:endo_nbr*nspred^2*exo_nbr); + ind_ghxuu = ind_ghxxu(end) + (1:endo_nbr*nspred*exo_nbr^2); + ind_ghuuu = ind_ghxuu(end) + (1:endo_nbr*exo_nbr^3); + ind_ghxss = ind_ghuuu(end) + (1:endo_nbr*nspred); + ind_ghuss = ind_ghxss(end) + (1:endo_nbr*exo_nbr); + DERIVS.dghxxx = reshape(dSig_gh(ind_ghxxx,:), [endo_nbr nspred^3 totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghxxu = reshape(dSig_gh(ind_ghxxu,:), [endo_nbr nspred^2*exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghxuu = reshape(dSig_gh(ind_ghxuu,:), [endo_nbr nspred*exo_nbr^2 totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghuuu = reshape(dSig_gh(ind_ghuuu,:), [endo_nbr exo_nbr^3 totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghxss = reshape(dSig_gh(ind_ghxss,:), [endo_nbr nspred totparam_nbr]); %in tensor notation, wrt selected parameters + DERIVS.dghuss = reshape(dSig_gh(ind_ghuss,:), [endo_nbr exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters + end + % Parameter Jacobian of Om=ghu*Sigma_e*ghu' and Correlation_matrix (wrt selected stderr, corr and model paramters) + DERIVS.dOm = zeros(endo_nbr,endo_nbr,totparam_nbr); %initialize in tensor notation + DERIVS.dCorrelation_matrix = zeros(exo_nbr,exo_nbr,totparam_nbr); %initialize in tensor notation + if ~isempty(indpstderr) %derivatives of ghu wrt stderr parameters are zero by construction + for jp=1:stderrparam_nbr + DERIVS.dOm(:,:,jp) = ghu*DERIVS.dSigma_e(:,:,jp)*ghu'; + end + end + if ~isempty(indpcorr) %derivatives of ghu wrt corr parameters are zero by construction + for jp=1:corrparam_nbr + DERIVS.dOm(:,:,stderrparam_nbr+jp) = ghu*DERIVS.dSigma_e(:,:,stderrparam_nbr+jp)*ghu'; + DERIVS.dCorrelation_matrix(indpcorr(jp,1),indpcorr(jp,2),stderrparam_nbr+jp) = 1; + DERIVS.dCorrelation_matrix(indpcorr(jp,2),indpcorr(jp,1),stderrparam_nbr+jp) = 1;%symmetry + end + end + if ~isempty(indpmodel) %derivatives of Sigma_e wrt model parameters are zero by construction + for jp=1:modparam_nbr + DERIVS.dOm(:,:,stderrparam_nbr+corrparam_nbr+jp) = DERIVS.dghu(:,:,stderrparam_nbr+corrparam_nbr+jp)*Sigma_e*ghu' + ghu*Sigma_e*DERIVS.dghu(:,:,stderrparam_nbr+corrparam_nbr+jp)'; + end + end + + %Parameter Jacobian of dynamic model derivatives (wrt selected model parameters only) + dYss_g = fjaco(numerical_objective_fname, modparam1, 'dynamic_model', estim_params_model, M, oo, options); + ind_Yss = 1:endo_nbr; + ind_g1 = ind_Yss(end) + (1:endo_nbr*yy0ex0_nbr); + DERIVS.dYss = dYss_g(ind_Yss, :); %in tensor notation, wrt selected model parameters only + DERIVS.dg1 = reshape(dYss_g(ind_g1,:),[endo_nbr, yy0ex0_nbr, modparam_nbr]); %in tensor notation, wrt selected model parameters only + if order > 1 + ind_g2 = ind_g1(end) + (1:endo_nbr*yy0ex0_nbr^2); + DERIVS.dg2 = reshape(sparse(dYss_g(ind_g2,:)),[endo_nbr, yy0ex0_nbr^2*modparam_nbr]); %blockwise in matrix notation, i.e. [dg2_dp1 dg2_dp2 ...], where dg2_dpj has dimension endo_nbr by yy0ex0_nbr^2 + end + if order > 2 + ind_g3 = ind_g2(end) + (1:endo_nbr*yy0ex0_nbr^3); + DERIVS.dg3 = reshape(sparse(dYss_g(ind_g3,:)),[endo_nbr, yy0ex0_nbr^3*modparam_nbr]); %blockwise in matrix notation, i.e. [dg3_dp1 dg3_dp2 ...], where dg3_dpj has dimension endo_nbr by yy0ex0_nbr^3 + end + + if d2flag + % Hessian (wrt paramters) of steady state and first-order solution matrices ghx and Om + % note that hessian_sparse.m (contrary to hessian.m) does not take symmetry into account, but focuses already on unique values + options.order = 1; %make sure only first order + d2Yss_KalmanA_Om = hessian_sparse(numerical_objective_fname, xparam1, gstep, 'Kalman_Transition', estim_params, M, oo, options); + options.order = order; %make sure to set back + ind_KalmanA = ind_Yss(end) + (1:endo_nbr^2); + DERIVS.d2KalmanA = d2Yss_KalmanA_Om(ind_KalmanA, indp2tottot2); %only unique elements + DERIVS.d2Om = d2Yss_KalmanA_Om(ind_KalmanA(end)+1:end , indp2tottot2); %only unique elements + DERIVS.d2Yss = zeros(endo_nbr,modparam_nbr,modparam_nbr); %initialize + for j = 1:endo_nbr + DERIVS.d2Yss(j,:,:) = dyn_unvech(full(d2Yss_KalmanA_Om(j,indp2modmod2))); %Hessian for d2Yss, but without cross derivatives + end + end + + return %[END OF MAIN FUNCTION]!!!!! +end + +if analytic_derivation_mode == -2 +%% Numerical two-sided finite difference method to compute parameter derivatives of steady state and dynamic model, +% i.e. dYss, dg1, dg2, dg3 as well as d2Yss, d2g1 numerically. +% The parameter derivatives of perturbation solution matrices are computed analytically below (analytic_derivation_mode=0) + if order == 3 + [~, g1, g2, g3] = feval([fname,'.dynamic'], ys(I), exo_steady_state', params, ys, 1); + g3 = unfold_g3(g3, yy0ex0_nbr); + elseif order == 2 + [~, g1, g2] = feval([fname,'.dynamic'], ys(I), exo_steady_state', params, ys, 1); + elseif order == 1 + [~, g1] = feval([fname,'.dynamic'], ys(I), exo_steady_state', params, ys, 1); + end + + if d2flag + % computation of d2Yss and d2g1 + % note that hessian_sparse does not take symmetry into account, i.e. compare hessian_sparse.m to hessian.m, but focuses already on unique values, which are duplicated below + options.order = 1; %d2flag requires only first order + d2Yss_g1 = hessian_sparse(numerical_objective_fname, modparam1, gstep, 'dynamic_model', estim_params_model, M, oo, options); % d2flag requires only first-order + options.order = order; %make sure to set back the order + d2Yss = reshape(full(d2Yss_g1(1:endo_nbr,:)), [endo_nbr modparam_nbr modparam_nbr]); %put into tensor notation + for j=1:endo_nbr + d2Yss(j,:,:) = dyn_unvech(dyn_vech(d2Yss(j,:,:))); %add duplicate values to full hessian + end + d2g1_full = d2Yss_g1(endo_nbr+1:end,:); + %store only nonzero unique entries and the corresponding indices of d2g1: + % rows: respective derivative term + % 1st column: equation number of the term appearing + % 2nd column: column number of variable in Jacobian of the dynamic model + % 3rd column: number of the first parameter in derivative + % 4th column: number of the second parameter in derivative + % 5th column: value of the Hessian term + ind_d2g1 = find(d2g1_full); + d2g1 = zeros(length(ind_d2g1),5); + for j=1:length(ind_d2g1) + [i1, i2] = ind2sub(size(d2g1_full),ind_d2g1(j)); + [ig1, ig2] = ind2sub(size(g1),i1); + [ip1, ip2] = ind2sub([modparam_nbr modparam_nbr],i2); + d2g1(j,:) = [ig1 ig2 ip1 ip2 d2g1_full(ind_d2g1(j))]; + end + clear d2g1_full d2Yss_g1; + end + + %Parameter Jacobian of dynamic model derivatives (wrt selected model parameters only) + dYss_g = fjaco(numerical_objective_fname, modparam1, 'dynamic_model', estim_params_model, M, oo, options); + ind_Yss = 1:endo_nbr; + ind_g1 = ind_Yss(end) + (1:endo_nbr*yy0ex0_nbr); + dYss = dYss_g(ind_Yss,:); %in tensor notation, wrt selected model parameters only + dg1 = reshape(dYss_g(ind_g1,:),[endo_nbr,yy0ex0_nbr,modparam_nbr]); %in tensor notation + if order > 1 + ind_g2 = ind_g1(end) + (1:endo_nbr*yy0ex0_nbr^2); + dg2 = reshape(sparse(dYss_g(ind_g2,:)),[endo_nbr, yy0ex0_nbr^2*modparam_nbr]); %blockwise in matrix notation, i.e. [dg2_dp1 dg2_dp2 ...], where dg2_dpj has dimension endo_nbr by yy0ex0_nbr^2 + end + if order > 2 + ind_g3 = ind_g2(end) + (1:endo_nbr*yy0ex0_nbr^3); + dg3 = reshape(sparse(dYss_g(ind_g3,:)), [endo_nbr, yy0ex0_nbr^3*modparam_nbr]); %blockwise in matrix notation, i.e. [dg3_dp1 dg3_dp2 ...], where dg3_dpj has dimension endo_nbr by yy0ex0_nbr^3 + end + clear dYss_g + +elseif (analytic_derivation_mode == 0 || analytic_derivation_mode == 1) + %% Analytical computation of Jacobian and Hessian (wrt selected model parameters) of steady state, i.e. dYss and d2Yss + [~, g1_static] = feval([fname,'.static'], ys, exo_steady_state', params); %g1_static is [endo_nbr by endo_nbr] first-derivative (wrt all endogenous variables) of static model equations f, i.e. df/dys, in declaration order + try + rp_static = feval([fname,'.static_params_derivs'], ys, exo_steady_state', params); %rp_static is [endo_nbr by param_nbr] first-derivative (wrt all model parameters) of static model equations f, i.e. df/dparams, in declaration order + catch + error('For analytical parameter derivatives ''static_params_derivs.m'' file is needed, this can be created by putting identification(order=%d) into your mod file.',order) + end + dys = -g1_static\rp_static; %use implicit function theorem (equation 5 of Ratto and Iskrev (2012) to compute [endo_nbr by param_nbr] first-derivative (wrt all model parameters) of steady state for all endogenous variables analytically, note that dys is in declaration order + d2ys = zeros(endo_nbr, param_nbr, param_nbr); %initialize in tensor notation, note that d2ys is only needed for d2flag, i.e. for g1pp + if d2flag + [~, ~, g2_static] = feval([fname,'.static'], ys, exo_steady_state', params); %g2_static is [endo_nbr by endo_nbr^2] second derivative (wrt all endogenous variables) of static model equations f, i.e. d(df/dys)/dys, in declaration order + if order < 3 + [~, g1, g2, g3] = feval([fname,'.dynamic'], ys(I), exo_steady_state', params, ys, 1); %note that g3 does not contain symmetric elements + g3 = unfold_g3(g3, yy0ex0_nbr); %add symmetric elements to g3 + else + T = NaN(sum(dynamic_tmp_nbr(1:5))); + T = feval([fname, '.dynamic_g4_tt'], T, ys(I), exo_steady_state', params, ys, 1); + g1 = feval([fname, '.dynamic_g1'], T, ys(I), exo_steady_state', params, ys, 1, false); %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + g2 = feval([fname, '.dynamic_g2'], T, ys(I), exo_steady_state', params, ys, 1, false); %g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + g3 = feval([fname, '.dynamic_g3'], T, ys(I), exo_steady_state', params, ys, 1, false); %note that g3 does not contain symmetric elements + g4 = feval([fname, '.dynamic_g4'], T, ys(I), exo_steady_state', params, ys, 1, false); %note that g4 does not contain symmetric elements + g3 = unfold_g3(g3, yy0ex0_nbr); %add symmetric elements to g3, %g3 is [endo_nbr by yy0ex0_nbr^3] third-derivative (wrt all dynamic variables) of dynamic model equations, i.e. (d(df/dyy0ex0)/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + g4 = unfold_g4(g4, yy0ex0_nbr); %add symmetric elements to g4, %g4 is [endo_nbr by yy0ex0_nbr^4] fourth-derivative (wrt all dynamic variables) of dynamic model equations, i.e. ((d(df/dyy0ex0)/dyy0ex0)/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + end + %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + %g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + %g3 is [endo_nbr by yy0ex0_nbr^3] third-derivative (wrt all dynamic variables) of dynamic model equations, i.e. (d(df/dyy0ex0)/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + try + [~, g1p_static, rpp_static] = feval([fname,'.static_params_derivs'], ys, exo_steady_state', params); + %g1p_static is [endo_nbr by endo_nbr by param_nbr] first derivative (wrt all model parameters) of first-derivative (wrt all endogenous variables) of static model equations f, i.e. (df/dys)/dparams, in declaration order + %rpp_static is [#second_order_residual_terms by 4] and contains nonzero values and corresponding indices of second derivatives (wrt all model parameters) of static model equations f, i.e. d(df/dparams)/dparams, in declaration order, where + % column 1 contains equation number; column 2 contains first parameter; column 3 contains second parameter; column 4 contains value of derivative + catch + error('For analytical parameter derivatives ''static_params_derivs.m'' file is needed, this can be created by putting identification(order=%d) into your mod file.',order) + end + rpp_static = get_all_resid_2nd_derivs(rpp_static, endo_nbr, param_nbr); %make full matrix out of nonzero values and corresponding indices + %rpp_static is [endo_nbr by param_nbr by param_nbr] second derivatives (wrt all model parameters) of static model equations, i.e. d(df/dparams)/dparams, in declaration order + if isempty(find(g2_static)) + %auxiliary expression on page 8 of Ratto and Iskrev (2012) is zero, i.e. gam = 0 + for j = 1:param_nbr + %using the implicit function theorem, equation 15 on page 7 of Ratto and Iskrev (2012) + d2ys(:,:,j) = -g1_static\rpp_static(:,:,j); + %d2ys is [endo_nbr by param_nbr by param_nbr] second-derivative (wrt all model parameters) of steady state of all endogenous variables, i.e. d(dys/dparams)/dparams, in declaration order + end + else + gam = zeros(endo_nbr,param_nbr,param_nbr); %initialize auxiliary expression on page 8 of Ratto and Iskrev (2012) + for j = 1:endo_nbr + tmp_g1p_static_dys = (squeeze(g1p_static(j,:,:))'*dys); + gam(j,:,:) = transpose(reshape(g2_static(j,:),[endo_nbr endo_nbr])*dys)*dys + tmp_g1p_static_dys + tmp_g1p_static_dys'; + end + for j = 1:param_nbr + %using the implicit function theorem, equation 15 on page 7 of Ratto and Iskrev (2012) + d2ys(:,:,j) = -g1_static\(rpp_static(:,:,j)+gam(:,:,j)); + %d2ys is [endo_nbr by param_nbr by param_nbr] second-derivative (wrt all model parameters) of steady state of all endogenous variables, i.e. d(dys/dparams)/dparams, in declaration order + end + clear g1p_static g2_static tmp_g1p_static_dys gam + end + end + %handling of steady state for nonstationary variables + if any(any(isnan(dys))) + [U,T] = schur(g1_static); + e1 = abs(ordeig(T)) < qz_criterium-1; + k = sum(e1); % Number of non stationary variables. + % Number of stationary variables: n = length(e1)-k + [U,T] = ordschur(U,T,e1); + T = T(k+1:end,k+1:end); + %using implicit function theorem, equation 5 of Ratto and Iskrev (2012), in declaration order + dys = -U(:,k+1:end)*(T\U(:,k+1:end)')*rp_static; + if d2flag + fprintf('Computation of d2ys for nonstationary variables is not yet correctly handled if g2_static is nonempty, but continue anyways...\n') + for j = 1:param_nbr + %using implicit function theorem, equation 15 of Ratto and Iskrev (2012), in declaration order + d2ys(:,:,j) = -U(:,k+1:end)*(T\U(:,k+1:end)')*rpp_static(:,:,j); %THIS IS NOT CORRECT, IF g2_static IS NONEMPTY. WE NEED TO ADD GAM [willi] + end + end + end + + if d2flag + try + if order < 3 + [~, g1p, ~, g1pp, g2p] = feval([fname,'.dynamic_params_derivs'], ys(I), exo_steady_state', params, ys, 1, dys, d2ys); + else + [~, g1p, ~, g1pp, g2p, g3p] = feval([fname,'.dynamic_params_derivs'], ys(I), exo_steady_state', params, ys, 1, dys, d2ys); + end + catch + error('For analytical parameter derivatives ''dynamic_params_derivs.m'' file is needed, this can be created by putting identification(order=%d) into your mod file.',order) + end + %g1pp are nonzero values and corresponding indices of second-derivatives (wrt all model parameters) of first-derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(d(df/dyy0ex0)/dparam)/dparam, rows are in declaration order, first column in declaration order + d2Yss = d2ys(order_var,indpmodel,indpmodel); %[endo_nbr by mod_param_nbr by mod_param_nbr], put into DR order and focus only on selected model parameters + else + if order == 1 + try + [~, g1p] = feval([fname,'.dynamic_params_derivs'], ys(I), exo_steady_state', params, ys, 1, dys, d2ys); + %g1p is [endo_nbr by yy0ex0_nbr by param_nbr] first-derivative (wrt all model parameters) of first-derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dparam, rows are in declaration order, column in lead_lag_incidence order + catch + error('For analytical parameter derivatives ''dynamic_params_derivs.m'' file is needed, this can be created by putting identification(order=%d) into your mod file.',order) + end + [~, g1, g2 ] = feval([fname,'.dynamic'], ys(I), exo_steady_state', params, ys, 1); + %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + %g2 is [endo_nbr by yy0ex0_nbr^2] second derivatives (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + elseif order == 2 + try + [~, g1p, ~, ~, g2p] = feval([fname,'.dynamic_params_derivs'], ys(I), exo_steady_state', params, ys, 1, dys, d2ys); + %g1p is [endo_nbr by yy0ex0_nbr by param_nbr] first-derivative (wrt all model parameters) of first-derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dparam, rows are in declaration order, column in lead_lag_incidence order + %g2p are nonzero values and corresponding indices of first-derivative (wrt all model parameters) of second-derivatives (wrt all dynamic variables) of dynamic model equations, i.e. d(d(df/dyy0ex0)/dyy0ex0)/dparam, rows are in declaration order, first and second column in declaration order + catch + error('For analytical parameter derivatives ''dynamic_params_derivs.m'' file is needed, this can be created by putting identification(order=%d) into your mod file.',order) + end + [~, g1, g2, g3] = feval([fname,'.dynamic'], ys(I), exo_steady_state', params, ys, 1); %note that g3 does not contain symmetric elements + g3 = unfold_g3(g3, yy0ex0_nbr); %add symmetric elements to g3 + %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + %g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + %g3 is [endo_nbr by yy0ex0_nbr^3] third-derivative (wrt all dynamic variables) of dynamic model equations, i.e. (d(df/dyy0ex0)/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + elseif order == 3 + try + [~, g1p, ~, ~, g2p, g3p] = feval([fname,'.dynamic_params_derivs'], ys(I), exo_steady_state', params, ys, 1, dys, d2ys); + %g1p is [endo_nbr by yy0ex0_nbr by param_nbr] first-derivative (wrt all model parameters) of first-derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dparam, rows are in declaration order, column in lead_lag_incidence order + %g2p are nonzero values and corresponding indices of first-derivative (wrt all model parameters) of second-derivatives (wrt all dynamic variables) of dynamic model equations, i.e. d(d(df/dyy0ex0)/dyy0ex0)/dparam, rows are in declaration order, first and second column in declaration order + %g3p are nonzero values and corresponding indices of first-derivative (wrt all model parameters) of third-derivatives (wrt all dynamic variables) of dynamic model equations, i.e. d(d(d(df/dyy0ex0)/dyy0ex0)/dyy0ex0)/dparam, rows are in declaration order, first, second and third column in declaration order + catch + error('For analytical parameter derivatives ''dynamic_params_derivs.m'' file is needed, this can be created by putting identification(order=%d) into your mod file.',order) + end + T = NaN(sum(dynamic_tmp_nbr(1:5))); + T = feval([fname, '.dynamic_g4_tt'], T, ys(I), exo_steady_state', params, ys, 1); + g1 = feval([fname, '.dynamic_g1'], T, ys(I), exo_steady_state', params, ys, 1, false); %g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + g2 = feval([fname, '.dynamic_g2'], T, ys(I), exo_steady_state', params, ys, 1, false); %g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + g3 = feval([fname, '.dynamic_g3'], T, ys(I), exo_steady_state', params, ys, 1, false); %note that g3 does not contain symmetric elements + g4 = feval([fname, '.dynamic_g4'], T, ys(I), exo_steady_state', params, ys, 1, false); %note that g4 does not contain symmetric elements + g3 = unfold_g3(g3, yy0ex0_nbr); %add symmetric elements to g3, %g3 is [endo_nbr by yy0ex0_nbr^3] third-derivative (wrt all dynamic variables) of dynamic model equations, i.e. (d(df/dyy0ex0)/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + g4 = unfold_g4(g4, yy0ex0_nbr); %add symmetric elements to g4, %g4 is [endo_nbr by yy0ex0_nbr^4] fourth-derivative (wrt all dynamic variables) of dynamic model equations, i.e. ((d(df/dyy0ex0)/dyy0ex0)/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order + end + end + % Parameter Jacobian of steady state in different orderings, note dys is in declaration order + dYss = dys(order_var, indpmodel); %in DR-order, focus only on selected model parameters + dyy0 = dys(I,:); %in lead_lag_incidence order, Jacobian of dynamic (without exogenous) variables, focus on all model parameters + dyy0ex0 = sparse([dyy0; zeros(exo_nbr,param_nbr)]); %in lead_lag_incidence order, Jacobian of dynamic (with exogenous) variables, focus on all model parameters + + %% Analytical computation of Jacobian (wrt selected model parameters) of first-derivative of dynamic model, i.e. dg1 + % Note that we use the implicit function theorem (see Ratto and Iskrev (2012) formula 7): + % Let g1 = df/dyy0ex0 be the first derivative (wrt all dynamic variables) of the dynamic model, then + % dg1 denotes the first-derivative (wrt model parameters) of g1 evaluated at the steady state. + % Note that g1 is a function of both the model parameters p and of the steady state of all dynamic variables, which also depend on the model parameters. + % Hence, implicitly g1=g1(p,yy0ex0(p)) and dg1 consists of two parts: + % (1) g1p: direct derivative (wrt to all model parameters) given by the preprocessor + % (2) g2*dyy0ex0: contribution of derivative of steady state of dynamic variables (wrt all model parameters) + % Note that in a stochastic context ex0 and dex0 is always zero and hence can be skipped in the computations + dg1 = zeros(endo_nbr,yy0ex0_nbr,param_nbr); %initialize part (2) + for j = 1:endo_nbr + [II, JJ] = ind2sub([yy0ex0_nbr yy0ex0_nbr], find(g2(j,:))); %g2 is [endo_nbr by yy0ex0_nbr^2] + for i = 1:yy0ex0_nbr + is = find(II==i); + is = is(find(JJ(is)<=yy0_nbr)); %focus only on oo.dr.ys(I) derivatives as exogenous variables are 0 in a stochastic context + if ~isempty(is) + tmp_g2 = full(g2(j,find(g2(j,:)))); + dg1(j,i,:) = tmp_g2(is)*dyy0(JJ(is),:); %put into tensor notation + end + end + end + dg1 = g1p + dg1; %add part (1) + dg1 = dg1(:,:,indpmodel); %focus only on selected model parameters + + if order>1 + %% Analytical computation of Jacobian (wrt selected model parameters) of second derivative of dynamic model, i.e. dg2 + % We use the implicit function theorem: + % Let g2 = d2f/(dyy0ex0*dyy0ex0) denote the second derivative (wrt all dynamic variables) of the dynamic model, then + % dg2 denotes the first-derivative (wrt all model parameters) of g2 evaluated at the steady state. + % Note that g2 is a function of both the model parameters p and of the steady state of all dynamic variables, which also depend on the parameters. + % Hence, implicitly g2=g2(p,yy0ex0(p)) and dg2 consists of two parts: + % (1) g2p: direct derivative wrt to all model parameters given by the preprocessor + % and + % (2) g3*dyy0ex0: contribution of derivative of steady state of dynamic variables (wrt all model parameters) + % Note that we focus on selected model parameters only, i.e. indpmodel + % Also note that we stack the parameter derivatives blockwise instead of in tensors + dg2 = reshape(g3,[endo_nbr*yy0ex0_nbr^2 yy0ex0_nbr])*dyy0ex0(:,indpmodel); %part (2) + dg2 = reshape(dg2, [endo_nbr, yy0ex0_nbr^2*modparam_nbr]); + for jj = 1:size(g2p,1) + jpos = find(indpmodel==g2p(jj,4)); + if jpos~=0 + dg2(g2p(jj,1), k2yy0ex0(g2p(jj,2),g2p(jj,3))+(jpos-1)*yy0ex0_nbr^2) = dg2(g2p(jj,1), k2yy0ex0(g2p(jj,2),g2p(jj,3))+(jpos-1)*yy0ex0_nbr^2) + g2p(jj,5); %add part (1) + end + end + end + + if order>2 + %% Analytical computation of Jacobian (wrt selected model parameters) of third derivative of dynamic model, i.e. dg3 + % We use the implicit function theorem: + % Let g3 = d3f/(dyy0ex0*dyy0ex0*dyy0ex0) denote the third derivative (wrt all dynamic variables) of the dynamic model, then + % dg3 denotes the first-derivative (wrt all model parameters) of g3 evaluated at the steady state. + % Note that g3 is a function of both the model parameters p and of the steady state of all dynamic variables, which also depend on the parameters. + % Hence, implicitly g3=g3(p,yy0ex0(p)) and dg3 consists of two parts: + % (1) g3p: direct derivative wrt to all model parameters given by the preprocessor + % and + % (2) g4*dyy0ex0: contribution of derivative of steady state of dynamic variables (wrt all model parameters) + % Note that we focus on selected model parameters only, i.e. indpmodel + % Also note that we stack the parameter derivatives blockwise instead of in tensors + dg3 = reshape(g4,[endo_nbr*yy0ex0_nbr^3 yy0ex0_nbr])*dyy0ex0(:,indpmodel); %part (2) + dg3 = reshape(dg3, [endo_nbr, yy0ex0_nbr^3*modparam_nbr]); + for jj = 1:size(g3p,1) + jpos = find(indpmodel==g3p(jj,5)); + if jpos~=0 + idyyy = unique(perms([g3p(jj,2) g3p(jj,3) g3p(jj,4)]),'rows'); %note that g3p does not contain symmetric terms, so we use the perms and unique functions + for k = 1:size(idyyy,1) + dg3(g3p(jj,1), k3yy0ex0(idyyy(k,1),idyyy(k,2),idyyy(k,3))+(jpos-1)*yy0ex0_nbr^3) = dg3(g3p(jj,1), k3yy0ex0(idyyy(k,1),idyyy(k,2),idyyy(k,3))+(jpos-1)*yy0ex0_nbr^3) + g3p(jj,6); %add part (1) + end + end + end + end + + if d2flag + %% Analytical computation of Hessian (wrt selected model parameters) of first-derivative of dynamic model, i.e. d2g1 + % We use the implicit function theorem (above we already computed: dg1 = g1p + g2*dyy0ex0): + % Accordingly, d2g1, the second-derivative (wrt model parameters), consists of five parts (ignoring transposes, see Ratto and Iskrev (2012) formula 16) + % (1) d(g1p)/dp = g1pp + % (2) d(g1p)/dyy0ex0*d(yy0ex0)/dp = g2p * dyy0ex0 + % (3) d(g2)/dp * dyy0ex0 = g2p * dyy0ex0 + % (4) d(g2)/dyy0ex0*d(dyy0ex0)/dp * dyy0ex0 = g3 * dyy0ex0 * dyy0ex0 + % (5) g2 * d(dyy0ex0)/dp = g2 * d2yy0ex0 + % Note that part 2 and 3 are equivalent besides the use of transpose (see Ratto and Iskrev (2012) formula 16) + d2g1_full = sparse(endo_nbr*yy0ex0_nbr, param_nbr*param_nbr); %initialize + g3_tmp = reshape(g3,[endo_nbr*yy0ex0_nbr*yy0ex0_nbr yy0ex0_nbr]); + d2g1_part4_left = sparse(endo_nbr*yy0ex0_nbr*yy0ex0_nbr,param_nbr); + for j = 1:param_nbr + %compute first two terms of part 4 + d2g1_part4_left(:,j) = g3_tmp*dyy0ex0(:,j); + end + for j=1:endo_nbr + %Note that in the following we skip exogenous variables as these are 0 by construction in a stochastic setting + d2g1_part5 = reshape(g2(j,:), [yy0ex0_nbr yy0ex0_nbr]); + d2g1_part5 = d2g1_part5(:,1:yy0_nbr)*reshape(d2ys(I,:,:),[yy0_nbr,param_nbr*param_nbr]); + for i=1:yy0ex0_nbr + ind_part4 = sub2ind([endo_nbr yy0ex0_nbr yy0ex0_nbr], ones(yy0ex0_nbr,1)*j ,ones(yy0ex0_nbr,1)*i, (1:yy0ex0_nbr)'); + d2g1_part4 = (d2g1_part4_left(ind_part4,:))'*dyy0ex0; + d2g1_part2_and_part3 = (get_hess_deriv(g2p,j,i,yy0ex0_nbr,param_nbr))'*dyy0ex0; + d2g1_part1 = get_2nd_deriv_mat(g1pp,j,i,param_nbr); + d2g1_tmp = d2g1_part1 + d2g1_part2_and_part3 + d2g1_part2_and_part3' + d2g1_part4 + reshape(d2g1_part5(i,:,:),[param_nbr param_nbr]); + d2g1_tmp = d2g1_tmp(indpmodel,indpmodel); %focus only on model parameters + if any(any(d2g1_tmp)) + ind_d2g1_tmp = find(triu(d2g1_tmp)); + d2g1_full(sub2ind([endo_nbr yy0ex0_nbr],j,i), ind_d2g1_tmp) = transpose(d2g1_tmp(ind_d2g1_tmp)); + end + end + end + clear d2g1_tmp d2g1_part1 d2g1_part2_and_part3 d2g1_part4 d2g1_part4_left d2g1_part5 + %store only nonzero entries and the corresponding indices of d2g1: + % 1st column: equation number of the term appearing + % 2nd column: column number of variable in Jacobian of the dynamic model + % 3rd column: number of the first parameter in derivative + % 4th column: number of the second parameter in derivative + % 5th column: value of the Hessian term + ind_d2g1 = find(d2g1_full); + d2g1 = zeros(length(ind_d2g1),5); + for j=1:length(ind_d2g1) + [i1, i2] = ind2sub(size(d2g1_full),ind_d2g1(j)); + [ig1, ig2] = ind2sub(size(g1),i1); + [ip1, ip2] = ind2sub([modparam_nbr modparam_nbr],i2); + d2g1(j,:) = [ig1 ig2 ip1 ip2 d2g1_full(ind_d2g1(j))]; + end + clear d2g1_full; + end +end + +%% clear variables that are not used any more +clear dys dyy0 dyy0ex0 d2ys +clear rp_static rpp_static +clear g1_static g1p_static g1p g1pp +clear g2_static g2p tmp_g2 g3_tmp +clear ind_d2g1 ind_d2g1_tmp ind_part4 i j i1 i2 ig1 ig2 I II JJ ip1 ip2 is +if order == 1 + clear g2 g3 +elseif order == 2 + clear g3 +end + +%% Construct Jacobian (wrt all selected parameters) of Sigma_e and Corr_e for Gaussian innovations +dSigma_e = zeros(exo_nbr,exo_nbr,totparam_nbr); %initialize +dCorrelation_matrix = zeros(exo_nbr,exo_nbr,totparam_nbr); %initialize +% Compute Jacobians wrt stderr parameters (these come first) +% note that derivatives wrt stderr parameters are zero by construction for Corr_e +if ~isempty(indpstderr) + for jp = 1:stderrparam_nbr + dSigma_e(indpstderr(jp),indpstderr(jp),jp) = 2*sqrt(Sigma_e(indpstderr(jp),indpstderr(jp))); + if isdiag(Sigma_e) == 0 % if there are correlated errors add cross derivatives + indotherex0 = 1:exo_nbr; + indotherex0(indpstderr(jp)) = []; + for kk = indotherex0 + dSigma_e(indpstderr(jp), kk, jp) = Correlation_matrix(indpstderr(jp),kk)*sqrt(Sigma_e(kk,kk)); + dSigma_e(kk, indpstderr(jp), jp) = dSigma_e(indpstderr(jp), kk, jp); %symmetry + end + end + end +end +% Compute Jacobians wrt corr parameters (these come second) +if ~isempty(indpcorr) + for jp = 1:corrparam_nbr + dSigma_e(indpcorr(jp,1),indpcorr(jp,2),stderrparam_nbr+jp) = sqrt(Sigma_e(indpcorr(jp,1),indpcorr(jp,1)))*sqrt(Sigma_e(indpcorr(jp,2),indpcorr(jp,2))); + dSigma_e(indpcorr(jp,2),indpcorr(jp,1),stderrparam_nbr+jp) = dSigma_e(indpcorr(jp,1),indpcorr(jp,2),stderrparam_nbr+jp); %symmetry + dCorrelation_matrix(indpcorr(jp,1),indpcorr(jp,2),stderrparam_nbr+jp) = 1; + dCorrelation_matrix(indpcorr(jp,2),indpcorr(jp,1),stderrparam_nbr+jp) = 1;%symmetry + end +end +% note that derivatives wrt model parameters (these come third) are zero by construction for Sigma_e and Corr_e + +%% Analytical computation of Jacobian (wrt selected model parameters) of first-order solution matrices ghx, ghu, and of Om=ghu*Sigma_e*ghu' +%Notation: +% fy_ = g1(:,nonzeros(klag)) in DR order +% fy0 = g1(:,nonzeros(kcurr)) in DR order +% fyp = g1(:,nonzeros(klead)) in DR order +if analytic_derivation_mode == 1 + % The following derivations are based on Iskrev (2010) and its online appendix A. + % Basic idea is to make use of the implicit function theorem. + % Define Kalman transition matrix KalmanA = [0 ghx 0], where the first zero spans nstatic columns, and the second zero nfwrd columns + % At first order we have: F = GAM0*KalmanA - GAM1*KalmanA*KalmanA - GAM2 = 0, where GAM0=fy0, GAM1=-fyp, GAM2 = -fy_ + % Note that F is a function of parameters p and KalmanA, which is also a function of p,therefore, F = F(p,KalmanA(p))=0, and hence, + % dF = Fp + dF_dKalmanA*dKalmanA = 0 or dKalmanA = - Fp/dF_dKalmanA + + % Some auxiliary matrices + I_endo = speye(endo_nbr); + KalmanA = [zeros(endo_nbr,nstatic) ghx zeros(endo_nbr,nfwrd)]; + + % Reshape to write first dynamic derivatives in the Magnus and Neudecker style, i.e. dvec(X)/dp + GAM0 = zeros(endo_nbr,endo_nbr); + GAM0(:,kcurr~=0,:) = g1(:,nonzeros(kcurr)); + dGAM0 = zeros(endo_nbr,endo_nbr,modparam_nbr); + dGAM0(:,kcurr~=0,:) = dg1(:,nonzeros(kcurr),:); + dGAM0 = reshape(dGAM0, endo_nbr*endo_nbr, modparam_nbr); + + GAM1 = zeros(endo_nbr,endo_nbr); + GAM1(:,klead~=0,:) = -g1(:,nonzeros(klead)); + dGAM1 = zeros(endo_nbr,endo_nbr,modparam_nbr); + dGAM1(:,klead~=0,:) = -dg1(:,nonzeros(klead),:); + dGAM1 = reshape(dGAM1, endo_nbr*endo_nbr, modparam_nbr); + + dGAM2 = zeros(endo_nbr,endo_nbr,modparam_nbr); + dGAM2(:,klag~=0,:) = -dg1(:,nonzeros(klag),:); + dGAM2 = reshape(dGAM2, endo_nbr*endo_nbr, modparam_nbr); + + GAM3 = -g1(:,yy0_nbr+1:end); + dGAM3 = reshape(-dg1(:,yy0_nbr+1:end,:), endo_nbr*exo_nbr, modparam_nbr); + + % Compute dKalmanA via implicit function + dF_dKalmanAghx = kron(I_endo,GAM0) - kron(KalmanA',GAM1) - kron(I_endo,GAM1*KalmanA); %equation 31 in Appendix A of Iskrev (2010) + Fp = kron(KalmanA',I_endo)*dGAM0 - kron( (KalmanA')^2,I_endo)*dGAM1 - dGAM2; %equation 32 in Appendix A of Iskrev (2010) + dKalmanA = -dF_dKalmanAghx\Fp; + + % Compute dBB from expressions 33 in Iskrev (2010) Appendix A + MM = GAM0-GAM1*KalmanA; %this corresponds to matrix M in Ratto and Iskrev (2012, page 6) + invMM = MM\eye(endo_nbr); + dghu = - kron( (invMM*GAM3)' , invMM ) * ( dGAM0 - kron( KalmanA' , I_endo ) * dGAM1 - kron( I_endo , GAM1 ) * dKalmanA ) + kron( speye(exo_nbr), invMM ) * dGAM3; + + % Add derivatives for stderr and corr parameters, which are zero by construction + dKalmanA = [zeros(endo_nbr^2, stderrparam_nbr+corrparam_nbr) dKalmanA]; + dghu = [zeros(endo_nbr*exo_nbr, stderrparam_nbr+corrparam_nbr) dghu]; + + % Compute dOm = dvec(ghu*Sigma_e*ghu') from expressions 34 in Iskrev (2010) Appendix A + dOm = kron(I_endo,ghu*Sigma_e)*(commutation(endo_nbr, exo_nbr)*dghu)... + + kron(ghu,ghu)*reshape(dSigma_e, exo_nbr^2, totparam_nbr) + kron(ghu*Sigma_e,I_endo)*dghu; + + % Put into tensor notation + dKalmanA = reshape(dKalmanA, endo_nbr, endo_nbr, totparam_nbr); + dghx = dKalmanA(:, nstatic+(1:nspred), stderrparam_nbr+corrparam_nbr+1:end); %get rid of zeros and focus on modparams only + dghu = reshape(dghu, endo_nbr, exo_nbr, totparam_nbr); + dghu = dghu(:,:,stderrparam_nbr+corrparam_nbr+1:end); %focus only on modparams + dOm = reshape(dOm, endo_nbr, endo_nbr, totparam_nbr); + clear dF_dKalmanAghx Fp dGAM0 dGAM1 dGAM2 dGAM3 MM invMM I_endo + +elseif (analytic_derivation_mode == 0 || analytic_derivation_mode == -2) + % Here we make use of more efficient generalized sylvester equations + % Notation: ghx_ = ghx(idx_states,:), ghx0 = ghx(kcurr~=0,:), ghxp = ghx(klead~=0,:) + % Note that at first-order we have the following expressions, which are (numerically) zero: + % * for ghx: g1*zx = fyp*ghxp*ghx_ + fy0*ghx0 + fy_ = A*ghx + fy_ = 0 + % Taking the differential yields a generalized sylvester equation to get dghx: A*dghx + B*dghx*ghx_ = -dg1*zx + % * for ghu: g1*zu = A*ghu + fu = 0 + % Taking the differential yields an invertible equation to get dghu: A*dghu = -(dfu + dA*ghu) + % INITIALIZATIONS + % Note that A and B are the perturbation matrices (NOT the Kalman transition matrices)! + A = zeros(endo_nbr,endo_nbr); + A(:,kcurr~=0) = g1(:,nonzeros(kcurr)); + A(:,idx_states) = A(:,idx_states) + g1(:,nonzeros(klead))*ghx(klead~=0,:); + B = zeros(endo_nbr,endo_nbr); + B(:,nstatic+npred+1:end) = g1(:,nonzeros(klead)); + zx = [eye(nspred); + ghx(kcurr~=0,:); + ghx(klead~=0,:)*ghx(idx_states,:); + zeros(exo_nbr,nspred)]; + dRHSx = zeros(endo_nbr,nspred,modparam_nbr); + for jp=1:modparam_nbr + dRHSx(:,:,jp) = -dg1(:,kyy0,jp)*zx(1:yy0_nbr,:); + end + %use iterated generalized sylvester equation to compute dghx + dghx = sylvester3(A,B,ghx(idx_states,:),dRHSx); + flag = 1; icount = 0; + while flag && icount < 4 + [dghx, flag] = sylvester3a(dghx,A,B,ghx(idx_states,:),dRHSx); + icount = icount+1; + end + + %Compute dOm, dghu, dA, dB + dOm = zeros(endo_nbr,endo_nbr,totparam_nbr); %as Om=ghu*Sigma_e*ghu', we need to use totparam_nbr, because there is also a contribution from stderr and corr parameters, which we compute after modparams + dghu = zeros(endo_nbr,exo_nbr,modparam_nbr); + dA = zeros(endo_nbr,endo_nbr,modparam_nbr); %dA is also needed at higher orders + dA(:,kcurr~=0,:) = dg1(:,nonzeros(kcurr),:); + invA = inv(A); %also needed at higher orders + for jp=1:modparam_nbr + dA(:,idx_states,jp) = dA(:,idx_states,jp) + dg1(:,nonzeros(klead),jp)*ghx(klead~=0,:) + g1(:,nonzeros(klead))*dghx(klead~=0,:,jp); + dghu(:,:,jp) = -invA*( dg1(:,yy0_nbr+1:end,jp) + dA(:,:,jp)*ghu); + dOm(:,:,stderrparam_nbr+corrparam_nbr+jp) = dghu(:,:,jp)*Sigma_e*ghu' + ghu*Sigma_e*dghu(:,:,jp)'; + end + %add stderr and corr derivatives to Om=ghu*Sigma_e*ghu' + if ~isempty(indpstderr) + for jp = 1:stderrparam_nbr + dOm(:,:,jp) = ghu*dSigma_e(:,:,jp)*ghu'; + end + end + if ~isempty(indpcorr) + for jp = 1:corrparam_nbr + dOm(:,:,stderrparam_nbr+jp) = ghu*dSigma_e(:,:,stderrparam_nbr+jp)*ghu'; + end + end +end + +%% Analytical computation of Jacobian (wrt selected model parameters) of second-order solution matrices ghxx,ghxu,ghuu and ghs2 +if order > 1 + % Notation: ghxx_ = ghxx(idx_states,:), ghxx0 = ghxx(kcurr~=0,:), ghxxp = ghxx(klead~=0,:) + % and similar for ghxu, ghuu and ghs2 + % Note that at second-order we have the following expressions, which are (numerically) zero: + % * for ghxx: A*ghxx + B*ghxx*kron(ghx_,ghx_) + g2*kron(zx,zx) = 0 + % Taking the differential yields a generalized sylvester equation to get dghxx: A*dghxx + B*dghxx*kron(ghx_,ghx_) = RHSxx + % * for ghxu: A*ghxu + B*ghxx*kron(ghx_,ghu_) + g2*kron(zx,zu) = 0 + % Taking the differential yields an invertible equation to get dghxu: A*dghxu = RHSxu + % * for ghuu: A*ghuu + B*ghxx*kron(ghu_,ghu_) + g2*kron(zu,zu) = 0 + % Taking the differential yields an invertible equation to get dghuu: A*dghuu = RHSuu + % * for ghs2: Ahs2*ghs2 + (gg2_{++}*kron(ghup,ghup) + fyp*ghuup)*vec(Sigma_e) = 0 + % Taking the differential yields an invertible equation to get dghs2: S*dghs2 = RHSs2 + % * due to certainty equivalence and zero mean shocks, we note that ghxs and ghus are zero, and thus not computed + dB = zeros(endo_nbr,endo_nbr,modparam_nbr); %this matrix is also needed at higher orders + dB(:,nstatic+npred+1:end,:) = dg1(:,nonzeros(klead),:); + S = A + B; %needed for dghs2, but also at higher orders + dS = dA + dB; + invS = inv(S); + G_x_x = kron(ghx(idx_states,:),ghx(idx_states,:)); + dG_x_x = zeros(size(G_x_x,1),size(G_x_x,2),modparam_nbr); + dzx = zeros(size(zx,1),size(zx,2),modparam_nbr); + dRHSghxx = zeros(endo_nbr,nspred^2,modparam_nbr); + for jp=1:modparam_nbr + dzx(:,:,jp) = [zeros(nspred,nspred); + dghx(kcurr~=0,:,jp); + dghx(klead~=0,:,jp)*ghx(idx_states,:) + ghx(klead~=0,:)*dghx(idx_states,:,jp); + zeros(exo_nbr,nspred)]; + dRHS_1 = sparse_hessian_times_B_kronecker_C(dg2(:,k2yy0ex0(kyy0,kyy0)+(jp-1)*yy0ex0_nbr^2),zx(1:yy0_nbr,:),threads_BC); + dRHS_2 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(kyy0,kyy0)),dzx(1:yy0_nbr,:,jp),zx(1:yy0_nbr,:),threads_BC); + dRHS_3 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(kyy0,kyy0)),zx(1:yy0_nbr,:),dzx(1:yy0_nbr,:,jp),threads_BC); + dG_x_x(:,:,jp) = kron(dghx(idx_states,:,jp),ghx(idx_states,:)) + kron(ghx(idx_states,:),dghx(idx_states,:,jp)); + dRHSghxx(:,:,jp) = -( (dRHS_1+dRHS_2+dRHS_3) + dA(:,:,jp)*ghxx + dB(:,:,jp)*ghxx*G_x_x + B*ghxx*dG_x_x(:,:,jp) ); + end + %use iterated generalized sylvester equation to compute dghxx + dghxx = sylvester3(A,B,G_x_x,dRHSghxx); + flag = 1; icount = 0; + while flag && icount < 4 + [dghxx, flag] = sylvester3a(dghxx,A,B,G_x_x,dRHSghxx); + icount = icount+1; + end + zu = [zeros(nspred,exo_nbr); + ghu(kcurr~=0,:); + ghx(klead~=0,:)*ghu(idx_states,:); + eye(exo_nbr)]; + abcOutxu = A_times_B_kronecker_C(ghxx,ghx(idx_states,:),ghu(idx_states,:)); %auxiliary expressions for dghxu + abcOutuu = A_times_B_kronecker_C(ghxx,ghu(idx_states,:)); %auxiliary expressions for dghuu + RHSs2 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(nonzeros(klead),nonzeros(klead))), ghu(klead~=0,:),threads_BC); + RHSs2 = RHSs2 + g1(:,nonzeros(klead))*ghuu(klead~=0,:); + dzu = zeros(size(zu,1),size(zu,2),modparam_nbr); + dghxu = zeros(endo_nbr,nspred*exo_nbr,modparam_nbr); + dghuu = zeros(endo_nbr,exo_nbr*exo_nbr,modparam_nbr); + dghs2 = zeros(endo_nbr,totparam_nbr); %note that for modparam we ignore the contribution by dSigma_e and add it after the computations for stderr and corr + for jp=1:modparam_nbr + dzu(:,:,jp) = [zeros(nspred,exo_nbr); + dghu(kcurr~=0,:,jp); + dghx(klead~=0,:,jp)*ghu(idx_states,:) + ghx(klead~=0,:)*dghu(idx_states,:,jp); + zeros(exo_nbr,exo_nbr)]; + %compute dghxu + dRHS_1 = sparse_hessian_times_B_kronecker_C(dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2),zx,zu,threads_BC); + dRHS_2 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(kyy0ex0,kyy0ex0)),dzx(:,:,jp),zu,threads_BC); + dRHS_3 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(kyy0ex0,kyy0ex0)),zx,dzu(:,:,jp),threads_BC); + dabcOut_1 = A_times_B_kronecker_C(dghxx(:,:,jp),ghx(idx_states,:),ghu(idx_states,:)); + dabcOut_2 = A_times_B_kronecker_C(ghxx,dghx(idx_states,:,jp),ghu(idx_states,:)); + dabcOut_3 = A_times_B_kronecker_C(ghxx,ghx(idx_states,:),dghu(idx_states,:,jp)); + dghxu(:,:,jp) = -invA * ( dA(:,:,jp)*ghxu + (dRHS_1+dRHS_2+dRHS_3) + dB(:,:,jp)*abcOutxu + B*(dabcOut_1+dabcOut_2+dabcOut_3) ); + %compute dghuu + dRHS_1 = sparse_hessian_times_B_kronecker_C(dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2),zu,threads_BC); + dRHS_2 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(kyy0ex0,kyy0ex0)),dzu(:,:,jp),zu,threads_BC); + dRHS_3 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(kyy0ex0,kyy0ex0)),zu,dzu(:,:,jp),threads_BC); + dabcOut_1 = A_times_B_kronecker_C(dghxx(:,:,jp),ghu(idx_states,:)); + dabcOut_2 = A_times_B_kronecker_C(ghxx,dghu(idx_states,:,jp),ghu(idx_states,:)); + dabcOut_3 = A_times_B_kronecker_C(ghxx,ghu(idx_states,:),dghu(idx_states,:,jp)); + dghuu(:,:,jp) = -invA * ( dA(:,:,jp)*ghuu + (dRHS_1+dRHS_2+dRHS_3) + dB(:,:,jp)*abcOutuu + B*(dabcOut_1+dabcOut_2+dabcOut_3) ); + %compute dghs2 + dRHS_1 = sparse_hessian_times_B_kronecker_C(dg2(:,k2yy0ex0(nonzeros(klead),nonzeros(klead))+(jp-1)*yy0ex0_nbr^2), ghu(klead~=0,:),threads_BC); + dRHS_2 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(nonzeros(klead),nonzeros(klead))), dghu(klead~=0,:,jp), ghu(klead~=0,:),threads_BC); + dRHS_3 = sparse_hessian_times_B_kronecker_C(g2(:,k2yy0ex0(nonzeros(klead),nonzeros(klead))), ghu(klead~=0,:), dghu(klead~=0,:,jp),threads_BC); + dghs2(:,stderrparam_nbr+corrparam_nbr+jp) = -invS * ( dS(:,:,jp)*ghs2 + ( (dRHS_1+dRHS_2+dRHS_3) + dg1(:,nonzeros(klead),jp)*ghuu(klead~=0,:) + g1(:,nonzeros(klead))*dghuu(klead~=0,:,jp) )*Sigma_e(:) ); + end + %add contributions by dSigma_e to dghs2 + if ~isempty(indpstderr) + for jp = 1:stderrparam_nbr + dghs2(:,jp) = -invS * RHSs2*vec(dSigma_e(:,:,jp)); + end + end + if ~isempty(indpcorr) + for jp = 1:corrparam_nbr + dghs2(:,stderrparam_nbr+jp) = -invS * RHSs2*vec(dSigma_e(:,:,stderrparam_nbr+jp)); + end + end +end + +if order > 2 + % NOTE: The computations can be improved significantly, particularly for larger models [to do: @wmutschl] + % Notation: ghxxx_ = ghxxx(idx_states,:), ghxxx0 = ghxxx(kcurr~=0,:), ghxxxp = ghxxx(klead~=0,:) + % and similar for ghxxu, ghxuu, ghuuu, ghxss, ghuss + + % Note that at third-order we have the following expressions, which are (numerically) zero, given suitable tensor-unfolding permuation matrices P: + % * for ghxxx: A*ghxxx + B*ghxxx*kron(ghx_,kron(ghx_,ghx_)) + g3*kron(kron(zx,zx),zx) + g2*kron(zx,zxx)*P_x_xx + fyp*ghxxp*kron(ghx_,ghxx_)*P_x_xx = 0 + % Taking the differential yields a generalized sylvester equation to get dghxxx: A*dghxxx + B*dghxxx*kron(ghx_,kron(ghx_,ghx_)) = RHSxxx + % * for ghxxu: A*ghxxu + B*ghxxx*kron(ghx_,kron(ghx_,ghu_)) + gg3*kron(zx,kron(zx,zu)) + gg2*(kron(zx,zxu)*P_x_xu + kron(zxx,zu)) + fyp*ghxxp*(kron(ghx_,ghxu_)*P_x_xu + kron(ghxx_,ghu_)) = 0 + % Taking the differential yields an invertible equation to get dghxxu: A*dghxxu = RHSxxu + % * for ghxuu: A*ghxuu + B*ghxxx*kron(ghx_,kron(ghu_,ghu_)) + gg3*kron(zx,kron(zu,zu)) + gg2*(kron(zxu,zu)*P_xu_u + kron(zx,zuu)) + fyp*ghxxp*(kron(ghxu_,ghu_)*Pxu_u + kron(ghx_,ghuu_)) = 0 + % Taking the differential yields an invertible equation to get dghxuu: A*dghxuu = RHSxuu + % * for ghuuu: A*ghuuu + B*ghxxx*kron(ghu_,kron(ghu_,ghu_)) + gg3*kron(kron(zu,zu),zu) + gg2*kron(zu,zuu)*P_u_uu + fyp*ghxxp*kron(ghu_,ghuu_)*P_u_uu = 0 + % Taking the differential yields an invertible equation to get dghuuu: A*dghuuu = RHSuuu + % * for ghxss: A*ghxss + B*ghxss*ghx_ + fyp*ghxxp*kron(ghx_,ghss_) + gg2*kron(zx,zss) + Fxupup*kron(Ix,Sigma_e(:)) = 0 + % Taking the differential yields a generalized sylvester equation to get dghxss: A*dghxss + B*dghxss*ghx_ = RHSxss + % * for ghuss: A*ghuss + B*ghxss*ghu_ + gg2*kron(zu,zss) + fyp*ghxxp*kron(ghu_,ghss_) + Fuupup*kron(Iu,Sigma_e(:)) = 0 + % Taking the differential yields an invertible equation to get dghuss: A*dghuss = RHSuss + % * due to certainty equivalence and Gaussian shocks, we note that ghxxs, ghxus, ghuus, and ghsss are zero and thus not computed + + % permutation matrices + id_xxx = reshape(1:nspred^3,1,nspred,nspred,nspred); + id_uux = reshape(1:nspred*exo_nbr^2,1,exo_nbr,exo_nbr,nspred); + id_uxx = reshape(1:nspred^2*exo_nbr,1,exo_nbr,nspred,nspred); + id_uuu = reshape(1:exo_nbr^3,1,exo_nbr,exo_nbr,exo_nbr); + I_xxx = speye(nspred^3); + I_xxu = speye(nspred^2*exo_nbr); + I_xuu = speye(nspred*exo_nbr^2); + I_uuu = speye(exo_nbr^3); + P_x_xx = I_xxx(:,ipermute(id_xxx,[1,3,4,2])) + I_xxx(:,ipermute(id_xxx,[1,2,4,3])) + I_xxx(:,ipermute(id_xxx,[1,2,3,4])); + P_x_xu = I_xxu(:,ipermute(id_uxx,[1,2,3,4])) + I_xxu(:,ipermute(id_uxx,[1,2,4,3])); + P_xu_u = I_xuu(:,ipermute(id_uux,[1,2,3,4])) + I_xuu(:,ipermute(id_uux,[1,3,2,4])); + P_u_uu = I_uuu(:,ipermute(id_uuu,[1,3,4,2])) + I_uuu(:,ipermute(id_uuu,[1,2,4,3])) + I_uuu(:,ipermute(id_uuu,[1,2,3,4])); + P_uu_u = I_uuu(:,ipermute(id_uuu,[1,2,3,4])) + I_uuu(:,ipermute(id_uuu,[1,3,4,2])); + + zxx = [spalloc(nspred,nspred^2,0); + ghxx(kcurr~=0,:); + ghxx(klead~=0,:)*G_x_x + ghx(klead~=0,:)*ghxx(idx_states,:); + spalloc(exo_nbr,nspred^2,0)]; + G_x_x_x = kron(ghx(idx_states,:), G_x_x); + G_x_xx = kron(ghx(idx_states,:),ghxx(idx_states,:)); + Z_x_x = kron(zx,zx); + Z_x_x_x = kron(zx,Z_x_x); + Z_x_xx = kron(zx,zxx); + fyp_ghxxp = sparse(g1(:,nonzeros(klead))*ghxx(klead~=0,:)); + B_ghxxx = B*ghxxx; + dzxx = zeros(size(zxx,1),size(zxx,2),modparam_nbr); + dfyp_ghxxp = zeros(size(fyp_ghxxp,1),size(fyp_ghxxp,2),modparam_nbr); + + dRHSghxxx = zeros(endo_nbr,nspred^3,modparam_nbr); + for jp=1:modparam_nbr + dzxx(:,:,jp) = [zeros(nspred,nspred^2); + dghxx(kcurr~=0,:,jp); + dghxx(klead~=0,:,jp)*G_x_x + ghxx(klead~=0,:)*dG_x_x(:,:,jp) + dghx(klead~=0,:,jp)*ghxx(idx_states,:) + ghx(klead~=0,:)*dghxx(idx_states,:,jp); + zeros(exo_nbr,nspred^2)]; + dG_x_x_x = kron(dghx(idx_states,:,jp),G_x_x) + kron(ghx(idx_states,:),dG_x_x(:,:,jp)); + dG_x_xx = kron(dghx(idx_states,:,jp),ghxx(idx_states,:)) + kron(ghx(idx_states,:),dghxx(idx_states,:,jp)); + dZ_x_x = kron(dzx(:,:,jp), zx) + kron(zx, dzx(:,:,jp)); + dZ_x_x_x = kron(dzx(:,:,jp), Z_x_x) + kron(zx, dZ_x_x); + dZ_x_xx = kron(dzx(:,:,jp), zxx) + kron(zx, dzxx(:,:,jp)); + dfyp_ghxxp(:,:,jp) = dg1(:,nonzeros(klead),jp)*ghxx(klead~=0,:) + g1(:,nonzeros(klead))*dghxx(klead~=0,:,jp); + dRHSghxxx(:,:,jp) = dA(:,:,jp)*ghxxx + dB(:,:,jp)*ghxxx*G_x_x_x + B_ghxxx*dG_x_x_x; + dRHSghxxx(:,:,jp) = dRHSghxxx(:,:,jp) + dg3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^3)*Z_x_x_x + g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*dZ_x_x_x; + dRHSghxxx(:,:,jp) = dRHSghxxx(:,:,jp) + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*Z_x_xx*P_x_xx + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_x_xx*P_x_xx; + dRHSghxxx(:,:,jp) = dRHSghxxx(:,:,jp) + dfyp_ghxxp(:,:,jp)*G_x_xx*P_x_xx + fyp_ghxxp*dG_x_xx*P_x_xx; + end + dRHSghxxx = -dRHSghxxx; + %use iterated generalized sylvester equation to compute dghxxx + dghxxx = sylvester3(A,B,G_x_x_x,dRHSghxxx); + flag = 1; icount = 0; + while flag && icount < 4 + [dghxxx, flag] = sylvester3a(dghxxx,A,B,G_x_x_x,dRHSghxxx); + icount = icount+1; + end + + %Auxiliary expressions for dghxxu, dghxuu, dghuuu, dghxss, dghuss + G_x_u = kron(ghx(idx_states,:),ghu(idx_states,:)); + G_u_u = kron(ghu(idx_states,:),ghu(idx_states,:)); + zxu = [zeros(nspred,nspred*exo_nbr); + ghxu(kcurr~=0,:); + ghxx(klead~=0,:)*G_x_u + ghx(klead~=0,:)*ghxu(idx_states,:); + zeros(exo_nbr,exo_nbr*nspred)]; + zuu = [zeros(nspred,exo_nbr^2); + ghuu(kcurr~=0,:); + ghxx(klead~=0,:)*G_u_u + ghx(klead~=0,:)*ghuu(idx_states,:); + zeros(exo_nbr,exo_nbr^2)]; + Z_x_u = kron(zx,zu); + Z_u_u = kron(zu,zu); + Z_x_xu = kron(zx,zxu); + Z_xx_u = kron(zxx,zu); + Z_xu_u = kron(zxu,zu); + Z_x_uu = kron(zx,zuu); + Z_u_uu = kron(zu,zuu); + Z_x_x_u = kron(Z_x_x,zu); + Z_x_u_u = kron(Z_x_u,zu); + Z_u_u_u = kron(Z_u_u,zu); + G_x_xu = kron(ghx(idx_states,:),ghxu(idx_states,:)); + G_xx_u = kron(ghxx(idx_states,:),ghu(idx_states,:)); + G_xu_u = kron(ghxu(idx_states,:),ghu(idx_states,:)); + G_x_uu = kron(ghx(idx_states,:),ghuu(idx_states,:)); + G_u_uu = kron(ghu(idx_states,:),ghuu(idx_states,:)); + G_x_x_u = kron(G_x_x,ghu(idx_states,:)); + G_x_u_u = kron(G_x_u,ghu(idx_states,:)); + G_u_u_u = kron(G_u_u,ghu(idx_states,:)); + aux_ZP_x_xu_Z_xx_u = Z_x_xu*P_x_xu + Z_xx_u; + aux_ZP_xu_u_Z_x_uu = Z_xu_u*P_xu_u + Z_x_uu; + aux_GP_x_xu_G_xx_u = G_x_xu*P_x_xu + G_xx_u; + aux_GP_xu_u_G_x_uu = G_xu_u*P_xu_u + G_x_uu; + dghxxu = zeros(endo_nbr,nspred^2*exo_nbr,modparam_nbr); + dghxuu = zeros(endo_nbr,nspred*exo_nbr^2,modparam_nbr); + dghuuu = zeros(endo_nbr,exo_nbr^3,modparam_nbr); + + %stuff for ghxss + zup = [zeros(nspred,exo_nbr); + zeros(length(nonzeros(kcurr)),exo_nbr); + ghu(klead~=0,:); + zeros(exo_nbr,exo_nbr)]; + zss = [zeros(nspred,1); + ghs2(kcurr~=0,:); + ghs2(klead~=0,:) + ghx(klead~=0,:)*ghs2(idx_states,:); + zeros(exo_nbr,1)]; + zxup = [zeros(nspred,nspred*exo_nbr); + zeros(length(nonzeros(kcurr)),nspred*exo_nbr); + ghxu(klead~=0,:)*kron(ghx(idx_states,:),eye(exo_nbr)); + zeros(exo_nbr,nspred*exo_nbr)]; + zupup = [zeros(nspred,exo_nbr^2); + zeros(length(nonzeros(kcurr)),exo_nbr^2); + ghuu(klead~=0,:); + zeros(exo_nbr,exo_nbr^2)]; + G_x_ss = kron(ghx(idx_states,:),ghs2(idx_states,:)); + Z_x_ss = kron(zx,zss); + Z_up_up = kron(zup,zup); + Z_xup_up = kron(zxup,zup); + Z_x_upup = kron(zx,zupup); + Z_x_up_up = kron(zx,Z_up_up); + aux_ZP_xup_up_Z_x_upup = Z_xup_up*P_xu_u + Z_x_upup; + Fxupup = g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*Z_x_up_up + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*aux_ZP_xup_up_Z_x_upup + g1(:,nonzeros(klead))*ghxuu(klead~=0,:)*kron(ghx(idx_states,:),eye(exo_nbr^2)); + Ix_vecSig_e = kron(speye(nspred),Sigma_e(:)); + dRHSxss = zeros(endo_nbr,nspred,totparam_nbr); + + %stuff for ghuss + zuup = [zeros(nspred,exo_nbr^2); + zeros(length(nonzeros(kcurr)),exo_nbr^2); + ghxu(klead~=0,:)*kron(ghu(idx_states,:),eye(exo_nbr)); + zeros(exo_nbr,exo_nbr^2)]; + G_u_ss = kron(ghu(idx_states,:),ghs2(idx_states,:)); + Z_u_ss = kron(zu,zss); + Z_u_upup = kron(zu,zupup); + Z_uup_up = kron(zuup,zup); + Z_u_up_up = kron(zu,Z_up_up); + aux_ZP_uup_up_Z_u_upup = Z_uup_up*P_uu_u + Z_u_upup; + Fuupup = g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*Z_u_up_up + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*aux_ZP_uup_up_Z_u_upup + g1(:,nonzeros(klead))*ghxuu(klead~=0,:)*kron(ghu(idx_states,:),eye(exo_nbr^2)); + Iu_vecSig_e = kron(speye(exo_nbr),Sigma_e(:)); + dRHSuss = zeros(endo_nbr,exo_nbr,totparam_nbr); + + for jp=1:modparam_nbr + dG_x_u = kron(dghx(idx_states,:,jp), ghu(idx_states,:)) + kron(ghx(idx_states,:), dghu(idx_states,:,jp)); + dG_u_u = kron(dghu(idx_states,:,jp), ghu(idx_states,:)) + kron(ghu(idx_states,:), dghu(idx_states,:,jp)); + dzxu = [zeros(nspred,nspred*exo_nbr); + dghxu(kcurr~=0,:,jp); + dghxx(klead~=0,:,jp)*G_x_u + ghxx(klead~=0,:)*dG_x_u + dghx(klead~=0,:,jp)*ghxu(idx_states,:) + ghx(klead~=0,:)*dghxu(idx_states,:,jp); + zeros(exo_nbr,nspred*exo_nbr)]; + dzuu = [zeros(nspred,exo_nbr^2); + dghuu(kcurr~=0,:,jp); + dghxx(klead~=0,:,jp)*G_u_u + ghxx(klead~=0,:)*dG_u_u + dghx(klead~=0,:,jp)*ghuu(idx_states,:) + ghx(klead~=0,:)*dghuu(idx_states,:,jp); + zeros(exo_nbr,exo_nbr^2)]; + dG_x_xu = kron(dghx(idx_states,:,jp),ghxu(idx_states,:)) + kron(ghx(idx_states,:),dghxu(idx_states,:,jp)); + dG_x_uu = kron(dghx(idx_states,:,jp),ghuu(idx_states,:)) + kron(ghx(idx_states,:),dghuu(idx_states,:,jp)); + dG_u_uu = kron(dghu(idx_states,:,jp),ghuu(idx_states,:)) + kron(ghu(idx_states,:),dghuu(idx_states,:,jp)); + dG_xx_u = kron(dghxx(idx_states,:,jp),ghu(idx_states,:)) + kron(ghxx(idx_states,:),dghu(idx_states,:,jp)); + dG_xu_u = kron(dghxu(idx_states,:,jp),ghu(idx_states,:)) + kron(ghxu(idx_states,:),dghu(idx_states,:,jp)); + dG_x_x_u = kron(G_x_x,dghu(idx_states,:,jp)) + kron(dG_x_x(:,:,jp),ghu(idx_states,:)); + dG_x_u_u = kron(G_x_u,dghu(idx_states,:,jp)) + kron(dG_x_u,ghu(idx_states,:)); + dG_u_u_u = kron(G_u_u,dghu(idx_states,:,jp)) + kron(dG_u_u,ghu(idx_states,:)); + dZ_x_u = kron(dzx(:,:,jp),zu) + kron(zx,dzu(:,:,jp)); + dZ_u_u = kron(dzu(:,:,jp),zu) + kron(zu,dzu(:,:,jp)); + dZ_x_x_u = kron(dzx(:,:,jp), Z_x_u) + kron(zx, dZ_x_u); + dZ_x_u_u = kron(dZ_x_u, zu) + kron(Z_x_u, dzu(:,:,jp)); + dZ_u_u_u = kron(dZ_u_u, zu) + kron(Z_u_u, dzu(:,:,jp)); + dZ_xx_u = kron(dzxx(:,:,jp), zu) + kron(zxx, dzu(:,:,jp)); + dZ_xu_u = kron(dzxu, zu) + kron(zxu, dzu(:,:,jp)); + dZ_x_xu = kron(dzx(:,:,jp), zxu) + kron(zx, dzxu); + dZ_x_uu = kron(dzx(:,:,jp), zuu) + kron(zx, dzuu); + dZ_u_uu = kron(dzu(:,:,jp), zuu) + kron(zu, dzuu); + dB_ghxxx = dB(:,:,jp)*ghxxx + B*dghxxx(:,:,jp); + %Compute dghxxu + dRHS = dA(:,:,jp)*ghxxu + dB_ghxxx*G_x_x_u + B_ghxxx*dG_x_x_u; + dRHS = dRHS + dg3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^3)*Z_x_x_u + g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*dZ_x_x_u; + dRHS = dRHS + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*aux_ZP_x_xu_Z_xx_u + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*( dZ_x_xu*P_x_xu + dZ_xx_u ); + dRHS = dRHS + dfyp_ghxxp(:,:,jp)*aux_GP_x_xu_G_xx_u + fyp_ghxxp*( dG_x_xu*P_x_xu + dG_xx_u ); + dghxxu(:,:,jp) = invA* (-dRHS); + %Compute dghxuu + dRHS = dA(:,:,jp)*ghxuu + dB_ghxxx*G_x_u_u + B_ghxxx*dG_x_u_u; + dRHS = dRHS + dg3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^3)*Z_x_u_u + g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*dZ_x_u_u; + dRHS = dRHS + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*aux_ZP_xu_u_Z_x_uu + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*( dZ_xu_u*P_xu_u + dZ_x_uu ); + dRHS = dRHS + dfyp_ghxxp(:,:,jp)*aux_GP_xu_u_G_x_uu + fyp_ghxxp*( dG_xu_u*P_xu_u + dG_x_uu ); + dghxuu(:,:,jp) = invA* (-dRHS); + %Compute dghuuu + dRHS = dA(:,:,jp)*ghuuu + dB_ghxxx*G_u_u_u + B_ghxxx*dG_u_u_u; + dRHS = dRHS + dg3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^3)*Z_u_u_u + g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*dZ_u_u_u; + dRHS = dRHS + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*Z_u_uu*P_u_uu + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_u_uu*P_u_uu; + dRHS = dRHS + dfyp_ghxxp(:,:,jp)*G_u_uu*P_u_uu + fyp_ghxxp*dG_u_uu*P_u_uu; + dghuuu(:,:,jp) = invA* (-dRHS); + %Compute dRHSxss + dzup = [zeros(nspred,exo_nbr); + zeros(length(nonzeros(kcurr)),exo_nbr); + dghu(klead~=0,:,jp); + zeros(exo_nbr,exo_nbr)]; + dzss = [zeros(nspred,1); + dghs2(kcurr~=0,stderrparam_nbr+corrparam_nbr+jp); + dghs2(klead~=0,stderrparam_nbr+corrparam_nbr+jp) + dghx(klead~=0,:,jp)*ghs2(idx_states,:) + ghx(klead~=0,:)*dghs2(idx_states,stderrparam_nbr+corrparam_nbr+jp); + zeros(exo_nbr,1)]; + dzxup = [zeros(nspred,nspred*exo_nbr); + zeros(length(nonzeros(kcurr)),nspred*exo_nbr); + dghxu(klead~=0,:,jp)*kron(ghx(idx_states,:),eye(exo_nbr)) + ghxu(klead~=0,:)*kron(dghx(idx_states,:,jp),eye(exo_nbr)); + zeros(exo_nbr,nspred*exo_nbr)]; + dzupup = [zeros(nspred,exo_nbr^2); + zeros(length(nonzeros(kcurr)),exo_nbr^2); + dghuu(klead~=0,:,jp); + zeros(exo_nbr,exo_nbr^2)]; + dG_x_ss = kron(dghx(idx_states,:,jp),ghs2(idx_states,:)) + kron(ghx(idx_states,:),dghs2(idx_states,stderrparam_nbr+corrparam_nbr+jp)); + dZ_x_ss = kron(dzx(:,:,jp),zss) + kron(zx,dzss); + dZ_up_up = kron(dzup,zup) + kron(zup,dzup); + dZ_xup_up = kron(dzxup,zup) + kron(zxup,dzup); + dZ_x_upup = kron(dzx(:,:,jp),zupup) + kron(zx,dzupup); + dZ_x_up_up = kron(dzx(:,:,jp),Z_up_up) + kron(zx,dZ_up_up); + daux_ZP_xup_up_Z_x_upup = dZ_xup_up*P_xu_u + dZ_x_upup; + dFxupup = dg3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^3)*Z_x_up_up + g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*dZ_x_up_up... + + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*aux_ZP_xup_up_Z_x_upup + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*daux_ZP_xup_up_Z_x_upup... + + dg1(:,nonzeros(klead),jp)*ghxuu(klead~=0,:)*kron(ghx(idx_states,:),eye(exo_nbr^2)) + g1(:,nonzeros(klead))*dghxuu(klead~=0,:,jp)*kron(ghx(idx_states,:),eye(exo_nbr^2)) + g1(:,nonzeros(klead))*ghxuu(klead~=0,:)*kron(dghx(idx_states,:,jp),eye(exo_nbr^2)); + dRHSxss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dA(:,:,jp)*ghxss + dB(:,:,jp)*ghxss*ghx(idx_states,:) + B*ghxss*dghx(idx_states,:,jp); + dRHSxss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dRHSxss(:,:,stderrparam_nbr+corrparam_nbr+jp) + dfyp_ghxxp(:,:,jp)*G_x_ss + fyp_ghxxp*dG_x_ss; + dRHSxss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dRHSxss(:,:,stderrparam_nbr+corrparam_nbr+jp) + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*Z_x_ss + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_x_ss; + dRHSxss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dRHSxss(:,:,stderrparam_nbr+corrparam_nbr+jp) + dFxupup*Ix_vecSig_e; %missing contribution by dSigma_e + %Compute dRHSuss + dzuup = [zeros(nspred,exo_nbr^2); + zeros(length(nonzeros(kcurr)),exo_nbr^2); + dghxu(klead~=0,:,jp)*kron(ghu(idx_states,:),eye(exo_nbr)) + ghxu(klead~=0,:)*kron(dghu(idx_states,:,jp),eye(exo_nbr)); + zeros(exo_nbr,exo_nbr^2)]; + dG_u_ss = kron(dghu(idx_states,:,jp),ghs2(idx_states,:)) + kron(ghu(idx_states,:),dghs2(idx_states,stderrparam_nbr+corrparam_nbr+jp)); + dZ_u_ss = kron(dzu(:,:,jp),zss) + kron(zu,dzss); + dZ_u_upup = kron(dzu(:,:,jp),zupup) + kron(zu,dzupup); + dZ_uup_up = kron(dzuup,zup) + kron(zuup,dzup); + dZ_u_up_up = kron(dzu(:,:,jp),Z_up_up) + kron(zu,dZ_up_up); + daux_ZP_uup_up_Z_u_upup = dZ_uup_up*P_uu_u + dZ_u_upup; + dFuupup = dg3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^3)*Z_u_up_up + g3(:,k3yy0ex0(kyy0ex0,kyy0ex0,kyy0ex0))*dZ_u_up_up... + + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*aux_ZP_uup_up_Z_u_upup + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*daux_ZP_uup_up_Z_u_upup... + + dg1(:,nonzeros(klead),jp)*ghxuu(klead~=0,:)*kron(ghu(idx_states,:),eye(exo_nbr^2)) + g1(:,nonzeros(klead))*dghxuu(klead~=0,:,jp)*kron(ghu(idx_states,:),eye(exo_nbr^2)) + g1(:,nonzeros(klead))*ghxuu(klead~=0,:)*kron(dghu(idx_states,:,jp),eye(exo_nbr^2)); + dRHSuss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dA(:,:,jp)*ghuss + dB(:,:,jp)*ghxss*ghu(idx_states,:) + B*ghxss*dghu(idx_states,:,jp); %missing dghxss + dRHSuss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dRHSuss(:,:,stderrparam_nbr+corrparam_nbr+jp) + dfyp_ghxxp(:,:,jp)*G_u_ss + fyp_ghxxp*dG_u_ss; + dRHSuss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dRHSuss(:,:,stderrparam_nbr+corrparam_nbr+jp) + dg2(:,k2yy0ex0(kyy0ex0,kyy0ex0)+(jp-1)*yy0ex0_nbr^2)*Z_u_ss + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_u_ss; + dRHSuss(:,:,stderrparam_nbr+corrparam_nbr+jp) = dRHSuss(:,:,stderrparam_nbr+corrparam_nbr+jp) + dFuupup*Iu_vecSig_e; %contribution by dSigma_e only for stderr and corr params + end + %Add contribution for stderr and corr params to dRHSxss and dRHSuss + if ~isempty(indpstderr) + for jp = 1:stderrparam_nbr + dzss = [zeros(nspred,1); + dghs2(kcurr~=0,jp); + dghs2(klead~=0,jp) + ghx(klead~=0,:)*dghs2(idx_states,jp); + zeros(exo_nbr,1)]; + dG_x_ss = kron(ghx(idx_states,:),dghs2(idx_states,jp)); + dZ_x_ss = kron(zx,dzss); + dRHSxss(:,:,jp) = Fxupup*kron(speye(nspred),vec(dSigma_e(:,:,jp))); + dRHSxss(:,:,jp) = dRHSxss(:,:,jp) + fyp_ghxxp*dG_x_ss; + dRHSxss(:,:,jp) = dRHSxss(:,:,jp) + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_x_ss; + + dG_u_ss = kron(ghu(idx_states,:),dghs2(idx_states,jp)); + dZ_u_ss = kron(zu,dzss); + dRHSuss(:,:,jp) = Fuupup*kron(speye(exo_nbr),vec(dSigma_e(:,:,jp))); + dRHSuss(:,:,jp) = dRHSuss(:,:,jp) + fyp_ghxxp*dG_u_ss; + dRHSuss(:,:,jp) = dRHSuss(:,:,jp) + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_u_ss; + end + end + if ~isempty(indpcorr) + for jp = (stderrparam_nbr+1):(stderrparam_nbr+corrparam_nbr) + dzss = [zeros(nspred,1); + dghs2(kcurr~=0,jp); + dghs2(klead~=0,jp) + ghx(klead~=0,:)*dghs2(idx_states,jp); + zeros(exo_nbr,1)]; + dG_x_ss = kron(ghx(idx_states,:),dghs2(idx_states,jp)); + dZ_x_ss = kron(zx,dzss); + dRHSxss(:,:,jp) = Fxupup*kron(speye(nspred),vec(dSigma_e(:,:,jp))); + dRHSxss(:,:,jp) = dRHSxss(:,:,jp) + fyp_ghxxp*dG_x_ss; + dRHSxss(:,:,jp) = dRHSxss(:,:,jp) + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_x_ss; + + dG_u_ss = kron(ghu(idx_states,:),dghs2(idx_states,jp)); + dZ_u_ss = kron(zu,dzss); + dRHSuss(:,:,jp) = Fuupup*kron(speye(exo_nbr),vec(dSigma_e(:,:,jp))); + dRHSuss(:,:,jp) = dRHSuss(:,:,jp) + fyp_ghxxp*dG_u_ss; + dRHSuss(:,:,jp) = dRHSuss(:,:,jp) + g2(:,k2yy0ex0(kyy0ex0,kyy0ex0))*dZ_u_ss; + end + end + dRHSxss = -dRHSxss; + %use iterated generalized sylvester equation to compute dghxss + dghxss = sylvester3(A,B,ghx(idx_states,:),dRHSxss); + flag = 1; icount = 0; + while flag && icount < 4 + [dghxss, flag] = sylvester3a(dghxss,A,B,ghx(idx_states,:),dRHSxss); + icount = icount+1; + end + %Add contribution by dghxss to dRHSuss and compute it + dghuss = zeros(endo_nbr,exo_nbr,totparam_nbr); + for jp = 1:totparam_nbr + dRHS = dRHSuss(:,:,jp) + B*dghxss(:,:,jp)*ghu(idx_states,:); + dghuss(:,:,jp) = invA* (-dRHS); + end +end + +%% Store into structure +DERIVS.dg1 = dg1; +DERIVS.dSigma_e = dSigma_e; +DERIVS.dCorrelation_matrix = dCorrelation_matrix; +DERIVS.dYss = dYss; +DERIVS.dghx = cat(3,zeros(endo_nbr,nspred,stderrparam_nbr+corrparam_nbr), dghx); +DERIVS.dghu = cat(3,zeros(endo_nbr,exo_nbr,stderrparam_nbr+corrparam_nbr), dghu); +DERIVS.dOm = dOm; +if order > 1 + DERIVS.dg2 = dg2; + DERIVS.dghxx = cat(3,zeros(endo_nbr,nspred^2,stderrparam_nbr+corrparam_nbr), dghxx); + DERIVS.dghxu = cat(3,zeros(endo_nbr,nspred*exo_nbr,stderrparam_nbr+corrparam_nbr), dghxu); + DERIVS.dghuu = cat(3,zeros(endo_nbr,exo_nbr^2,stderrparam_nbr+corrparam_nbr), dghuu); + DERIVS.dghs2 = dghs2; +end +if order > 2 + DERIVS.dg3 = dg3; + DERIVS.dghxxx = cat(3,zeros(endo_nbr,nspred^3,stderrparam_nbr+corrparam_nbr), dghxxx); + DERIVS.dghxxu = cat(3,zeros(endo_nbr,nspred^2*exo_nbr,stderrparam_nbr+corrparam_nbr), dghxxu); + DERIVS.dghxuu = cat(3,zeros(endo_nbr,nspred*exo_nbr^2,stderrparam_nbr+corrparam_nbr), dghxuu); + DERIVS.dghuuu = cat(3,zeros(endo_nbr,exo_nbr^3,stderrparam_nbr+corrparam_nbr), dghuuu); + DERIVS.dghxss = dghxss; + DERIVS.dghuss = dghuss; +end + +%% Construct Hessian (wrt all selected parameters) of ghx, and Om=ghu*Sigma_e*ghu' +if d2flag + % Construct Hessian (wrt all selected parameters) of Sigma_e + % note that we only need to focus on (stderr x stderr), (stderr x corr), (corr x stderr) parameters, because derivatives wrt all other second-cross parameters are zero by construction + d2Sigma_e = zeros(exo_nbr,exo_nbr,totparam_nbr^2); %initialize full matrix, even though we'll reduce it later to unique upper triangular values + % Compute Hessian of Sigma_e wrt (stderr x stderr) parameters + if ~isempty(indp2stderrstderr) + for jp = 1:stderrparam_nbr + for ip = 1:jp + if jp == ip %same stderr parameters + d2Sigma_e(indpstderr(jp),indpstderr(jp),indp2stderrstderr(ip,jp)) = 2; + else %different stderr parameters + if isdiag(Sigma_e) == 0 % if there are correlated errors + d2Sigma_e(indpstderr(jp),indpstderr(ip),indp2stderrstderr(ip,jp)) = Correlation_matrix(indpstderr(jp),indpstderr(ip)); + d2Sigma_e(indpstderr(ip),indpstderr(jp),indp2stderrstderr(ip,jp)) = Correlation_matrix(indpstderr(jp),indpstderr(ip)); %symmetry + end + end + end + end + end + % Compute Hessian of Sigma_e wrt (stderr x corr) parameters + if ~isempty(indp2stderrcorr) + for jp = 1:stderrparam_nbr + for ip = 1:corrparam_nbr + if indpstderr(jp) == indpcorr(ip,1) %if stderr is equal to first index of corr parameter, then derivative is equal to stderr of second index + d2Sigma_e(indpstderr(jp),indpcorr(ip,2),indp2stderrcorr(jp,ip)) = sqrt(Sigma_e(indpcorr(ip,2),indpcorr(ip,2))); + d2Sigma_e(indpcorr(ip,2),indpstderr(jp),indp2stderrcorr(jp,ip)) = sqrt(Sigma_e(indpcorr(ip,2),indpcorr(ip,2))); % symmetry + end + if indpstderr(jp) == indpcorr(ip,2) %if stderr is equal to second index of corr parameter, then derivative is equal to stderr of first index + d2Sigma_e(indpstderr(jp),indpcorr(ip,1),indp2stderrcorr(jp,ip)) = sqrt(Sigma_e(indpcorr(ip,1),indpcorr(ip,1))); + d2Sigma_e(indpcorr(ip,1),indpstderr(jp),indp2stderrcorr(jp,ip)) = sqrt(Sigma_e(indpcorr(ip,1),indpcorr(ip,1))); % symmetry + end + end + end + end + d2Sigma_e = d2Sigma_e(:,:,indp2tottot2); %focus on upper triangular hessian values only + + % Construct nonzero derivatives wrt to t+1, i.e. GAM1=-f_{y^+} in Villemot (2011) + GAM1 = zeros(endo_nbr,endo_nbr); + GAM1(:,klead~=0,:) = -g1(:,nonzeros(klead)); + dGAM1 = zeros(endo_nbr,endo_nbr,modparam_nbr); + dGAM1(:,klead~=0,:) = -dg1(:,nonzeros(klead),:); + indind = ismember(d2g1(:,2),nonzeros(klead)); + tmp = d2g1(indind,:); + tmp(:,end)=-tmp(:,end); + d2GAM1 = tmp; + indklead = find(klead~=0); + for j = 1:size(tmp,1) + inxinx = (nonzeros(klead)==tmp(j,2)); + d2GAM1(j,2) = indklead(inxinx); + end + + % Construct nonzero derivatives wrt to t, i.e. GAM0=f_{y^0} in Villemot (2011) + GAM0 = zeros(endo_nbr,endo_nbr); + GAM0(:,kcurr~=0,:) = g1(:,nonzeros(kcurr)); + dGAM0 = zeros(endo_nbr,endo_nbr,modparam_nbr); + dGAM0(:,kcurr~=0,:) = dg1(:,nonzeros(kcurr),:); + indind = ismember(d2g1(:,2),nonzeros(kcurr)); + tmp = d2g1(indind,:); + d2GAM0 = tmp; + indkcurr = find(kcurr~=0); + for j = 1:size(tmp,1) + inxinx = (nonzeros(kcurr)==tmp(j,2)); + d2GAM0(j,2) = indkcurr(inxinx); + end + + % Construct nonzero derivatives wrt to t-1, i.e. GAM2=-f_{y^-} in Villemot (2011) + % GAM2 = zeros(endo_nbr,endo_nbr); + % GAM2(:,klag~=0) = -g1(:,nonzeros(klag)); + % dGAM2 = zeros(endo_nbr,endo_nbr,modparam_nbr); + % dGAM2(:,klag~=0) = -dg1(:,nonzeros(klag),:); + indind = ismember(d2g1(:,2),nonzeros(klag)); + tmp = d2g1(indind,:); + tmp(:,end) = -tmp(:,end); + d2GAM2 = tmp; + indklag = find(klag~=0); + for j = 1:size(tmp,1) + inxinx = (nonzeros(klag)==tmp(j,2)); + d2GAM2(j,2) = indklag(inxinx); + end + + % Construct nonzero derivatives wrt to u_t, i.e. GAM3=-f_{u} in Villemot (2011) + % GAM3 = -g1(:,yy0_nbr+1:end); + % dGAM3 = -dg1(:,yy0_nbr+1:end,:); + cols_ex = yy0_nbr+(1:yy0ex0_nbr); + indind = ismember(d2g1(:,2),cols_ex); + tmp = d2g1(indind,:); + tmp(:,end) = -tmp(:,end); + d2GAM3 = tmp; + for j = 1:size(tmp,1) + inxinx = find(cols_ex==tmp(j,2)); + d2GAM3(j,2) = inxinx; + end + + clear d2g1 tmp + + % Compute Hessian (wrt selected params) of ghx using generalized sylvester equations, see equations 17 and 18 in Ratto and Iskrev (2012) + % solves MM*d2KalmanA+N*d2KalmanA*P = QQ where d2KalmanA are second order derivatives (wrt model parameters) of KalmanA + QQ = zeros(endo_nbr,endo_nbr,floor(sqrt(modparam_nbr2))); + jcount=0; + cumjcount=0; + jinx = []; + x2x=sparse(endo_nbr*endo_nbr,modparam_nbr2); + dKalmanA = zeros(endo_nbr,endo_nbr,modparam_nbr); + dKalmanA(:,idx_states,:) = dghx; + MM = (GAM0-GAM1*KalmanA); + invMM = inv(MM); + for i=1:modparam_nbr + for j=1:i + elem1 = (get_2nd_deriv(d2GAM0,endo_nbr,endo_nbr,j,i)-get_2nd_deriv(d2GAM1,endo_nbr,endo_nbr,j,i)*KalmanA); + elem1 = get_2nd_deriv(d2GAM2,endo_nbr,endo_nbr,j,i)-elem1*KalmanA; + elemj0 = dGAM0(:,:,j)-dGAM1(:,:,j)*KalmanA; + elemi0 = dGAM0(:,:,i)-dGAM1(:,:,i)*KalmanA; + elem2 = -elemj0*dKalmanA(:,:,i)-elemi0*dKalmanA(:,:,j); + elem2 = elem2 + ( dGAM1(:,:,j)*dKalmanA(:,:,i) + dGAM1(:,:,i)*dKalmanA(:,:,j) )*KalmanA; + elem2 = elem2 + GAM1*( dKalmanA(:,:,i)*dKalmanA(:,:,j) + dKalmanA(:,:,j)*dKalmanA(:,:,i)); + jcount=jcount+1; + jinx = [jinx; [j i]]; + QQ(:,:,jcount) = elem1+elem2; + if jcount==floor(sqrt(modparam_nbr2)) || (j*i)==modparam_nbr^2 + if (j*i)==modparam_nbr^2 + QQ = QQ(:,:,1:jcount); + end + xx2=sylvester3(MM,-GAM1,KalmanA,QQ); + flag=1; + icount=0; + while flag && icount<4 + [xx2, flag]=sylvester3a(xx2,MM,-GAM1,KalmanA,QQ); + icount = icount + 1; + end + x2x(:,cumjcount+1:cumjcount+jcount)=reshape(xx2,[endo_nbr*endo_nbr jcount]); + cumjcount=cumjcount+jcount; + jcount = 0; + jinx = []; + end + end + end + clear xx2; + jcount = 0; + icount = 0; + cumjcount = 0; + MAX_DIM_MAT = 100000000; + ncol = max(1,floor(MAX_DIM_MAT/(8*endo_nbr*(endo_nbr+1)/2))); + ncol = min(ncol, totparam_nbr2); + d2KalmanA = sparse(endo_nbr*endo_nbr,totparam_nbr2); + d2Om = sparse(endo_nbr*(endo_nbr+1)/2,totparam_nbr2); + d2KalmanA_tmp = zeros(endo_nbr*endo_nbr,ncol); + d2Om_tmp = zeros(endo_nbr*(endo_nbr+1)/2,ncol); + tmpDir = CheckPath('tmp_derivs',dname); + offset = stderrparam_nbr+corrparam_nbr; + % d2B = zeros(m,n,tot_param_nbr,tot_param_nbr); + for j=1:totparam_nbr + for i=1:j + jcount=jcount+1; + if j<=offset %stderr and corr parameters + y = KalmanB*d2Sigma_e(:,:,jcount)*KalmanB'; + d2Om_tmp(:,jcount) = dyn_vech(y); + else %model parameters + jind = j-offset; + iind = i-offset; + if i<=offset + y = dghu(:,:,jind)*dSigma_e(:,:,i)*KalmanB'+KalmanB*dSigma_e(:,:,i)*dghu(:,:,jind)'; + % y(abs(y)<1.e-8)=0; + d2Om_tmp(:,jcount) = dyn_vech(y); + else + icount=icount+1; + dKalmanAj = reshape(x2x(:,icount),[endo_nbr endo_nbr]); + % x = get_2nd_deriv(x2x,m,m,iind,jind);%xx2(:,:,jcount); + elem1 = (get_2nd_deriv(d2GAM0,endo_nbr,endo_nbr,iind,jind)-get_2nd_deriv(d2GAM1,endo_nbr,endo_nbr,iind,jind)*KalmanA); + elem1 = elem1 -( dGAM1(:,:,jind)*dKalmanA(:,:,iind) + dGAM1(:,:,iind)*dKalmanA(:,:,jind) ); + elemj0 = dGAM0(:,:,jind)-dGAM1(:,:,jind)*KalmanA-GAM1*dKalmanA(:,:,jind); + elemi0 = dGAM0(:,:,iind)-dGAM1(:,:,iind)*KalmanA-GAM1*dKalmanA(:,:,iind); + elem0 = elemj0*dghu(:,:,iind)+elemi0*dghu(:,:,jind); + y = invMM * (get_2nd_deriv(d2GAM3,endo_nbr,exo_nbr,iind,jind)-elem0-(elem1-GAM1*dKalmanAj)*KalmanB); + % d2B(:,:,j+length(indexo),i+length(indexo)) = y; + % d2B(:,:,i+length(indexo),j+length(indexo)) = y; + y = y*Sigma_e*KalmanB'+KalmanB*Sigma_e*y'+ ... + dghu(:,:,jind)*Sigma_e*dghu(:,:,iind)'+dghu(:,:,iind)*Sigma_e*dghu(:,:,jind)'; + % x(abs(x)<1.e-8)=0; + d2KalmanA_tmp(:,jcount) = vec(dKalmanAj); + % y(abs(y)<1.e-8)=0; + d2Om_tmp(:,jcount) = dyn_vech(y); + end + end + if jcount==ncol || i*j==totparam_nbr^2 + d2KalmanA(:,cumjcount+1:cumjcount+jcount) = d2KalmanA_tmp(:,1:jcount); + % d2KalmanA(:,:,j+length(indexo),i+length(indexo)) = x; + % d2KalmanA(:,:,i+length(indexo),j+length(indexo)) = x; + d2Om(:,cumjcount+1:cumjcount+jcount) = d2Om_tmp(:,1:jcount); + % d2Om(:,:,j+length(indexo),i+length(indexo)) = y; + % d2Om(:,:,i+length(indexo),j+length(indexo)) = y; + save([tmpDir filesep 'd2KalmanA_' int2str(cumjcount+1) '_' int2str(cumjcount+jcount) '.mat'],'d2KalmanA') + save([tmpDir filesep 'd2Om_' int2str(cumjcount+1) '_' int2str(cumjcount+jcount) '.mat'],'d2Om') + cumjcount = cumjcount+jcount; + jcount=0; + % d2KalmanA = sparse(m1*m1,tot_param_nbr*(tot_param_nbr+1)/2); + % d2Om = sparse(m1*(m1+1)/2,tot_param_nbr*(tot_param_nbr+1)/2); + d2KalmanA_tmp = zeros(endo_nbr*endo_nbr,ncol); + d2Om_tmp = zeros(endo_nbr*(endo_nbr+1)/2,ncol); + end + end + end + + %Store into structure + DERIVS.d2Yss = d2Yss; + DERIVS.d2KalmanA = d2KalmanA; + DERIVS.d2Om = d2Om; +end + +return + +%% AUXILIARY FUNCTIONS %% +%%%%%%%%%%%%%%%%%%%%%%%%% + +function g22 = get_2nd_deriv(gpp,m,n,i,j) +% inputs: +% - gpp: [#second_order_Jacobian_terms by 5] double Hessian matrix (wrt parameters) of a matrix +% rows: respective derivative term +% 1st column: equation number of the term appearing +% 2nd column: column number of variable in Jacobian +% 3rd column: number of the first parameter in derivative +% 4th column: number of the second parameter in derivative +% 5th column: value of the Hessian term +% - m: scalar number of equations +% - n: scalar number of variables +% - i: scalar number for which first parameter +% - j: scalar number for which second parameter + +g22=zeros(m,n); +is=find(gpp(:,3)==i); +is=is(find(gpp(is,4)==j)); + +if ~isempty(is) + g22(sub2ind([m,n],gpp(is,1),gpp(is,2)))=gpp(is,5)'; +end +return + +function g22 = get_2nd_deriv_mat(gpp,i,j,npar) +% inputs: +% - gpp: [#second_order_Jacobian_terms by 5] double Hessian matrix of (wrt parameters) of dynamic Jacobian +% rows: respective derivative term +% 1st column: equation number of the term appearing +% 2nd column: column number of variable in Jacobian of the dynamic model +% 3rd column: number of the first parameter in derivative +% 4th column: number of the second parameter in derivative +% 5th column: value of the Hessian term +% - i: scalar number for which model equation +% - j: scalar number for which variable in Jacobian of dynamic model +% - npar: scalar Number of model parameters, i.e. equals param_nbr +% +% output: +% g22: [npar by npar] Hessian matrix (wrt parameters) of Jacobian of dynamic model for equation i +% rows: first parameter in Hessian +% columns: second paramater in Hessian + +g22=zeros(npar,npar); +is=find(gpp(:,1)==i); +is=is(find(gpp(is,2)==j)); + +if ~isempty(is) + g22(sub2ind([npar,npar],gpp(is,3),gpp(is,4)))=gpp(is,5)'; +end +return + +function r22 = get_all_resid_2nd_derivs(rpp,m,npar) +% inputs: +% - rpp: [#second_order_residual_terms by 4] double Hessian matrix (wrt paramters) of model equations +% rows: respective derivative term +% 1st column: equation number of the term appearing +% 2nd column: number of the first parameter in derivative +% 3rd column: number of the second parameter in derivative +% 4th column: value of the Hessian term +% - m: scalar Number of residuals (or model equations), i.e. equals endo_nbr +% - npar: scalar Number of model parameters, i.e. equals param_nbr +% +% output: +% r22: [endo_nbr by param_nbr by param_nbr] Hessian matrix of model equations with respect to parameters +% rows: equations in order of declaration +% 1st columns: first parameter number in derivative +% 2nd columns: second parameter in derivative + +r22=zeros(m,npar,npar); + +for is=1:size(rpp,1) + % Keep symmetry in hessian, hence 2 and 3 as well as 3 and 2, i.e. d2f/(dp1 dp2) = d2f/(dp2 dp1) + r22(rpp(is,1),rpp(is,2),rpp(is,3))=rpp(is,4); + r22(rpp(is,1),rpp(is,3),rpp(is,2))=rpp(is,4); +end + +return + +function h2 = get_hess_deriv(hp,i,j,m,npar) +% inputs: +% - hp: [#first_order_Hessian_terms by 5] double Jacobian matrix (wrt paramters) of dynamic Hessian +% rows: respective derivative term +% 1st column: equation number of the term appearing +% 2nd column: column number of first variable in Hessian of the dynamic model +% 3rd column: column number of second variable in Hessian of the dynamic model +% 4th column: number of the parameter in derivative +% 5th column: value of the Hessian term +% - i: scalar number for which model equation +% - j: scalar number for which first variable in Hessian of dynamic model variable +% - m: scalar Number of dynamic model variables + exogenous vars, i.e. yy0_nbr + exo_nbr +% - npar: scalar Number of model parameters, i.e. equals param_nbr +% +% output: +% h2: [(yy0_nbr + exo_nbr) by param_nbr] Jacobian matrix (wrt parameters) of dynamic Hessian +% rows: second dynamic or exogenous variables in Hessian of specific model equation of the dynamic model +% columns: parameters + +h2=zeros(m,npar); +is1=find(hp(:,1)==i); +is=is1(find(hp(is1,2)==j)); + +if ~isempty(is) + h2(sub2ind([m,npar],hp(is,3),hp(is,4)))=hp(is,5)'; +end + +return diff --git a/matlab/get_perturbation_params_derivs_numerical_objective.m b/matlab/get_perturbation_params_derivs_numerical_objective.m new file mode 100644 index 000000000..5193bc323 --- /dev/null +++ b/matlab/get_perturbation_params_derivs_numerical_objective.m @@ -0,0 +1,110 @@ +function [out,info] = get_perturbation_params_derivs_numerical_objective(params, outputflag, estim_params, M, oo, options) +%function [out,info] = get_perturbation_params_derivs_numerical_objective(params, outputflag, estim_params, M, oo, options) +% ------------------------------------------------------------------------- +% Objective function to compute numerically the Jacobians used for get_perturbation_params_derivs +% ========================================================================= +% INPUTS +% params: [vector] parameter values at which to evaluate objective function +% stderr parameters come first, corr parameters second, model parameters third +% outputflag: [string] flag which objective to compute (see below) +% estim_params: [structure] storing the estimation information +% M: [structure] storing the model information +% oo: [structure] storing the solution results +% options: [structure] storing the options +% ------------------------------------------------------------------------- +% +% OUTPUT +% out (dependent on outputflag and order of approximation): +% - 'perturbation_solution': out = out1 = [vec(Sigma_e);vec(ghx);vec(ghu)]; (order==1) +% out = out2 = [out1;vec(ghxx);vec(ghxu);vec(ghuu);vec(ghs2)]; (order==2) +% out = out3 = [out1;out2;vec(ghxxx);vec(ghxxu);vec(ghxuu);vec(ghuuu);vec(ghxss);vec(ghuss)]; (order==3) +% - 'dynamic_model': out = [Yss; vec(g1); vec(g2); vec(g3)] +% - 'Kalman_Transition': out = [Yss; vec(KalmanA); dyn_vech(KalmanB*Sigma_e*KalmanB')]; +% all in DR-order +% info [integer] output from resol +% ------------------------------------------------------------------------- +% This function is called by +% * get_perturbation_params_derivs.m (previously getH.m) +% ------------------------------------------------------------------------- +% This function calls +% * [M.fname,'.dynamic'] +% * resol +% * dyn_vech +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= + +%% Update stderr, corr and model parameters and compute perturbation approximation and steady state with updated parameters +M = set_all_parameters(params,estim_params,M); +[~,info,M,options,oo] = resol(0,M,options,oo); +Sigma_e = M.Sigma_e; + +if info(1) > 0 + % there are errors in the solution algorithm + out = []; + return +else + ys = oo.dr.ys; %steady state of model variables in declaration order + ghx = oo.dr.ghx; ghu = oo.dr.ghu; + if options.order > 1 + ghxx = oo.dr.ghxx; ghxu = oo.dr.ghxu; ghuu = oo.dr.ghuu; ghs2 = oo.dr.ghs2; + end + if options.order > 2 + ghxxx = oo.dr.ghxxx; ghxxu = oo.dr.ghxxu; ghxuu = oo.dr.ghxuu; ghxss = oo.dr.ghxss; ghuuu = oo.dr.ghuuu; ghuss = oo.dr.ghuss; + end +end +Yss = ys(oo.dr.order_var); %steady state of model variables in DR order + +%% out = [vec(Sigma_e);vec(ghx);vec(ghu);vec(ghxx);vec(ghxu);vec(ghuu);vec(ghs2);vec(ghxxx);vec(ghxxu);vec(ghxuu);vec(ghuuu);vec(ghxss);vec(ghuss)] +if strcmp(outputflag,'perturbation_solution') + out = [Sigma_e(:); ghx(:); ghu(:)]; + if options.order > 1 + out = [out; ghxx(:); ghxu(:); ghuu(:); ghs2(:);]; + end + if options.order > 2 + out = [out; ghxxx(:); ghxxu(:); ghxuu(:); ghuuu(:); ghxss(:); ghuss(:)]; + end +end + +%% out = [Yss; vec(g1); vec(g2); vec(g3)]; of all endogenous variables, in DR order +if strcmp(outputflag,'dynamic_model') + [I,~] = find(M.lead_lag_incidence'); %I is used to evaluate dynamic model files + if options.order == 1 + [~, g1] = feval([M.fname,'.dynamic'], ys(I), oo.exo_steady_state', M.params, ys, 1); + out = [Yss; g1(:)]; + elseif options.order == 2 + [~, g1, g2] = feval([M.fname,'.dynamic'], ys(I), oo.exo_steady_state', M.params, ys, 1); + out = [Yss; g1(:); g2(:)]; + elseif options.order == 3 + [~, g1, g2, g3] = feval([M.fname,'.dynamic'], ys(I), oo.exo_steady_state', M.params, ys, 1); + g3 = unfold_g3(g3, length(ys(I))+M.exo_nbr); + out = [Yss; g1(:); g2(:); g3(:)]; + end +end + +%% out = [Yss; vec(KalmanA); dyn_vech(KalmanB*Sigma_e*KalmanB')]; in DR order, where A and B are Kalman transition matrices +if strcmp(outputflag,'Kalman_Transition') + if options.order == 1 + KalmanA = zeros(M.endo_nbr,M.endo_nbr); + KalmanA(:,M.nstatic+(1:M.nspred)) = ghx; + Om = ghu*Sigma_e*transpose(ghu); + out = [Yss; KalmanA(:); dyn_vech(Om)]; + else + error('''get_perturbation_params_derivs_numerical_objective.m'': Kalman_Transition works only at order=1'); + end +end diff --git a/matlab/get_variables_and_parameters_in_equation.m b/matlab/get_variables_and_parameters_in_equation.m index babd9e0d7..b4ed92a2c 100644 --- a/matlab/get_variables_and_parameters_in_equation.m +++ b/matlab/get_variables_and_parameters_in_equation.m @@ -8,7 +8,7 @@ function [pnames, enames, xnames, pid, eid, xid] = get_variables_and_parameters_ % - DynareModel [struct] Structure describing the current model (M_). % % OUTPUTS -% - pnames [cell] Cell of row char arrays (p elements), names of the parameters. +% - pnames [cell] Cell of row char arrays (p elements), names of the parameters. % - enames [cell] Cell of row char arrays (n elements), names of the endogenous variables. % - xnames [cell] Cell of row char arrays (m elements), names of the exogenous variables. % - pid [Integer] p*1 vector of indices in M_.param_names for the listed parameters in params. diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m index 340c795da..a5fca4e23 100644 --- a/matlab/global_initialization.m +++ b/matlab/global_initialization.m @@ -93,6 +93,13 @@ oo_.exo_steady_state = []; oo_.exo_det_steady_state = []; oo_.exo_det_simul = []; +oo_.gui.ran_estimation = false; +oo_.gui.ran_stoch_simul = false; +oo_.gui.ran_calib_smoother = false; +oo_.gui.ran_perfect_foresight = false; +oo_.gui.ran_shock_decomposition = false; +oo_.gui.ran_realtime_shock_decomposition = false; + M_.params = []; M_.endo_histval = []; M_.exo_histval = []; @@ -117,6 +124,8 @@ M_.osr.param_bounds=[]; M_.osr.variable_weights=[]; M_.osr.variable_indices =[]; +M_.instr_id=[]; + % Set default options_ but keep global_init_file field if defined in the driver. if isstruct(options_) && isfield(options_, 'global_init_file') global_init_file = options_.global_init_file; @@ -141,7 +150,15 @@ set_dynare_seed('default'); % Load user configuration file. if isfield(options_, 'global_init_file') - run(options_.global_init_file); + if isfile(options_.global_init_file) + try + run(options_.global_init_file); + catch + error('Cannot evaluate global initialization file (%s)', options_.global_init_file) + end + else + error('Cannot find global initialization file (%s).', options_.global_init_file) + end end end diff --git a/matlab/graph_decomp.m b/matlab/graph_decomp.m index ea3e1ebe4..5bf318bc8 100644 --- a/matlab/graph_decomp.m +++ b/matlab/graph_decomp.m @@ -50,6 +50,13 @@ if ~isempty(opts_decomp.type) fig_mode1 = ['_' fig_mode]; fig_mode = [fig_mode '_']; end + +if isfield(opts_decomp,'init_cond_decomp') + init_cond_decomp = opts_decomp.init_cond_decomp ; +else + init_cond_decomp = 0; +end + fig_name_long = opts_decomp.fig_name; use_shock_groups = DynareOptions.plot_shock_decomp.use_shock_groups; @@ -96,10 +103,16 @@ if DynareOptions.TeX && any(strcmp('eps',cellstr(DynareOptions.plot_shock_decomp fprintf(fidTeX,' \n'); end -if opts_decomp.vintage && opts_decomp.realtime>1 - preamble_txt = 'Shock decomposition'; +if init_cond_decomp + preamble_txt = 'Initial condition decomposition'; + preamble_figname = '_initval_decomposition_'; else - preamble_txt = 'Historical shock decomposition'; + preamble_figname = '_shock_decomposition_'; + if opts_decomp.vintage && opts_decomp.realtime>1 + preamble_txt = 'Shock decomposition'; + else + preamble_txt = 'Historical shock decomposition'; + end end if ~(screen_shocks && comp_nbr>18) @@ -135,6 +148,11 @@ for j=1:nvar ax=axes('Position',[0.1 0.1 0.6 0.8],'box','on'); % plot(ax,x(2:end),z1(end,:),'k-','LineWidth',2) % axis(ax,[xmin xmax ymin ymax]); + if strcmp('aoa',DynareOptions.plot_shock_decomp.type) + bgap = 0.15; + else + bgap = 0; + end hold on; for i=1:gend i_1 = i-1; @@ -143,10 +161,10 @@ for j=1:nvar for k = 1:comp_nbr zz = z1(k,i); if zz > 0 - fill([x(i) x(i) x(i+1) x(i+1)]+(1/freq/2),[yp yp+zz yp+zz yp],k); + fill([x(i)+bgap x(i)+bgap x(i+1)-bgap x(i+1)-bgap]+(1/freq/2),[yp yp+zz yp+zz yp],k); yp = yp+zz; else - fill([x(i) x(i) x(i+1) x(i+1)]+(1/freq/2),[ym ym+zz ym+zz ym],k); + fill([x(i)+bgap x(i)+bgap x(i+1)-bgap x(i+1)-bgap]+(1/freq/2),[ym ym+zz ym+zz ym],k); ym = ym+zz; end hold on; @@ -200,13 +218,14 @@ for j=1:nvar mydata.first_obs = DynareOptions.first_obs; mydata.nobs = DynareOptions.nobs; mydata.plot_shock_decomp.zfull = DynareOptions.plot_shock_decomp.zfull(i_var(j),:,:); - mydata.endo_names = endo_names{i_var(j)}; - mydata.endo_names_tex = DynareModel.endo_names_tex{i_var(j)}; + mydata.endo_names = endo_names(i_var(j)); + mydata.endo_names_tex = DynareModel.endo_names_tex(i_var(j)); + mydata.exo_names = DynareModel.exo_names; if ~isempty(mydata.shock_group.shocks) c = uicontextmenu; hl.UIContextMenu=c; browse_menu = uimenu(c,'Label','Browse group'); - expand_menu = uimenu(c,'Label','Expand group','Callback',['expand_group(''' mydata.plot_shock_decomp.use_shock_groups ''',''' deblank(mydata.plot_shock_decomp.orig_varlist{j}) ''',' int2str(i) ')']); + expand_menu = uimenu(c,'Label','Expand group','Callback',['expand_group(''' mydata.plot_shock_decomp.use_shock_groups ''',''' mydata.plot_shock_decomp.orig_varlist{j} ''',' int2str(i) ')']); set(expand_menu,'UserData',mydata,'Tag',['group' int2str(i)]); for jmember = mydata.shock_group.shocks uimenu('parent',browse_menu,'Label',char(jmember)) @@ -222,21 +241,23 @@ for j=1:nvar end hold off if ~DynareOptions.plot_shock_decomp.expand - - dyn_saveas(fhandle,[GraphDirectoryName, filesep, DynareModel.fname,'_shock_decomposition_',endo_names{i_var(j)},fig_mode1,fig_name],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); + + dyn_saveas(fhandle,[GraphDirectoryName, filesep, DynareModel.fname,preamble_figname,endo_names{i_var(j)},fig_mode1,fig_name],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); if DynareOptions.TeX && any(strcmp('eps',cellstr(DynareOptions.plot_shock_decomp.graph_format))) fprintf(fidTeX,'\\begin{figure}[H]\n'); fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[width=0.8\\textwidth]{%s/graphs/%s_shock_decomposition_%s}\n',DynareModel.fname,DynareModel.fname,[endo_names{i_var(j)} fig_mode1 fig_name]); + fprintf(fidTeX,'\\includegraphics[width=0.8\\textwidth]{%s/graphs/%s%s}\n',DynareModel.fname,DynareModel.fname,[preamble_figname endo_names{i_var(j)} fig_mode1 fig_name]); fprintf(fidTeX,'\\label{Fig:shock_decomp:%s}\n',[fig_mode endo_names{i_var(j)} fig_name]); fprintf(fidTeX,['\\caption{' preamble_txt fig_name_long strrep(fig_mode1, '_', ' ') ': $ %s $.}\n'],DynareModel.endo_names_tex{i_var(j)}); fprintf(fidTeX,'\\end{figure}\n'); fprintf(fidTeX,' \n'); end else - dyn_saveas(fhandle,[DynareOptions.plot_shock_decomp.filepath, filesep, DynareModel.fname,'_shock_decomposition_',endo_names{i_var(j)},fig_mode1,fig_name],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); - + if ~isempty(DynareOptions.plot_shock_decomp.filepath) + dyn_saveas(fhandle,[DynareOptions.plot_shock_decomp.filepath, filesep, DynareModel.fname,preamble_figname,endo_names{i_var(j)},fig_mode1,fig_name],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); + end end + end %% write LaTeX-Footer diff --git a/matlab/graph_decomp_detail.m b/matlab/graph_decomp_detail.m index d20997640..aa12fe7e3 100644 --- a/matlab/graph_decomp_detail.m +++ b/matlab/graph_decomp_detail.m @@ -24,7 +24,7 @@ function []=graph_decomp_detail(z,shock_names,endo_names,i_var,initial_date,Dyna % 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. -% +%xf % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . @@ -36,6 +36,7 @@ fig_mode=''; fig_mode1=''; % fig_name=''; % screen_shocks=0; +initval = DynareOptions.plot_shock_decomp.initval; use_shock_groups = DynareOptions.plot_shock_decomp.use_shock_groups; if use_shock_groups shock_groups = DynareModel.shock_groups.(use_shock_groups); @@ -53,6 +54,13 @@ if ~isempty(opts_decomp.type) fig_mode1 = ['_' fig_mode]; fig_mode = [fig_mode '_']; end + +if isfield(opts_decomp,'init_cond_decomp') + init_cond_decomp = opts_decomp.init_cond_decomp ; +else + init_cond_decomp = 0; +end +max_nrows = opts_decomp.max_nrows; screen_shocks = opts_decomp.screen_shocks; if ~isempty(DynareOptions.plot_shock_decomp.use_shock_groups) || comp_nbr<=18 screen_shocks=0; @@ -117,18 +125,28 @@ if DynareOptions.TeX && any(strcmp('eps',cellstr(DynareOptions.plot_shock_decomp fprintf(fidTeX,' \n'); end -if opts_decomp.vintage && opts_decomp.realtime>1 - preamble_txt = 'Shock decomposition'; +if init_cond_decomp + preamble_txt = 'Initial condition decomposition'; + preamble_figname = '_initval_decomposition_'; else - preamble_txt = 'Historical shock decomposition'; + preamble_figname = '_shock_decomposition_'; + if opts_decomp.vintage && opts_decomp.realtime>1 + preamble_txt = 'Shock decomposition'; + else + preamble_txt = 'Historical shock decomposition'; + end end ncol=3; nrow=ceil(comp_nbr/ncol); ntotrow = nrow; -nrow = min(ntotrow, 6); +nrow = min(ntotrow, max_nrows); nfigs = ceil(ntotrow/nrow); -labels = char(char(shock_names),'Initial values'); +if initval + labels = char(char(shock_names),'All shocks'); +else + labels = char(char(shock_names),'Initial values'); +end if ~(screen_shocks && comp_nbr>18) screen_shocks=0; end @@ -138,7 +156,11 @@ for j=1:nvar z1 = squeeze(z(i_var(j),:,:)); if screen_shocks, [~, isort] = sort(mean(abs(z1(1:end-2,:)')), 'descend'); - labels = char(char(shock_names(isort(1:16))),'Others', 'Initial values'); + if initval + labels = char(char(shock_names(isort(1:16))),'Others', 'All shocks'); + else + labels = char(char(shock_names(isort(1:16))),'Others', 'Initial values'); + end zres = sum(z1(isort(17:end),:),1); z1 = [z1(isort(1:16),:); zres; z1(comp_nbr0:end,:)]; comp_nbr=18; @@ -169,19 +191,19 @@ for j=1:nvar hax = subplot(nrow,ncol,i); set(gca,'box','on') hbar = bar(x(2:end),(zz.*ipos)','stacked','FaceColor','flat'); if ~isoctave && ~matlab_ver_less_than('9.3.0') - % make bar obey colormap under MATLAB R2017b - for k = 1:2 - hbar(k).CData = k; - end + % make bar obey colormap under MATLAB R2017b + for k = 1:2 + hbar(k).CData = k; + end end set(hbar,'edgecolor','flat'); hold on, hbar = bar(x(2:end),(zz.*ineg)','stacked','FaceColor','flat'); if ~isoctave && ~matlab_ver_less_than('9.3.0') - % make bar obey colormap under MATLAB R2017b - for k = 1:2 - hbar(k).CData = k; - end + % make bar obey colormap under MATLAB R2017b + for k = 1:2 + hbar(k).CData = k; + end end set(hbar,'edgecolor','flat'); title(deblank(labels(ic,:)),'Interpreter','none'), @@ -202,13 +224,14 @@ for j=1:nvar mydata.first_obs = DynareOptions.first_obs; mydata.nobs = DynareOptions.nobs; mydata.plot_shock_decomp.zfull = DynareOptions.plot_shock_decomp.zfull(i_var(j),:,:); - mydata.endo_names = endo_names{i_var(j)}; - mydata.endo_names_tex = DynareModel.endo_names_tex{i_var(j)}; + mydata.endo_names = endo_names(i_var(j)); + mydata.endo_names_tex = DynareModel.endo_names_tex(i_var(j)); + mydata.exo_names = DynareModel.exo_names; if ~isempty(mydata.shock_group.shocks) c = uicontextmenu; hax.UIContextMenu=c; browse_menu = uimenu(c,'Label','Browse group'); - expand_menu = uimenu(c,'Label','Expand group','Callback',['expand_group(''' mydata.plot_shock_decomp.use_shock_groups ''',''' deblank(mydata.plot_shock_decomp.orig_varlist{j}) ''',' int2str(ic) ')']); + expand_menu = uimenu(c,'Label','Expand group','Callback',['expand_group(''' mydata.plot_shock_decomp.use_shock_groups ''',''' mydata.plot_shock_decomp.orig_varlist{j} ''',' int2str(ic) ')']); set(expand_menu,'UserData',mydata,'Tag',['group' int2str(ic)]); for jmember = mydata.shock_group.shocks uimenu('parent',browse_menu,'Label',char(jmember)) @@ -238,7 +261,7 @@ for j=1:nvar hold on x1 = x1 + width; end - colormap([0.15 0.15 0.15;0.85 0.85 0.85]), + colormap([0.15 0.15 0.15;0.85 0.85 0.85]), if nfigs>1 @@ -248,19 +271,20 @@ for j=1:nvar end if ~DynareOptions.plot_shock_decomp.expand dyn_saveas(fhandle,[GraphDirectoryName, filesep, DynareModel.fname, ... - '_shock_decomposition_', endo_names{i_var(j)}, fig_mode1,fig_name suffix],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); + preamble_figname, endo_names{i_var(j)}, fig_mode1,fig_name suffix],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); if DynareOptions.TeX && any(strcmp('eps',cellstr(DynareOptions.plot_shock_decomp.graph_format))) fprintf(fidTeX,'\\begin{figure}[H]\n'); fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[width=0.8\\textwidth]{%s/graphs/%s_shock_decomposition_%s}\n',DynareModel.fname,DynareModel.fname,[endo_names{i_var(j)} fig_mode1 fig_name suffix]); + fprintf(fidTeX,'\\includegraphics[width=0.8\\textwidth]{%s/graphs/%s%s}\n',DynareModel.fname,DynareModel.fname,[preamble_figname endo_names{i_var(j)} fig_mode1 fig_name suffix]); fprintf(fidTeX,'\\label{Fig:shock_decomp_detail:%s}\n',[fig_mode endo_names{i_var(j)} fig_name suffix]); fprintf(fidTeX,['\\caption{' preamble_txt fig_name_long strrep(fig_mode1, '_', ' ') ': $ %s $ (detail).}\n'], DynareModel.endo_names_tex{i_var(j)}); fprintf(fidTeX,'\\end{figure}\n'); fprintf(fidTeX,' \n'); end else - dyn_saveas(fhandle,[DynareOptions.plot_shock_decomp.filepath, filesep, DynareModel.fname,'_shock_decomposition_',endo_names{i_var(j)},fig_mode1,fig_name suffix],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); - + if ~isempty(DynareOptions.plot_shock_decomp.filepath) + dyn_saveas(fhandle,[DynareOptions.plot_shock_decomp.filepath, filesep, DynareModel.fname,preamble_figname,endo_names{i_var(j)},fig_mode1,fig_name suffix],DynareOptions.plot_shock_decomp.nodisplay,DynareOptions.plot_shock_decomp.graph_format); + end end end end diff --git a/matlab/gsa/pick.m b/matlab/gsa/pick.m index ed50f60cf..2f84d9892 100644 --- a/matlab/gsa/pick.m +++ b/matlab/gsa/pick.m @@ -2,7 +2,7 @@ function pick % % Copyright (C) 2001-2017 European Commission % Copyright (C) 2017 DynareTeam - + % This file is part of GLUEWIN % GLUEWIN is a MATLAB code designed for analysing the output % of Monte Carlo runs when empirical observations of the model output are available diff --git a/matlab/gsa/redform_map.m b/matlab/gsa/redform_map.m index 4e5923ceb..e790cf58f 100644 --- a/matlab/gsa/redform_map.m +++ b/matlab/gsa/redform_map.m @@ -239,7 +239,7 @@ for j = 1:length(anamendo) icheck=[]; end if isempty(icheck) - if length(iy)<=10 + if length(iy)<=10 if isempty(iy) disp(['There are NO MC samples in the desired range [' num2str(threshold) ']!']) else @@ -298,7 +298,7 @@ for j = 1:length(anamendo) end else - disp(['This entry in the shock matrix is CONSTANT = ' num2str(mean(y0),3)]) + disp(['This entry in the shock matrix is CONSTANT = ' num2str(mean(y0),3)]) end end end @@ -396,7 +396,7 @@ for j = 1:length(anamendo) icheck = []; end if isempty(icheck) - if length(iy)<=10 + if length(iy)<=10 if isempty(iy) disp(['There are NO MC samples in the desired range [' num2str(threshold) ']!']) else @@ -454,7 +454,7 @@ for j = 1:length(anamendo) end else - disp(['This entry in the transition matrix is CONSTANT = ' num2str(mean(y0),3)]) + disp(['This entry in the transition matrix is CONSTANT = ' num2str(mean(y0),3)]) end end end diff --git a/matlab/ident_bruteforce.m b/matlab/ident_bruteforce.m index 70ff5e838..50396a232 100644 --- a/matlab/ident_bruteforce.m +++ b/matlab/ident_bruteforce.m @@ -17,8 +17,8 @@ function [pars, cosnJ] = ident_bruteforce(J, max_dim_cova_group, TeX, name_tex, % pars : cell array with group of params for each column of J for 1 to n % cosnJ : cosn of each column with the selected group of columns % ------------------------------------------------------------------------- -% This function is called by -% * identification_analysis.m +% This function is called by +% * identification_analysis.m % ========================================================================= % Copyright (C) 2009-2019 Dynare Team % diff --git a/matlab/identification_analysis.m b/matlab/identification_analysis.m index 9f72aaafb..75d429182 100644 --- a/matlab/identification_analysis.m +++ b/matlab/identification_analysis.m @@ -1,12 +1,15 @@ -function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_lre, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init) -% [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_lre, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init) +function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_dynamic, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init) +% [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_dynamic, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init) % ------------------------------------------------------------------------- % This function wraps all identification analysis, i.e. it % (1) wraps functions for the theoretical identification analysis based on moments (Iskrev, 2010), % spectrum (Qu and Tkachenko, 2012), minimal system (Komunjer and Ng, 2011), information matrix, -% reduced-form solution and linear rational expectation model (Ratto and Iskrev, 2011). +% reduced-form solution and dynamic model derivatives (Ratto and Iskrev, 2011). % (2) computes the identification strength based on moments (Ratto and Iskrev, 2011) % (3) checks which parameters are involved. +% If options_ident.order>1, then the identification analysis is based on +% Mutschler (2015), i.e. the pruned state space system and the corresponding +% moments, spectrum, reduced-form solution and dynamic model derivatives % ========================================================================= % INPUTS % * params [mc_sample_nbr by totparam_nbr] @@ -15,8 +18,8 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide % index of model parameters for which identification is checked % * indpstderr [stderrparam_nbr by 1] % index of stderr parameters for which identification is checked -% * indpcorr [corrparam_nbr by 1] -% index of corr parmeters for which identification is checked +% * indpcorr [corrparam_nbr by 2] +% matrix of corr parmeters for which identification is checked % * options_ident [structure] % identification options % * dataset_info [structure] @@ -25,25 +28,23 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide % 1: prior exists. Identification is checked for stderr, corr and model parameters as declared in estimated_params block % 0: prior does not exist. Identification is checked for all stderr and model parameters, but no corr parameters % * init [integer] -% flag for initialization of persistent vars. This is needed if one may want to re-initialize persistent -% variables even if they are not empty, e.g. by making more calls to identification in the same dynare mod file +% flag for initialization of persistent vars. This is needed if one may want to make more calls to identification in the same mod file % ------------------------------------------------------------------------- % OUTPUTS % * ide_moments [structure] -% identification results using theoretical moments (Iskrev, 2010) +% identification results using theoretical moments (Iskrev, 2010; Mutschler, 2015) % * ide_spectrum [structure] -% identification results using spectrum (Qu and Tkachenko, 2012) +% identification results using spectrum (Qu and Tkachenko, 2012; Mutschler, 2015) % * ide_minimal [structure] -% identification results using minimal system (Komunjer and Ng, 2011) +% identification results using theoretical mean and minimal system (Komunjer and Ng, 2011) % * ide_hess [structure] % identification results using asymptotic Hessian (Ratto and Iskrev, 2011) % * ide_reducedform [structure] -% identification results using reduced form solution (Ratto and Iskrev, 2011) -% * ide_lre [structure] -% identification results using linear rational expectations model, -% i.e. steady state and Jacobian of dynamic model, (Ratto and Iskrev, 2011) +% identification results using steady state and reduced form solution (Ratto and Iskrev, 2011) +% * ide_dynamic [structure] +% identification results using steady state and dynamic model derivatives (Ratto and Iskrev, 2011) % * derivatives_info [structure] -% info about derivatives, used in dsge_likelihood.m +% info about first-order perturbation derivatives, used in dsge_likelihood.m % * info [integer] % output from dynare_resolve % * options_ident [structure] @@ -57,7 +58,6 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide % * dseries % * dsge_likelihood.m % * dyn_vech -% * dynare_resolve % * ident_bruteforce % * identification_checks % * identification_checks_via_subsets @@ -65,12 +65,13 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide % * get_identification_jacobians (previously getJJ) % * matlab_ver_less_than % * prior_bounds +% * resol % * set_all_parameters % * simulated_moment_uncertainty % * stoch_simul % * vec % ========================================================================= -% Copyright (C) 2008-2019 Dynare Team +% Copyright (C) 2008-2020 Dynare Team % % This file is part of Dynare. % @@ -89,23 +90,24 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide % ========================================================================= global oo_ M_ options_ bayestopt_ estim_params_ -persistent ind_J ind_G ind_D ind_dTAU ind_dLRE -% persistence is necessary, because in a MC loop the numerical threshold used may provide vectors of different length, leading to crashes in MC loops +persistent ind_dMOMENTS ind_dREDUCEDFORM ind_dDYNAMIC +% persistent indices are necessary, because in a MC loop the numerical threshold +% used may provide vectors of different length, leading to crashes in MC loops %initialize output structures -ide_hess = struct(); %asymptotic/simulated information matrix -ide_reducedform = struct(); %reduced form solution -ide_lre = struct(); %linear rational expectation model -ide_moments = struct(); %Iskrev (2010)'s J -ide_spectrum = struct(); %Qu and Tkachenko (2012)'s G -ide_minimal = struct(); %Komunjer and Ng (2011)'s D -derivatives_info = struct(); %storage for Jacobians used in dsge_likelihood.m for (analytical or simulated) asymptotic Gradient and Hession of likelihood +ide_hess = struct(); %Identification structure based on asymptotic/simulated information matrix +ide_reducedform = struct(); %Identification structure based on steady state and reduced form solution +ide_dynamic = struct(); %Identification structure based on steady state and dynamic model derivatives +ide_moments = struct(); %Identification structure based on first two moments (Iskrev, 2010; Mutschler, 2015) +ide_spectrum = struct(); %Identification structure based on Gram matrix of Jacobian of spectral density plus Gram matrix of Jacobian of steady state (Qu and Tkachenko, 2012; Mutschler, 2015) +ide_minimal = struct(); %Identification structure based on mean and minimal system (Komunjer and Ng, 2011) +derivatives_info = struct(); %storage for first-order perturbation Jacobians used in dsge_likelihood.m totparam_nbr = length(params); %number of all parameters to be checked modparam_nbr = length(indpmodel); %number of model parameters to be checked stderrparam_nbr = length(indpstderr); %number of stderr parameters to be checked corrparam_nbr = size(indpcorr,1); %number of stderr parameters to be checked -indvobs = bayestopt_.mf2; % index of observable variables +indvobs = bayestopt_.mf2; %index of observable variables if ~isempty(estim_params_) %estimated_params block is available, so we are able to use set_all_parameters.m @@ -113,163 +115,139 @@ if ~isempty(estim_params_) end %get options (see dynare_identification.m for description of options) -nlags = options_ident.ar; -advanced = options_ident.advanced; -replic = options_ident.replic; -periods = options_ident.periods; -max_dim_cova_group = options_ident.max_dim_cova_group; -normalize_jacobians = options_ident.normalize_jacobians; -tol_deriv = options_ident.tol_deriv; -tol_rank = options_ident.tol_rank; -tol_sv = options_ident.tol_sv; -no_identification_strength = options_ident.no_identification_strength; -no_identification_reducedform = options_ident.no_identification_reducedform; -no_identification_moments = options_ident.no_identification_moments; -no_identification_minimal = options_ident.no_identification_minimal; -no_identification_spectrum = options_ident.no_identification_spectrum; -checks_via_subsets = options_ident.checks_via_subsets; +order = options_ident.order; +nlags = options_ident.ar; +advanced = options_ident.advanced; +replic = options_ident.replic; +periods = options_ident.periods; +max_dim_cova_group = options_ident.max_dim_cova_group; +normalize_jacobians = options_ident.normalize_jacobians; +checks_via_subsets = options_ident.checks_via_subsets; +tol_deriv = options_ident.tol_deriv; +tol_rank = options_ident.tol_rank; +tol_sv = options_ident.tol_sv; +no_identification_strength = options_ident.no_identification_strength; +no_identification_reducedform = options_ident.no_identification_reducedform; +no_identification_moments = options_ident.no_identification_moments; +no_identification_minimal = options_ident.no_identification_minimal; +no_identification_spectrum = options_ident.no_identification_spectrum; -[I,~] = find(M_.lead_lag_incidence'); %I is used to select nonzero columns of the Jacobian of endogenous variables in dynamic model files - -%Compute linear approximation and matrices A and B of the transition equation for all endogenous variables in DR order -[A, B, ~, info, M_, options_, oo_] = dynare_resolve(M_,options_,oo_); +%Compute linear approximation and fill dr structure +[oo_.dr,info,M_,options_,oo_] = resol(0,M_,options_,oo_); if info(1) == 0 %no errors in solution - oo0 = oo_; %store oo_ structure - y0 = oo_.dr.ys(oo_.dr.order_var); %steady state in DR order - yy0 = oo_.dr.ys(I); %steady state of dynamic (endogenous and auxiliary variables) in DR order - ex0 = oo_.exo_steady_state'; %steady state of exogenous variables in declaration order - param0 = M_.params; %parameter values at which to evaluate dynamic, static and param_derivs files - Sigma_e0 = M_.Sigma_e; %store covariance matrix of exogenous shocks - - %compute vectorized reduced-form solution in DR order - tau = [y0; vec(A); dyn_vech(B*Sigma_e0*B')]; - - %compute vectorized linear rational expectations model in DR order - [~, g1 ] = feval([M_.fname,'.dynamic'], yy0, repmat(ex0, M_.maximum_exo_lag+M_.maximum_exo_lead+1), param0, oo_.dr.ys, 1); - %g1 is [endo_nbr by (dynamicvar_nbr+exo_nbr)] first derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. df/d[yy0;ex0], in DR order - lre = [y0; vec(g1)]; %add steady state in DR order and vectorize - - %Compute Jacobians for identification analysis either analytically or numerically dependent on analytic_derivation_mode in options_ident - [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params_, M_, oo0, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs); - if isempty(D) + % Compute parameter Jacobians for identification analysis + [MEAN, dMEAN, REDUCEDFORM, dREDUCEDFORM, DYNAMIC, dDYNAMIC, MOMENTS, dMOMENTS, dSPECTRUM, dSPECTRUM_NO_MEAN, dMINIMAL, derivatives_info] = get_identification_jacobians(estim_params_, M_, oo_, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs); + if isempty(dMINIMAL) % Komunjer and Ng is not computed if (1) minimality conditions are not fullfilled or (2) there are more shocks and measurement errors than observables, so we need to reset options no_identification_minimal = 1; options_ident.no_identification_minimal = 1; end - - %store derivatives for use in dsge_likelihood.m - derivatives_info.DT = dA; - derivatives_info.DOm = dOm; - derivatives_info.DYss = dYss; - + if init %check stationarity if ~no_identification_moments - ind_J = (find(max(abs(J'),[],1) > tol_deriv)); %index for non-zero derivatives - if isempty(ind_J) && any(any(isnan(J))) - error('There are NaN in the JJ matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.' ) + ind_dMOMENTS = (find(max(abs(dMOMENTS'),[],1) > tol_deriv)); %index for non-zero rows + if isempty(ind_dMOMENTS) && any(any(isnan(dMOMENTS))) + error('There are NaN in the dMOMENTS matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.' ) end if any(any(isnan(MOMENTS))) error('There are NaN''s in the theoretical moments: make sure that for non-stationary models stationary transformations of non-stationary observables are used for checking identification. [TIP: use first differences].') end end if ~no_identification_spectrum - ind_G = (find(max(abs(G'),[],1) > tol_deriv)); %index for non-zero derivatives - if isempty(ind_G) && any(any(isnan(G))) - warning_QuTkachenko = 'WARNING: There are NaN in Qu and Tkachenko (2012)''s G matrix. Please check whether your model has units roots (diffuse_filter=1 does not work yet for the G matrix).\n'; - warning_QuTkachenko = [warning_QuTkachenko ' Skip identification analysis based on spectrum.\n']; - fprintf(warning_QuTkachenko); - %reset options to neither display nor plot Qu and Tkachenko's G anymore + ind_dSPECTRUM = (find(max(abs(dSPECTRUM'),[],1) > tol_deriv)); %index for non-zero rows + if isempty(ind_dSPECTRUM) && any(any(isnan(dSPECTRUM))) + warning_SPECTRUM = 'WARNING: There are NaN in the dSPECTRUM matrix. Please check whether your model has units roots and your forgot to set diffuse_filter=1.\n'; + warning_SPECTRUM = [warning_SPECTRUM ' Skip identification analysis based on spectrum.\n']; + fprintf(warning_SPECTRUM); + %reset options to neither display nor plot dSPECTRUM anymore no_identification_spectrum = 1; options_ident.no_identification_spectrum = 1; end end if ~no_identification_minimal - ind_D = (find(max(abs(D'),[],1) > tol_deriv)); %index for non-zero derivatives - if isempty(ind_D) && any(any(isnan(D))) - warning_KomunjerNg = 'WARNING: There are NaN in Komunjer and Ng (2011)''s D matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.\n'; - warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal system.\n']; - fprintf(warning_KomunjerNg); - %reset options to neither display nor plot Komunjer and Ng's D anymore + ind_dMINIMAL = (find(max(abs(dMINIMAL'),[],1) > tol_deriv)); %index for non-zero rows + if isempty(ind_dMINIMAL) && any(any(isnan(dMINIMAL))) + warning_MINIMAL = 'WARNING: There are NaN in the dMINIMAL matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.\n'; + warning_MINIMAL = [warning_MINIMAL ' Skip identification analysis based on minimal system.\n']; + fprintf(warning_MINIMAL); + %reset options to neither display nor plot dMINIMAL anymore no_identification_minimal = 1; options_ident.no_identification_minimal = 1; end end if no_identification_moments && no_identification_minimal && no_identification_spectrum - %error if all three criteria fail + %display error if all three criteria fail error('identification_analyis: Stationarity condition(s) failed and/or diffuse_filter option missing'); end - + % Check order conditions if ~no_identification_moments %check order condition of Iskrev (2010) - while length(ind_J) < totparam_nbr && nlags < 10 + while length(ind_dMOMENTS) < totparam_nbr && nlags < 10 %Try to add lags to autocovariogram if order condition fails disp('The number of moments with non-zero derivative is smaller than the number of parameters') disp(['Try increasing ar = ', int2str(nlags+1)]) nlags = nlags + 1; - options_ident.no_identification_minimal = 1; %do not recompute D - options_ident.no_identification_spectrum = 1; %do not recompute G + options_ident.no_identification_minimal = 1; %do not recompute dMINIMAL + options_ident.no_identification_spectrum = 1; %do not recompute dSPECTRUM options_ident.ar = nlags; %store new lag number options_.ar = nlags; %store new lag number - [J, ~, ~, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params_, M_, oo0, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs); - ind_J = (find(max(abs(J'),[],1) > tol_deriv)); %new index with non-zero derivatives - %store derivatives for use in dsge_likelihood.m - derivatives_info.DT = dA; - derivatives_info.DOm = dOm; - derivatives_info.DYss = dYss; + [~, ~, ~, ~, ~, ~, MOMENTS, dMOMENTS, ~, ~, ~, ~] = get_identification_jacobians(estim_params_, M_, oo_, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs); + + ind_dMOMENTS = (find(max(abs(dMOMENTS'),[],1) > tol_deriv)); %new index with non-zero rows end - options_ident.no_identification_minimal = no_identification_minimal; % reset option to original choice - options_ident.no_identification_spectrum = no_identification_spectrum; % reset option to original choice - if length(ind_J) < totparam_nbr - warning_Iskrev = 'WARNING: Order condition for Iskrev (2010) failed: There are not enough moments and too many parameters.\n'; - warning_Iskrev = [warning_Iskrev ' The number of moments with non-zero derivative is smaller than the number of parameters up to 10 lags.\n']; - warning_Iskrev = [warning_Iskrev ' Either reduce the list of parameters, or further increase ar, or increase number of observables.\n']; - warning_Iskrev = [warning_Iskrev ' Skip identification analysis based on moments.\n']; - fprintf(warning_Iskrev); - %reset options to neither display nor plot Iskrev's J anymore + options_ident.no_identification_minimal = no_identification_minimal; % reset option to original setting + options_ident.no_identification_spectrum = no_identification_spectrum; % reset option to original setting + if length(ind_dMOMENTS) < totparam_nbr + warning_MOMENTS = 'WARNING: Order condition for dMOMENTS failed: There are not enough moments and too many parameters.\n'; + warning_MOMENTS = [warning_MOMENTS ' The number of moments with non-zero derivative is smaller than the number of parameters up to 10 lags.\n']; + warning_MOMENTS = [warning_MOMENTS ' Either reduce the list of parameters, or further increase ar, or increase number of observables.\n']; + warning_MOMENTS = [warning_MOMENTS ' Skip identification analysis based on moments.\n']; + fprintf(warning_MOMENTS); + %reset options to neither display nor plot dMOMENTS anymore no_identification_moments = 1; options_ident.no_identification_moments = 1; end end if ~no_identification_minimal - if length(ind_D) < size(D,2) - warning_KomunjerNg = 'WARNING: Order condition for Komunjer and Ng (2011) failed: There are too many parameters or too few observable variables.\n'; - warning_KomunjerNg = [warning_KomunjerNg ' The number of minimal system elements with non-zero derivative is smaller than the number of parameters.\n']; - warning_KomunjerNg = [warning_KomunjerNg ' Either reduce the list of parameters, or increase number of observables.\n']; - warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n']; - fprintf(warning_KomunjerNg); - %resest options to neither display nor plot Komunjer and Ng's D anymore + if length(ind_dMINIMAL) < size(dMINIMAL,2) + warning_MINIMAL = 'WARNING: Order condition for dMINIMAL failed: There are too many parameters or too few observable variables.\n'; + warning_MINIMAL = [warning_MINIMAL ' The number of minimal system elements with non-zero derivative is smaller than the number of parameters.\n']; + warning_MINIMAL = [warning_MINIMAL ' Either reduce the list of parameters, or increase number of observables.\n']; + warning_MINIMAL = [warning_MINIMAL ' Skip identification analysis based on minimal state space system.\n']; + fprintf(warning_MINIMAL); + %resest options to neither display nor plot dMINIMAL anymore no_identification_minimal = 1; options_ident.no_identification_minimal = 1; end end - %There is no order condition for Qu and Tkachenko's G + %Note that there is no order condition for dSPECTRUM, as the matrix is always of dimension totparam_nbr by totparam_nbr if no_identification_moments && no_identification_minimal && no_identification_spectrum %error if all three criteria fail error('identification_analyis: Order condition(s) failed'); end if ~no_identification_reducedform - ind_dTAU = (find(max(abs(dTAU'),[],1) > tol_deriv)); %index with non-zero derivatives + ind_dREDUCEDFORM = (find(max(abs(dREDUCEDFORM'),[],1) > tol_deriv)); %index with non-zero rows end - ind_dLRE = (find(max(abs(dLRE'),[],1) > tol_deriv)); %index with non-zero derivatives + ind_dDYNAMIC = (find(max(abs(dDYNAMIC'),[],1) > tol_deriv)); %index with non-zero rows end - - LRE = lre(ind_dLRE); - si_dLRE = (dLRE(ind_dLRE,:)); %focus only on non-zero derivatives + + DYNAMIC = DYNAMIC(ind_dDYNAMIC); %focus only on non-zero entries + si_dDYNAMIC = (dDYNAMIC(ind_dDYNAMIC,:)); %focus only on non-zero rows if ~no_identification_reducedform - TAU = tau(ind_dTAU); - si_dTAU = (dTAU(ind_dTAU,:)); %focus only on non-zero derivatives + REDUCEDFORM = REDUCEDFORM(ind_dREDUCEDFORM); %focus only on non-zero entries + si_dREDUCEDFORM = (dREDUCEDFORM(ind_dREDUCEDFORM,:)); %focus only on non-zero rows end - + if ~no_identification_moments - MOMENTS = MOMENTS(ind_J); - si_J = (J(ind_J,:)); %focus only on non-zero derivatives - %% compute identification strength based on moments + MOMENTS = MOMENTS(ind_dMOMENTS); %focus only on non-zero entries + si_dMOMENTS = (dMOMENTS(ind_dMOMENTS,:)); %focus only on non-zero derivatives +%% MOMENTS IDENTIFICATION STRENGTH ANALYSIS if ~no_identification_strength && init %only for initialization of persistent vars - ide_strength_J = NaN(1,totparam_nbr); %initialize - ide_strength_J_prior = NaN(1,totparam_nbr); %initialize + ide_strength_dMOMENTS = NaN(1,totparam_nbr); %initialize + ide_strength_dMOMENTS_prior = NaN(1,totparam_nbr); %initialize ide_uncert_unnormaliz = NaN(1,totparam_nbr); %initialize if prior_exist offset_prior = 0; @@ -289,13 +267,15 @@ if info(1) == 0 %no errors in solution else normaliz_prior_std = NaN(1,totparam_nbr); %no prior information available, do not normalize end - + try %try to compute asymptotic Hessian for identification strength analysis based on moments + if options_.order > 1 + error('IDENTIFICATION STRENGTH: Analytic computation of Hessian is not available for ''order>1''. Identification strength is based on simulated moment uncertainty'); + end % reset some options for faster computations options_.irf = 0; options_.noprint = 1; - options_.order = 1; options_.SpectralDensity.trigger = 0; options_.periods = periods+100; if options_.kalman_algo > 2 @@ -303,20 +283,16 @@ if info(1) == 0 %no errors in solution end analytic_derivation = options_.analytic_derivation; options_.analytic_derivation = -2; %this sets asy_Hess=1 in dsge_likelihood.m - [info, oo_, options_] = stoch_simul(M_, options_, oo_, options_.varobs); + [info, oo_, options_, M_] = stoch_simul(M_, options_, oo_, options_.varobs); dataset_ = dseries(oo_.endo_simul(options_.varobs_id,100+1:end)',dates('1Q1'), options_.varobs); %get information on moments derivatives_info.no_DLIK = 1; - bounds = prior_bounds(bayestopt_, options_.prior_trunc); %reset bounds as lb and ub must only be operational during mode-finding + bounds = prior_bounds(bayestopt_, options_.prior_trunc); %reset bounds as lb and ub must only be operational during mode-finding + %note that for order>1 we do not provide any information on DT,DYss,DOM in derivatives_info, such that dsge_likelihood creates an error. Therefore the computation will be based on simulated_moment_uncertainty for order>1. [fval, info, cost_flag, DLIK, AHess, ys, trend_coeff, M_, options_, bayestopt_, oo_] = dsge_likelihood(params', dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds, oo_, derivatives_info); %non-used output variables need to be set for octave for some reason %note that for the order of parameters in AHess we have: stderr parameters come first, corr parameters second, model parameters third. the order within these blocks corresponds to the order specified in the estimated_params block options_.analytic_derivation = analytic_derivation; %reset option AHess = -AHess; %take negative of hessian - if ischar(tol_rank) %if tolerance is specified as 'robust' - tol_rankAhess = max(size(AHess))*eps(norm(AHess)); - else - tol_rankAhess = tol_rank; - end - if min(eig(AHess))<-tol_rankAhess + if min(eig(AHess))<-tol_rank error('identification_analysis: Analytic Hessian is not positive semi-definite!') end ide_hess.AHess = AHess; %store asymptotic Hessian @@ -332,16 +308,23 @@ if info(1) == 0 %no errors in solution indok = find(max(ide_hess.indno,[],1)==0); ide_uncert_unnormaliz(indok) = sqrt(diag(inv(AHess(indok,indok))))'; ind1 = find(ide_hess.ind0); - cmm = si_J(:,ind1)*((AHess(ind1,ind1))\si_J(:,ind1)'); %covariance matrix of moments - temp1 = ((AHess(ind1,ind1))\si_dTAU(:,ind1)'); - diag_chh = sum(si_dTAU(:,ind1)'.*temp1)'; + cmm = si_dMOMENTS(:,ind1)*((AHess(ind1,ind1))\si_dMOMENTS(:,ind1)'); %covariance matrix of moments + temp1 = ((AHess(ind1,ind1))\si_dREDUCEDFORM(:,ind1)'); + diag_chh = sum(si_dREDUCEDFORM(:,ind1)'.*temp1)'; ind1 = ind1(ind1>stderrparam_nbr+corrparam_nbr); - clre = si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)*((AHess(ind1,ind1))\si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)'); - flag_score = 1; %this is only used for a title of a plot in plot_identification.m + cdynamic = si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)*((AHess(ind1,ind1))\si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)'); + flag_score = 1; %this is used for the title in plot_identification.m catch - %Asymptotic Hessian via simulation - replic = max([replic, length(ind_J)*3]); - cmm = simulated_moment_uncertainty(ind_J, periods, replic,options_,M_,oo_); %covariance matrix of moments + %Asymptotic Hessian via simulation + if options_.order > 1 + % reset some options for faster computations + options_.irf = 0; + options_.noprint = 1; + options_.SpectralDensity.trigger = 0; + options_.periods = periods+100; + end + replic = max([replic, length(ind_dMOMENTS)*3]); + cmm = simulated_moment_uncertainty(ind_dMOMENTS, periods, replic,options_,M_,oo_); %covariance matrix of moments sd = sqrt(diag(cmm)); cc = cmm./(sd*sd'); if isoctave || matlab_ver_less_than('8.3') @@ -353,7 +336,7 @@ if info(1) == 0 %no errors in solution [VV,DD,WW] = eig(cc); end id = find(diag(DD)>tol_deriv); - siTMP = si_J./repmat(sd,[1 totparam_nbr]); + siTMP = si_dMOMENTS./repmat(sd,[1 totparam_nbr]); MIM = (siTMP'*VV(:,id))*(DD(id,id)\(WW(:,id)'*siTMP)); clear siTMP; ide_hess.AHess = MIM; %store asymptotic hessian @@ -368,122 +351,123 @@ if info(1) == 0 %no errors in solution end indok = find(max(ide_hess.indno,[],1)==0); ind1 = find(ide_hess.ind0); - temp1 = ((MIM(ind1,ind1))\si_dTAU(:,ind1)'); - diag_chh = sum(si_dTAU(:,ind1)'.*temp1)'; + temp1 = ((MIM(ind1,ind1))\si_dREDUCEDFORM(:,ind1)'); + diag_chh = sum(si_dREDUCEDFORM(:,ind1)'.*temp1)'; ind1 = ind1(ind1>stderrparam_nbr+corrparam_nbr); - clre = si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)*((MIM(ind1,ind1))\si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)'); + cdynamic = si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)*((MIM(ind1,ind1))\si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)'); if ~isempty(indok) ide_uncert_unnormaliz(indok) = (sqrt(diag(inv(tildaM(indok,indok))))./deltaM(indok))'; %sqrt(diag(inv(MIM(indok,indok))))'; end - flag_score = 0; %this is only used for a title of a plot + flag_score = 0; %this is used for the title in plot_identification.m end % end of computing sample information matrix for identification strength measure - - ide_strength_J(indok) = (1./(ide_uncert_unnormaliz(indok)'./abs(params(indok)'))); %this is s_i in Ratto and Iskrev (2011, p.13) - ide_strength_J_prior(indok) = (1./(ide_uncert_unnormaliz(indok)'./normaliz_prior_std(indok)')); %this is s_i^{prior} in Ratto and Iskrev (2011, p.14) + + ide_strength_dMOMENTS(indok) = (1./(ide_uncert_unnormaliz(indok)'./abs(params(indok)'))); %this is s_i in Ratto and Iskrev (2011, p.13) + ide_strength_dMOMENTS_prior(indok) = (1./(ide_uncert_unnormaliz(indok)'./normaliz_prior_std(indok)')); %this is s_i^{prior} in Ratto and Iskrev (2011, p.14) sensitivity_zero_pos = find(isinf(deltaM)); deltaM_prior = deltaM.*abs(normaliz_prior_std'); %this is \Delta_i^{prior} in Ratto and Iskrev (2011, p.14) deltaM = deltaM.*abs(params'); %this is \Delta_i in Ratto and Iskrev (2011, p.14) - quant = si_J./repmat(sqrt(diag(cmm)),1,totparam_nbr); + quant = si_dMOMENTS./repmat(sqrt(diag(cmm)),1,totparam_nbr); if size(quant,1)==1 - si_Jnorm = abs(quant).*normaliz_prior_std; + si_dMOMENTSnorm = abs(quant).*normaliz_prior_std; else - si_Jnorm = vnorm(quant).*normaliz_prior_std; + si_dMOMENTSnorm = vnorm(quant).*normaliz_prior_std; end iy = find(diag_chh); - ind_dTAU = ind_dTAU(iy); - si_dTAU = si_dTAU(iy,:); + ind_dREDUCEDFORM = ind_dREDUCEDFORM(iy); + si_dREDUCEDFORM = si_dREDUCEDFORM(iy,:); if ~isempty(iy) - quant = si_dTAU./repmat(sqrt(diag_chh(iy)),1,totparam_nbr); + quant = si_dREDUCEDFORM./repmat(sqrt(diag_chh(iy)),1,totparam_nbr); if size(quant,1)==1 - si_dTAUnorm = abs(quant).*normaliz_prior_std; + si_dREDUCEDFORMnorm = abs(quant).*normaliz_prior_std; else - si_dTAUnorm = vnorm(quant).*normaliz_prior_std; + si_dREDUCEDFORMnorm = vnorm(quant).*normaliz_prior_std; end else - si_dTAUnorm = []; + si_dREDUCEDFORMnorm = []; end - diag_clre = diag(clre); - iy = find(diag_clre); - ind_dLRE = ind_dLRE(iy); - si_dLRE = si_dLRE(iy,:); + diag_cdynamic = diag(cdynamic); + iy = find(diag_cdynamic); + ind_dDYNAMIC = ind_dDYNAMIC(iy); + si_dDYNAMIC = si_dDYNAMIC(iy,:); if ~isempty(iy) - quant = si_dLRE./repmat(sqrt(diag_clre(iy)),1,modparam_nbr); + quant = si_dDYNAMIC./repmat(sqrt(diag_cdynamic(iy)),1,modparam_nbr); if size(quant,1)==1 - si_dLREnorm = abs(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end); + si_dDYNAMICnorm = abs(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end); else - si_dLREnorm = vnorm(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end); + si_dDYNAMICnorm = vnorm(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end); end else - si_dLREnorm=[]; + si_dDYNAMICnorm=[]; end %store results of identification strength - ide_hess.ide_strength_J = ide_strength_J; - ide_hess.ide_strength_J_prior = ide_strength_J_prior; + ide_hess.ide_strength_dMOMENTS = ide_strength_dMOMENTS; + ide_hess.ide_strength_dMOMENTS_prior = ide_strength_dMOMENTS_prior; ide_hess.deltaM = deltaM; ide_hess.deltaM_prior = deltaM_prior; ide_hess.sensitivity_zero_pos = sensitivity_zero_pos; ide_hess.identified_parameter_indices = indok; ide_hess.flag_score = flag_score; - ide_lre.si_dLREnorm = si_dLREnorm; - ide_moments.si_Jnorm = si_Jnorm; - ide_reducedform.si_dTAUnorm = si_dTAUnorm; + ide_dynamic.si_dDYNAMICnorm = si_dDYNAMICnorm; + ide_moments.si_dMOMENTSnorm = si_dMOMENTSnorm; + ide_reducedform.si_dREDUCEDFORMnorm = si_dREDUCEDFORMnorm; end %end of identification strength analysis end - %% Theoretical identification analysis based on linear rational expectations model, i.e. steady state and Jacobian of dynamic model equations +%% Normalization of Jacobians +% For Dynamic, ReducedForm, Moment and Minimal Jacobian: rescale each row by its largest element in absolute value +% For Spectrum: transform into correlation-type matrices (as above with AHess) if normalize_jacobians - norm_dLRE = max(abs(si_dLRE),[],2); - norm_dLRE = norm_dLRE(:,ones(size(dLRE,2),1)); + norm_dDYNAMIC = max(abs(si_dDYNAMIC),[],2); + norm_dDYNAMIC = norm_dDYNAMIC(:,ones(size(dDYNAMIC,2),1)); else - norm_dLRE = 1; + norm_dDYNAMIC = 1; end - % store into structure (not everything is really needed) - ide_lre.ind_dLRE = ind_dLRE; - ide_lre.norm_dLRE = norm_dLRE; - ide_lre.si_dLRE = si_dLRE; - ide_lre.dLRE = dLRE; - ide_lre.LRE = LRE; - - %% Theoretical identification analysis based on steady state and reduced-form-solution + % store into structure (not everything is used later on) + ide_dynamic.ind_dDYNAMIC = ind_dDYNAMIC; + ide_dynamic.norm_dDYNAMIC = norm_dDYNAMIC; + ide_dynamic.si_dDYNAMIC = si_dDYNAMIC; + ide_dynamic.dDYNAMIC = dDYNAMIC; + ide_dynamic.DYNAMIC = DYNAMIC; + if ~no_identification_reducedform if normalize_jacobians - norm_dTAU = max(abs(si_dTAU),[],2); - norm_dTAU = norm_dTAU(:,ones(totparam_nbr,1)); + norm_dREDUCEDFORM = max(abs(si_dREDUCEDFORM),[],2); + norm_dREDUCEDFORM = norm_dREDUCEDFORM(:,ones(totparam_nbr,1)); else - norm_dTAU = 1; + norm_dREDUCEDFORM = 1; end - % store into structure (not everything is really needed) - ide_reducedform.ind_dTAU = ind_dTAU; - ide_reducedform.norm_dTAU = norm_dTAU; - ide_reducedform.si_dTAU = si_dTAU; - ide_reducedform.dTAU = dTAU; - ide_reducedform.TAU = TAU; - end - - %% Theoretical identification analysis based on Iskrev (2010)'s method, i.e. first two moments + % store into structure (not everything is used later on) + ide_reducedform.ind_dREDUCEDFORM = ind_dREDUCEDFORM; + ide_reducedform.norm_dREDUCEDFORM = norm_dREDUCEDFORM; + ide_reducedform.si_dREDUCEDFORM = si_dREDUCEDFORM; + ide_reducedform.dREDUCEDFORM = dREDUCEDFORM; + ide_reducedform.REDUCEDFORM = REDUCEDFORM; + end + if ~no_identification_moments if normalize_jacobians - norm_J = max(abs(si_J),[],2); - norm_J = norm_J(:,ones(totparam_nbr,1)); + norm_dMOMENTS = max(abs(si_dMOMENTS),[],2); + norm_dMOMENTS = norm_dMOMENTS(:,ones(totparam_nbr,1)); else - norm_J = 1; + norm_dMOMENTS = 1; end - % store into structure (not everything is really needed) - ide_moments.ind_J = ind_J; - ide_moments.norm_J = norm_J; - ide_moments.si_J = si_J; - ide_moments.J = J; - ide_moments.MOMENTS = MOMENTS; - + % store into structure (not everything is used later on) + ide_moments.ind_dMOMENTS = ind_dMOMENTS; + ide_moments.norm_dMOMENTS = norm_dMOMENTS; + ide_moments.si_dMOMENTS = si_dMOMENTS; + ide_moments.dMOMENTS = dMOMENTS; + ide_moments.MOMENTS = MOMENTS; + if advanced - % here we do not normalize (i.e. set normJ=1) as the OLS in ident_bruteforce is very sensitive to normJ - [ide_moments.pars, ide_moments.cosnJ] = ident_bruteforce(J(ind_J,:), max_dim_cova_group, options_.TeX, options_ident.name_tex, options_ident.tittxt, options_ident.tol_deriv); + % here we do not normalize (i.e. we set norm_dMOMENTS=1) as the OLS in ident_bruteforce is very sensitive to norm_dMOMENTS + [ide_moments.pars, ide_moments.cosndMOMENTS] = ident_bruteforce(dMOMENTS(ind_dMOMENTS,:), max_dim_cova_group, options_.TeX, options_ident.name_tex, options_ident.tittxt, options_ident.tol_deriv); end - %here idea is to have the unnormalized S and V, which is then used in plot_identification.m and for prior_mc > 1 - [~, S, V] = svd(J(ind_J,:),0); + + %here we focus on the unnormalized S and V, which is then used in plot_identification.m and for prior_mc > 1 + [~, S, V] = svd(dMOMENTS(ind_dMOMENTS,:),0); S = diag(S); - S = [S;zeros(size(J,2)-length(ind_J),1)]; + S = [S;zeros(size(dMOMENTS,2)-length(ind_dMOMENTS),1)]; if totparam_nbr > 8 ide_moments.S = S([1:4, end-3:end]); ide_moments.V = V(:,[1:4, end-3:end]); @@ -492,63 +476,64 @@ if info(1) == 0 %no errors in solution ide_moments.V = V; end end - - %% Theoretical identification analysis based on Komunjer and Ng (2011)'s method, i.e. steady state and observational equivalent spectral densities within a minimal system + if ~no_identification_minimal if normalize_jacobians - norm_D = max(abs(D(ind_D,:)),[],2); - norm_D = norm_D(:,ones(size(D,2),1)); + ind_dMINIMAL = (find(max(abs(dMINIMAL'),[],1) > tol_deriv)); %index for non-zero rows + norm_dMINIMAL = max(abs(dMINIMAL(ind_dMINIMAL,:)),[],2); + norm_dMINIMAL = norm_dMINIMAL(:,ones(size(dMINIMAL,2),1)); else - norm_D = 1; + norm_dMINIMAL = 1; end - % store into structure - ide_minimal.ind_D = ind_D; - ide_minimal.norm_D = norm_D; - ide_minimal.D = D; + % store into structure (not everything is used later on) + ide_minimal.ind_dMINIMAL = ind_dMINIMAL; + ide_minimal.norm_dMINIMAL = norm_dMINIMAL; + ide_minimal.dMINIMAL = dMINIMAL; end - - %% Theoretical identification analysis based on Qu and Tkachenko (2012)'s method, i.e. steady state and spectral density + if ~no_identification_spectrum if normalize_jacobians - tilda_G = zeros(size(G)); - delta_G = sqrt(diag(G(ind_G,ind_G))); - tilda_G(ind_G,ind_G) = G(ind_G,ind_G)./((delta_G)*(delta_G')); - norm_G = max(abs(G(ind_G,:)),[],2); - norm_G = norm_G(:,ones(size(G,2),1)); + ind_dSPECTRUM = (find(max(abs(dSPECTRUM'),[],1) > tol_deriv)); %index for non-zero rows + tilda_dSPECTRUM = zeros(size(dSPECTRUM)); + delta_dSPECTRUM = sqrt(diag(dSPECTRUM(ind_dSPECTRUM,ind_dSPECTRUM))); + tilda_dSPECTRUM(ind_dSPECTRUM,ind_dSPECTRUM) = dSPECTRUM(ind_dSPECTRUM,ind_dSPECTRUM)./((delta_dSPECTRUM)*(delta_dSPECTRUM')); + norm_dSPECTRUM = max(abs(dSPECTRUM(ind_dSPECTRUM,:)),[],2); + norm_dSPECTRUM = norm_dSPECTRUM(:,ones(size(dSPECTRUM,2),1)); else - tilda_G = G; - norm_G = 1; + tilda_dSPECTRUM = dSPECTRUM; + norm_dSPECTRUM = 1; end - % store into structure - ide_spectrum.ind_G = ind_G; - ide_spectrum.tilda_G = tilda_G; - ide_spectrum.G = G; - ide_spectrum.norm_G = norm_G; + % store into structure (not everything is used later on) + ide_spectrum.ind_dSPECTRUM = ind_dSPECTRUM; + ide_spectrum.norm_dSPECTRUM = norm_dSPECTRUM; + ide_spectrum.tilda_dSPECTRUM = tilda_dSPECTRUM; + ide_spectrum.dSPECTRUM = dSPECTRUM; + ide_spectrum.dSPECTRUM_NO_MEAN = dSPECTRUM_NO_MEAN; end - %% Perform identification checks, i.e. find out which parameters are involved +%% Perform identification checks, i.e. find out which parameters are involved if checks_via_subsets % identification_checks_via_subsets is only for debugging - [ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = ... - identification_checks_via_subsets(ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident); + [ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = ... + identification_checks_via_subsets(ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident); else - [ide_lre.cond, ide_lre.rank, ide_lre.ind0, ide_lre.indno, ide_lre.ino, ide_lre.Mco, ide_lre.Pco, ide_lre.jweak, ide_lre.jweak_pair] = ... - identification_checks(dLRE(ind_dLRE,:)./norm_dLRE, 1, tol_rank, tol_sv, modparam_nbr); + [ide_dynamic.cond, ide_dynamic.rank, ide_dynamic.ind0, ide_dynamic.indno, ide_dynamic.ino, ide_dynamic.Mco, ide_dynamic.Pco, ide_dynamic.jweak, ide_dynamic.jweak_pair] = ... + identification_checks(dDYNAMIC(ind_dDYNAMIC,:)./norm_dDYNAMIC, 1, tol_rank, tol_sv, modparam_nbr); if ~no_identification_reducedform [ide_reducedform.cond, ide_reducedform.rank, ide_reducedform.ind0, ide_reducedform.indno, ide_reducedform.ino, ide_reducedform.Mco, ide_reducedform.Pco, ide_reducedform.jweak, ide_reducedform.jweak_pair] = ... - identification_checks(dTAU(ind_dTAU,:)./norm_dTAU, 1, tol_rank, tol_sv, totparam_nbr); + identification_checks(dREDUCEDFORM(ind_dREDUCEDFORM,:)./norm_dREDUCEDFORM, 1, tol_rank, tol_sv, totparam_nbr); end if ~no_identification_moments [ide_moments.cond, ide_moments.rank, ide_moments.ind0, ide_moments.indno, ide_moments.ino, ide_moments.Mco, ide_moments.Pco, ide_moments.jweak, ide_moments.jweak_pair] = ... - identification_checks(J(ind_J,:)./norm_J, 1, tol_rank, tol_sv, totparam_nbr); - end + identification_checks(dMOMENTS(ind_dMOMENTS,:)./norm_dMOMENTS, 1, tol_rank, tol_sv, totparam_nbr); + end if ~no_identification_minimal [ide_minimal.cond, ide_minimal.rank, ide_minimal.ind0, ide_minimal.indno, ide_minimal.ino, ide_minimal.Mco, ide_minimal.Pco, ide_minimal.jweak, ide_minimal.jweak_pair] = ... - identification_checks(D(ind_D,:)./norm_D, 2, tol_rank, tol_sv, totparam_nbr); - end - if ~no_identification_spectrum + identification_checks(dMINIMAL(ind_dMINIMAL,:)./norm_dMINIMAL, 2, tol_rank, tol_sv, totparam_nbr); + end + if ~no_identification_spectrum [ide_spectrum.cond, ide_spectrum.rank, ide_spectrum.ind0, ide_spectrum.indno, ide_spectrum.ino, ide_spectrum.Mco, ide_spectrum.Pco, ide_spectrum.jweak, ide_spectrum.jweak_pair] = ... - identification_checks(tilda_G, 3, tol_rank, tol_sv, totparam_nbr); + identification_checks(tilda_dSPECTRUM, 3, tol_rank, tol_sv, totparam_nbr); end end end \ No newline at end of file diff --git a/matlab/identification_checks.m b/matlab/identification_checks.m index 4b4ba057c..cb6717470 100644 --- a/matlab/identification_checks.m +++ b/matlab/identification_checks.m @@ -24,7 +24,7 @@ function [condX, rankX, ind0, indno, ixno, Mco, Pco, jweak, jweak_pair] = identi % * jweak_pair [(vech) matrix] gives 1 if a couple parameters has Pco=1 (with tolerance tol_rank) % ------------------------------------------------------------------------- % This function is called by -% * identification_analysis.m +% * identification_analysis.m % ------------------------------------------------------------------------- % This function calls % * cosn @@ -48,9 +48,11 @@ function [condX, rankX, ind0, indno, ixno, Mco, Pco, jweak, jweak_pair] = identi % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . % ========================================================================= - -if nargin < 3 || isempty(tol_rank) - tol_rank = 1.e-10; %tolerance level used for rank computations +if issparse(X) + X = full(X); +end +if nargin < 3 || isempty(tol_rank) || strcmp(tol_rank,'robust') + tol_rank = max(size(X)) * eps(norm(X)); %tolerance level used for rank computations end if nargin < 4 || isempty(tol_sv) tol_sv = 1.e-3; %tolerance level for zero singular value @@ -71,7 +73,7 @@ else Xrest = []; end - % find non-zero columns at machine precision +% find non-zero columns at machine precision if size(Xpar,1) > 1 ind1 = find(vnorm(Xpar) >= eps); else @@ -121,7 +123,7 @@ if icheck rankX = rank(X,tol_rank); end -ind0 = zeros(1,param_nbr); %initialize +ind0 = zeros(1,param_nbr); %initialize ind0(ind1) = 1; % find near linear dependence problems via multicorrelation coefficients @@ -129,17 +131,17 @@ if test_flag == 0 || test_flag == 3 % G is a Gram matrix and hence should be a c if test_flag == 3 % For Qu and Tkachenko's G matrix we need to keep track of all parameters Mco = NaN(param_nbr,1); end - Pco=NaN(param_nbr,param_nbr); % pairwise correlation coefficient + Pco=NaN(param_nbr,param_nbr); % pairwise correlation coefficient deltaX = sqrt(diag(X(ind1,ind1))); - tildaX = X(ind1,ind1)./((deltaX)*(deltaX')); + tildaX = X(ind1,ind1)./((deltaX)*(deltaX')); Mco(ind1,1)=(1-1./diag(inv(tildaX))); % multicorrelation coefficent Pco(ind1,ind1)=inv(X(ind1,ind1)); sd=sqrt(diag(Pco)); Pco = abs(Pco./((sd)*(sd'))); -else +else Mco = NaN(param_nbr,1); for ii = 1:size(Xparnonzero,2) - Mco(ind1(ii),:) = cosn([Xparnonzero(:,ii) , Xparnonzero(:,find([1:1:size(Xparnonzero,2)]~=ii)), Xrest]); + Mco(ind1(ii),:) = cosn([Xparnonzero(:,ii) , Xparnonzero(:,find([1:1:size(Xparnonzero,2)]~=ii)), Xrest]); end end @@ -151,10 +153,10 @@ if param_nbr>0 && (rankX tol_sv)'; indno(ixno,ind1) = temp(1:(end-size(Xrest,2))); @@ -178,7 +180,7 @@ if test_flag ~= 0 || test_flag ~= 0 Pco(ind1(jj),ind1(ii)) = Pco(ind1(ii),ind1(jj)); end end - + for j=1:param_nbr if Mco(j)>(1-tol_rank) jweak(j)=1; diff --git a/matlab/identification_checks_via_subsets.m b/matlab/identification_checks_via_subsets.m index 3cb9d3ece..63a9bbce3 100644 --- a/matlab/identification_checks_via_subsets.m +++ b/matlab/identification_checks_via_subsets.m @@ -1,22 +1,22 @@ -function [ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident) -%[ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident) +function [ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident) +%[ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident) % ------------------------------------------------------------------------- % Finds problematic sets of paramters via checking the necessary rank condition % of the Jacobians for all possible combinations of parameters. The rank is % computed via an inbuild function based on the SVD, similar to matlab's -% rank. The idea is that once we have the Jacobian for all parameters, we +% rank. The idea is that once we have the Jacobian for all parameters, we % can easily set up Jacobians containing all combinations of parameters by -% picking the relevant columns/elements of the full Jacobian. Then the rank -% of these smaller Jacobians indicates whether this paramter combination is +% picking the relevant columns/elements of the full Jacobian. Then the rank +% of these smaller Jacobians indicates whether this paramter combination is % identified or not. To speed up computations: % (1) single parameters are removed from possible higher-order sets, -% (2) for parameters that are collinear, i.e. rank failure for 2 element sets, -% we replace the second parameter by the first one, and then compute +% (2) for parameters that are collinear, i.e. rank failure for 2 element sets, +% we replace the second parameter by the first one, and then compute % higher-order combinations [uncommented] % (3) all lower-order problematic sets are removed from higher-order sets % by an inbuild function % (4) we could replace nchoosek by a mex version, e.g. VChooseK -% (https://de.mathworks.com/matlabcentral/fileexchange/26190-vchoosek) as +% (https://de.mathworks.com/matlabcentral/fileexchange/26190-vchoosek) as % nchoosek could be the bottleneck in terms of speed (and memory for models % with totparam_nbr > 150) % ========================================================================= @@ -44,12 +44,12 @@ function [ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = id % ide_reducedform, ide_moments, ide_spectrum, ide_minimal are augmented by the % following fields: % * problpars: [1 by totparam_nbr] cell with the following structure for j=1:totparam_nbr -% problpars{j}: [nonidentified_j_set_parameters_nbr by j] +% problpars{j}: [nonidentified_j_set_parameters_nbr by j] % matrix with j collinear parameters in each row % * rank: [integer] rank of Jacobian % ------------------------------------------------------------------------- -% This function is called by -% * identification_analysis.m +% This function is called by +% * identification_analysis.m % ========================================================================= % Copyright (C) 2019 Dynare Team % @@ -70,14 +70,14 @@ function [ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = id % ========================================================================= %% initialize output objects and get options -no_identification_lre = 0; %always compute lre +no_identification_dynamic = 0; %always compute dynamic no_identification_reducedform = options_ident.no_identification_reducedform; no_identification_moments = options_ident.no_identification_moments; no_identification_spectrum = options_ident.no_identification_spectrum; no_identification_minimal = options_ident.no_identification_minimal; tol_rank = options_ident.tol_rank; max_dim_subsets_groups = options_ident.max_dim_subsets_groups; -lre_problpars = cell(1,max_dim_subsets_groups); +dynamic_problpars = cell(1,max_dim_subsets_groups); reducedform_problpars = cell(1,max_dim_subsets_groups); moments_problpars = cell(1,max_dim_subsets_groups); spectrum_problpars = cell(1,max_dim_subsets_groups); @@ -87,298 +87,362 @@ indtotparam = 1:totparam_nbr; %initialize index of parameters %% Prepare Jacobians and check rank % initialize linear rational expectations model -if ~no_identification_lre - dLRE = ide_lre.dLRE; - dLRE(ide_lre.ind_dLRE,:) = dLRE(ide_lre.ind_dLRE,:)./ide_lre.norm_dLRE; %normalize +if ~no_identification_dynamic + dDYNAMIC = ide_dynamic.dDYNAMIC; + dDYNAMIC(ide_dynamic.ind_dDYNAMIC,:) = dDYNAMIC(ide_dynamic.ind_dDYNAMIC,:)./ide_dynamic.norm_dDYNAMIC; %normalize if totparam_nbr > modparam_nbr - dLRE = [zeros(size(ide_lre.dLRE,1),totparam_nbr-modparam_nbr) dLRE]; %add derivatives wrt stderr and corr parameters + dDYNAMIC = [zeros(size(ide_dynamic.dDYNAMIC,1),totparam_nbr-modparam_nbr) dDYNAMIC]; %add derivatives wrt stderr and corr parameters end - rank_dLRE = rank(dLRE,tol_rank); %compute rank with imposed tolerance level - ide_lre.rank = rank_dLRE; + if strcmp(tol_rank,'robust') + rank_dDYNAMIC = rank(full(dDYNAMIC)); %compute rank with imposed tolerance level + else + rank_dDYNAMIC = rank(full(dDYNAMIC),tol_rank); %compute rank with imposed tolerance level + end + ide_dynamic.rank = rank_dDYNAMIC; % check rank criteria for full Jacobian - if rank_dLRE == totparam_nbr + if rank_dDYNAMIC == totparam_nbr % all parameters are identifiable - no_identification_lre = 1; %skip in the following - indparam_dLRE = []; - else + no_identification_dynamic = 1; %skip in the following + indparam_dDYNAMIC = []; + else % there is lack of identification - indparam_dLRE = indtotparam; %initialize for nchoosek + indparam_dDYNAMIC = indtotparam; %initialize for nchoosek end else - indparam_dLRE = []; %empty for nchoosek + indparam_dDYNAMIC = []; %empty for nchoosek end % initialize for reduced form solution criteria if ~no_identification_reducedform - dTAU = ide_reducedform.dTAU; - dTAU(ide_reducedform.ind_dTAU,:) = dTAU(ide_reducedform.ind_dTAU,:)./ide_reducedform.norm_dTAU; %normalize - rank_dTAU = rank(dTAU,tol_rank); %compute rank with imposed tolerance level - ide_reducedform.rank = rank_dTAU; + dREDUCEDFORM = ide_reducedform.dREDUCEDFORM; + dREDUCEDFORM(ide_reducedform.ind_dREDUCEDFORM,:) = dREDUCEDFORM(ide_reducedform.ind_dREDUCEDFORM,:)./ide_reducedform.norm_dREDUCEDFORM; %normalize + if strcmp(tol_rank,'robust') + rank_dREDUCEDFORM = rank(full(dREDUCEDFORM)); %compute rank with imposed tolerance level + else + rank_dREDUCEDFORM = rank(full(dREDUCEDFORM),tol_rank); %compute rank with imposed tolerance level + end + ide_reducedform.rank = rank_dREDUCEDFORM; % check rank criteria for full Jacobian - if rank_dTAU == totparam_nbr + if rank_dREDUCEDFORM == totparam_nbr % all parameters are identifiable no_identification_reducedform = 1; %skip in the following - indparam_dTAU = []; - else + indparam_dREDUCEDFORM = []; + else % there is lack of identification - indparam_dTAU = indtotparam; %initialize for nchoosek + indparam_dREDUCEDFORM = indtotparam; %initialize for nchoosek end else - indparam_dTAU = []; %empty for nchoosek + indparam_dREDUCEDFORM = []; %empty for nchoosek end % initialize for moments criteria if ~no_identification_moments - J = ide_moments.J; - J(ide_moments.ind_J,:) = J(ide_moments.ind_J,:)./ide_moments.norm_J; %normalize - rank_J = rank(J,tol_rank); %compute rank with imposed tolerance level - ide_moments.rank = rank_J; + dMOMENTS = ide_moments.dMOMENTS; + dMOMENTS(ide_moments.ind_dMOMENTS,:) = dMOMENTS(ide_moments.ind_dMOMENTS,:)./ide_moments.norm_dMOMENTS; %normalize + if strcmp(tol_rank,'robust') + rank_dMOMENTS = rank(full(dMOMENTS)); %compute rank with imposed tolerance level + else + rank_dMOMENTS = rank(full(dMOMENTS),tol_rank); %compute rank with imposed tolerance level + end + ide_moments.rank = rank_dMOMENTS; % check rank criteria for full Jacobian - if rank_J == totparam_nbr + if rank_dMOMENTS == totparam_nbr % all parameters are identifiable no_identification_moments = 1; %skip in the following - indparam_J = []; - else + indparam_dMOMENTS = []; + else % there is lack of identification - indparam_J = indtotparam; %initialize for nchoosek + indparam_dMOMENTS = indtotparam; %initialize for nchoosek end else - indparam_J = []; %empty for nchoosek + indparam_dMOMENTS = []; %empty for nchoosek end % initialize for spectrum criteria if ~no_identification_spectrum - G = ide_spectrum.tilda_G; %tilda G is normalized G matrix in identification_analysis.m + dSPECTRUM = ide_spectrum.tilda_dSPECTRUM; %tilda dSPECTRUM is normalized dSPECTRUM matrix in identification_analysis.m %alternative normalization - %G = ide_spectrum.G; - %G(ide_spectrum.ind_G,:) = G(ide_spectrum.ind_G,:)./ide_spectrum.norm_G; %normalize - rank_G = rank(G,tol_rank); %compute rank with imposed tolerance level - ide_spectrum.rank = rank_G; + %dSPECTRUM = ide_spectrum.dSPECTRUM; + %dSPECTRUM(ide_spectrum.ind_dSPECTRUM,:) = dSPECTRUM(ide_spectrum.ind_dSPECTRUM,:)./ide_spectrum.norm_dSPECTRUM; %normalize + if strcmp(tol_rank,'robust') + rank_dSPECTRUM = rank(full(dSPECTRUM)); %compute rank with imposed tolerance level + else + rank_dSPECTRUM = rank(full(dSPECTRUM),tol_rank); %compute rank with imposed tolerance level + end + ide_spectrum.rank = rank_dSPECTRUM; % check rank criteria for full Jacobian - if rank_G == totparam_nbr + if rank_dSPECTRUM == totparam_nbr % all parameters are identifiable no_identification_spectrum = 1; %skip in the following - indparam_G = []; + indparam_dSPECTRUM = []; else % lack of identification - indparam_G = indtotparam; %initialize for nchoosek + indparam_dSPECTRUM = indtotparam; %initialize for nchoosek end else - indparam_G = []; %empty for nchoosek + indparam_dSPECTRUM = []; %empty for nchoosek end % initialize for minimal system criteria if ~no_identification_minimal - D = ide_minimal.D; - D(ide_minimal.ind_D,:) = D(ide_minimal.ind_D,:)./ide_minimal.norm_D; %normalize - D_par = D(:,1:totparam_nbr); %part of D that is dependent on parameters - D_rest = D(:,(totparam_nbr+1):end); %part of D that is independent of parameters - rank_D = rank(D,tol_rank); %compute rank via SVD see function below - ide_minimal.rank = rank_D; - D_fixed_rank_nbr = size(D_rest,2); + dMINIMAL = ide_minimal.dMINIMAL; + dMINIMAL(ide_minimal.ind_dMINIMAL,:) = dMINIMAL(ide_minimal.ind_dMINIMAL,:)./ide_minimal.norm_dMINIMAL; %normalize + dMINIMAL_par = dMINIMAL(:,1:totparam_nbr); %part of dMINIMAL that is dependent on parameters + dMINIMAL_rest = dMINIMAL(:,(totparam_nbr+1):end); %part of dMINIMAL that is independent of parameters + if strcmp(tol_rank,'robust') + rank_dMINIMAL = rank(full(dMINIMAL)); %compute rank via SVD see function below + else + rank_dMINIMAL = rank(full(dMINIMAL),tol_rank); %compute rank via SVD see function below + end + ide_minimal.rank = rank_dMINIMAL; + dMINIMAL_fixed_rank_nbr = size(dMINIMAL_rest,2); % check rank criteria for full Jacobian - if rank_D == totparam_nbr + D_fixed_rank_nbr + if rank_dMINIMAL == totparam_nbr + dMINIMAL_fixed_rank_nbr % all parameters are identifiable no_identification_minimal = 1; %skip in the following - indparam_D = []; + indparam_dMINIMAL = []; else % lack of identification - indparam_D = indtotparam; %initialize for nchoosek + indparam_dMINIMAL = indtotparam; %initialize for nchoosek end else - indparam_D = []; %empty for nchoosek + indparam_dMINIMAL = []; %empty for nchoosek end %% Check single parameters for j=1:totparam_nbr - if ~no_identification_lre + if ~no_identification_dynamic % Columns correspond to single parameters, i.e. full rank would be equal to 1 - if rank(dLRE(:,j),tol_rank) == 0 - lre_problpars{1} = [lre_problpars{1};j]; + if strcmp(tol_rank,'robust') + if rank(full(dDYNAMIC(:,j))) == 0 + dynamic_problpars{1} = [dynamic_problpars{1};j]; + end + else + if rank(full(dDYNAMIC(:,j)),tol_rank) == 0 + dynamic_problpars{1} = [dynamic_problpars{1};j]; + end end end if ~no_identification_reducedform % Columns correspond to single parameters, i.e. full rank would be equal to 1 - if rank(dTAU(:,j),tol_rank) == 0 - reducedform_problpars{1} = [reducedform_problpars{1};j]; + if strcmp(tol_rank,'robust') + if rank(full(dREDUCEDFORM(:,j))) == 0 + reducedform_problpars{1} = [reducedform_problpars{1};j]; + end + else + if rank(full(dREDUCEDFORM(:,j)),tol_rank) == 0 + reducedform_problpars{1} = [reducedform_problpars{1};j]; + end end end - if ~no_identification_moments + if ~no_identification_moments % Columns correspond to single parameters, i.e. full rank would be equal to 1 - if rank(J(:,j),tol_rank) == 0 - moments_problpars{1} = [moments_problpars{1};j]; + if strcmp(tol_rank,'robust') + if rank(full(dMOMENTS(:,j))) == 0 + moments_problpars{1} = [moments_problpars{1};j]; + end + else + if rank(full(dMOMENTS(:,j)),tol_rank) == 0 + moments_problpars{1} = [moments_problpars{1};j]; + end end end if ~no_identification_spectrum % Diagonal values correspond to single parameters, absolute value needs to be greater than tolerance level - if abs(G(j,j)) < tol_rank + if abs(dSPECTRUM(j,j)) < tol_rank spectrum_problpars{1} = [spectrum_problpars{1};j]; end end if ~no_identification_minimal - % Columns of D_par correspond to single parameters, needs to be augmented with D_rest (part that is independent of parameters), - % full rank would be equal to 1+D_fixed_rank_nbr - if rank([D_par(:,j) D_rest],tol_rank) == D_fixed_rank_nbr - minimal_problpars{1} = [minimal_problpars{1};j]; + % Columns of dMINIMAL_par correspond to single parameters, needs to be augmented with dMINIMAL_rest (part that is independent of parameters), + % full rank would be equal to 1+dMINIMAL_fixed_rank_nbr + if strcmp(tol_rank,'robust') + if rank(full([dMINIMAL_par(:,j) dMINIMAL_rest])) == dMINIMAL_fixed_rank_nbr + minimal_problpars{1} = [minimal_problpars{1};j]; + end + else + if rank(full([dMINIMAL_par(:,j) dMINIMAL_rest]),tol_rank) == dMINIMAL_fixed_rank_nbr + minimal_problpars{1} = [minimal_problpars{1};j]; + end end end end % Check whether lack of identification is only due to single parameters -if ~no_identification_lre - if size(lre_problpars{1},1) == (totparam_nbr - rank_dLRE) +if ~no_identification_dynamic + if size(dynamic_problpars{1},1) == (totparam_nbr - rank_dDYNAMIC) %found all nonidentified parameter sets - no_identification_lre = 1; %skip in the following + no_identification_dynamic = 1; %skip in the following else %still parameter sets that are nonidentified - indparam_dLRE(lre_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam + indparam_dDYNAMIC(dynamic_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam end end if ~no_identification_reducedform - if size(reducedform_problpars{1},1) == (totparam_nbr - rank_dTAU) + if size(reducedform_problpars{1},1) == (totparam_nbr - rank_dREDUCEDFORM) %found all nonidentified parameter sets no_identification_reducedform = 1; %skip in the following else %still parameter sets that are nonidentified - indparam_dTAU(reducedform_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam + indparam_dREDUCEDFORM(reducedform_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam end end if ~no_identification_moments - if size(moments_problpars{1},1) == (totparam_nbr - rank_J) + if size(moments_problpars{1},1) == (totparam_nbr - rank_dMOMENTS) %found all nonidentified parameter sets no_identification_moments = 1; %skip in the following else %still parameter sets that are nonidentified - indparam_J(moments_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam + indparam_dMOMENTS(moments_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam end end if ~no_identification_spectrum - if size(spectrum_problpars{1},1) == (totparam_nbr - rank_G) + if size(spectrum_problpars{1},1) == (totparam_nbr - rank_dSPECTRUM) %found all nonidentified parameter sets no_identification_spectrum = 1; %skip in the following else %still parameter sets that are nonidentified - indparam_G(spectrum_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam + indparam_dSPECTRUM(spectrum_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam end end if ~no_identification_minimal - if size(minimal_problpars{1},1) == (totparam_nbr + D_fixed_rank_nbr - rank_D) + if size(minimal_problpars{1},1) == (totparam_nbr + dMINIMAL_fixed_rank_nbr - rank_dMINIMAL) %found all nonidentified parameter sets no_identification_minimal = 1; %skip in the following else %still parameter sets that are nonidentified - indparam_D(minimal_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam + indparam_dMINIMAL(minimal_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam end end %% check higher order (j>1) parameter sets -%get common parameter indices from which to sample higher-order sets using nchoosek (we do not want to run nchoosek three times), most of the times indparamJ, indparamG, and indparamD are equal anyways -indtotparam = unique([indparam_dLRE indparam_dTAU indparam_J indparam_G indparam_D]); +%get common parameter indices from which to sample higher-order sets using nchoosek (we do not want to run nchoosek three times), most of the times indparamdMOMENTS, indparamdSPECTRUM, and indparamdMINIMAL are equal anyways +indtotparam = unique([indparam_dDYNAMIC indparam_dREDUCEDFORM indparam_dMOMENTS indparam_dSPECTRUM indparam_dMINIMAL]); for j=2:min(length(indtotparam),max_dim_subsets_groups) % Check j-element subsets h = dyn_waitbar(0,['Brute force collinearity for ' int2str(j) ' parameters.']); %Step1: get all possible unique subsets of j elements - if ~no_identification_lre || ~no_identification_reducedform || ~no_identification_moments || ~no_identification_spectrum || ~no_identification_minimal + if ~no_identification_dynamic || ~no_identification_reducedform || ~no_identification_moments || ~no_identification_spectrum || ~no_identification_minimal indexj=nchoosek(int16(indtotparam),j); % int16 speeds up nchoosek % One could also use a mex version of nchoosek to speed this up, e.g.VChooseK from https://de.mathworks.com/matlabcentral/fileexchange/26190-vchoosek end %Step 2: remove already problematic sets and initialize rank vector - if ~no_identification_lre - indexj_dLRE = RemoveProblematicParameterSets(indexj,lre_problpars); - rankj_dLRE = zeros(size(indexj_dLRE,1),1); + if ~no_identification_dynamic + indexj_dDYNAMIC = RemoveProblematicParameterSets(indexj,dynamic_problpars); + rankj_dDYNAMIC = zeros(size(indexj_dDYNAMIC,1),1); else - indexj_dLRE = []; + indexj_dDYNAMIC = []; end if ~no_identification_reducedform - indexj_dTAU = RemoveProblematicParameterSets(indexj,reducedform_problpars); - rankj_dTAU = zeros(size(indexj_dTAU,1),1); + indexj_dREDUCEDFORM = RemoveProblematicParameterSets(indexj,reducedform_problpars); + rankj_dREDUCEDFORM = zeros(size(indexj_dREDUCEDFORM,1),1); else - indexj_dTAU = []; + indexj_dREDUCEDFORM = []; end if ~no_identification_moments - indexj_J = RemoveProblematicParameterSets(indexj,moments_problpars); - rankj_J = zeros(size(indexj_J,1),1); + indexj_dMOMENTS = RemoveProblematicParameterSets(indexj,moments_problpars); + rankj_dMOMENTS = zeros(size(indexj_dMOMENTS,1),1); else - indexj_J = []; + indexj_dMOMENTS = []; end if ~no_identification_spectrum - indexj_G = RemoveProblematicParameterSets(indexj,spectrum_problpars); - rankj_G = zeros(size(indexj_G,1),1); + indexj_dSPECTRUM = RemoveProblematicParameterSets(indexj,spectrum_problpars); + rankj_dSPECTRUM = zeros(size(indexj_dSPECTRUM,1),1); else - indexj_G = []; + indexj_dSPECTRUM = []; end if ~no_identification_minimal - indexj_D = RemoveProblematicParameterSets(indexj,minimal_problpars); - rankj_D = zeros(size(indexj_D,1),1); + indexj_dMINIMAL = RemoveProblematicParameterSets(indexj,minimal_problpars); + rankj_dMINIMAL = zeros(size(indexj_dMINIMAL,1),1); else - indexj_D = []; + indexj_dMINIMAL = []; end - + %Step3: Check rank criteria on submatrices - k_dLRE=0; k_dTAU=0; k_J=0; k_G=0; k_D=0; %initialize counters - maxk = max([size(indexj_dLRE,1), size(indexj_dTAU,1), size(indexj_J,1), size(indexj_D,1), size(indexj_G,1)]); + k_dDYNAMIC=0; k_dREDUCEDFORM=0; k_dMOMENTS=0; k_dSPECTRUM=0; k_dMINIMAL=0; %initialize counters + maxk = max([size(indexj_dDYNAMIC,1), size(indexj_dREDUCEDFORM,1), size(indexj_dMOMENTS,1), size(indexj_dMINIMAL,1), size(indexj_dSPECTRUM,1)]); for k=1:maxk - if ~no_identification_lre - k_dLRE = k_dLRE+1; - if k_dLRE <= size(indexj_dLRE,1) - dLRE_j = dLRE(:,indexj_dLRE(k_dLRE,:)); % pick columns that correspond to parameter subset - rankj_dLRE(k_dLRE,1) = rank(dLRE_j,tol_rank); %compute rank with imposed tolerance + if ~no_identification_dynamic + k_dDYNAMIC = k_dDYNAMIC+1; + if k_dDYNAMIC <= size(indexj_dDYNAMIC,1) + dDYNAMIC_j = dDYNAMIC(:,indexj_dDYNAMIC(k_dDYNAMIC,:)); % pick columns that correspond to parameter subset + if strcmp(tol_rank,'robust') + rankj_dDYNAMIC(k_dDYNAMIC,1) = rank(full(dDYNAMIC_j)); %compute rank with imposed tolerance + else + rankj_dDYNAMIC(k_dDYNAMIC,1) = rank(full(dDYNAMIC_j),tol_rank); %compute rank with imposed tolerance + end end end if ~no_identification_reducedform - k_dTAU = k_dTAU+1; - if k_dTAU <= size(indexj_dTAU,1) - dTAU_j = dTAU(:,indexj_dTAU(k_dTAU,:)); % pick columns that correspond to parameter subset - rankj_dTAU(k_dTAU,1) = rank(dTAU_j,tol_rank); %compute rank with imposed tolerance + k_dREDUCEDFORM = k_dREDUCEDFORM+1; + if k_dREDUCEDFORM <= size(indexj_dREDUCEDFORM,1) + dREDUCEDFORM_j = dREDUCEDFORM(:,indexj_dREDUCEDFORM(k_dREDUCEDFORM,:)); % pick columns that correspond to parameter subset + if strcmp(tol_rank,'robust') + rankj_dREDUCEDFORM(k_dREDUCEDFORM,1) = rank(full(dREDUCEDFORM_j)); %compute rank with imposed tolerance + else + rankj_dREDUCEDFORM(k_dREDUCEDFORM,1) = rank(full(dREDUCEDFORM_j),tol_rank); %compute rank with imposed tolerance + end end end if ~no_identification_moments - k_J = k_J+1; - if k_J <= size(indexj_J,1) - J_j = J(:,indexj_J(k_J,:)); % pick columns that correspond to parameter subset - rankj_J(k_J,1) = rank(J_j,tol_rank); %compute rank with imposed tolerance + k_dMOMENTS = k_dMOMENTS+1; + if k_dMOMENTS <= size(indexj_dMOMENTS,1) + dMOMENTS_j = dMOMENTS(:,indexj_dMOMENTS(k_dMOMENTS,:)); % pick columns that correspond to parameter subset + if strcmp(tol_rank,'robust') + rankj_dMOMENTS(k_dMOMENTS,1) = rank(full(dMOMENTS_j)); %compute rank with imposed tolerance + else + rankj_dMOMENTS(k_dMOMENTS,1) = rank(full(dMOMENTS_j),tol_rank); %compute rank with imposed tolerance + end end end if ~no_identification_minimal - k_D = k_D+1; - if k_D <= size(indexj_D,1) - D_j = [D_par(:,indexj_D(k_D,:)) D_rest]; % pick columns in D_par that correspond to parameter subset and augment with parameter-indepdendet part D_rest - rankj_D(k_D,1) = rank(D_j,tol_rank); %compute rank with imposed tolerance + k_dMINIMAL = k_dMINIMAL+1; + if k_dMINIMAL <= size(indexj_dMINIMAL,1) + dMINIMAL_j = [dMINIMAL_par(:,indexj_dMINIMAL(k_dMINIMAL,:)) dMINIMAL_rest]; % pick columns in dMINIMAL_par that correspond to parameter subset and augment with parameter-indepdendet part dMINIMAL_rest + if strcmp(tol_rank,'robust') + rankj_dMINIMAL(k_dMINIMAL,1) = rank(full(dMINIMAL_j)); %compute rank with imposed tolerance + else + rankj_dMINIMAL(k_dMINIMAL,1) = rank(full(dMINIMAL_j),tol_rank); %compute rank with imposed tolerance + end end end if ~no_identification_spectrum - k_G = k_G+1; - if k_G <= size(indexj_G,1) - G_j = G(indexj_G(k_G,:),indexj_G(k_G,:)); % pick rows and columns that correspond to parameter subset - rankj_G(k_G,1) = rank(G_j,tol_rank); % Compute rank with imposed tol + k_dSPECTRUM = k_dSPECTRUM+1; + if k_dSPECTRUM <= size(indexj_dSPECTRUM,1) + dSPECTRUM_j = dSPECTRUM(indexj_dSPECTRUM(k_dSPECTRUM,:),indexj_dSPECTRUM(k_dSPECTRUM,:)); % pick rows and columns that correspond to parameter subset + if strcmp(tol_rank,'robust') + rankj_dSPECTRUM(k_dSPECTRUM,1) = rank(full(dSPECTRUM_j)); % Compute rank with imposed tol + else + rankj_dSPECTRUM(k_dSPECTRUM,1) = rank(full(dSPECTRUM_j),tol_rank); % Compute rank with imposed tol + end end end dyn_waitbar(k/maxk,h) end - + %Step 4: Compare rank conditions for all possible subsets. If rank condition is violated, then the corresponding numbers of the parameters are stored - if ~no_identification_lre - lre_problpars{j} = indexj_dLRE(rankj_dLRE < j,:); + if ~no_identification_dynamic + dynamic_problpars{j} = indexj_dDYNAMIC(rankj_dDYNAMIC < j,:); end if ~no_identification_reducedform - reducedform_problpars{j} = indexj_dTAU(rankj_dTAU < j,:); + reducedform_problpars{j} = indexj_dREDUCEDFORM(rankj_dREDUCEDFORM < j,:); end - if ~no_identification_moments - moments_problpars{j} = indexj_J(rankj_J < j,:); + if ~no_identification_moments + moments_problpars{j} = indexj_dMOMENTS(rankj_dMOMENTS < j,:); end if ~no_identification_minimal - minimal_problpars{j} = indexj_D(rankj_D < (j+D_fixed_rank_nbr),:); + minimal_problpars{j} = indexj_dMINIMAL(rankj_dMINIMAL < (j+dMINIMAL_fixed_rank_nbr),:); end if ~no_identification_spectrum - spectrum_problpars{j} = indexj_G(rankj_G < j,:); + spectrum_problpars{j} = indexj_dSPECTRUM(rankj_dSPECTRUM < j,:); end % % Optional Step 5: % remove redundant 2-sets, eg. if the problematic sets are [(p1,p2);(p1,p3);(p2,p3)], then the unique problematic parameter sets are actually only [(p1,p2),(p1,p3)] % if j == 2 -% for jj=1:max([size(lre_problpars{2},1), size(reducedform_problpars{2},1), size(moments_problpars{2},1), size(spectrum_problpars{2},1), size(minimal_problpars{2},1)]) -% if jj <= size(lre_problpars{2},1) -% lre_problpars{2}(lre_problpars{2}(jj,2)==lre_problpars{2}(:,1)) = lre_problpars{2}(jj,1); +% for jj=1:max([size(dynamic_problpars{2},1), size(reducedform_problpars{2},1), size(moments_problpars{2},1), size(spectrum_problpars{2},1), size(minimal_problpars{2},1)]) +% if jj <= size(dynamic_problpars{2},1) +% dynamic_problpars{2}(dynamic_problpars{2}(jj,2)==dynamic_problpars{2}(:,1)) = dynamic_problpars{2}(jj,1); % end % if jj <= size(reducedform_problpars{2},1) % reducedform_problpars{2}(reducedform_problpars{2}(jj,2)==reducedform_problpars{2}(:,1)) = reducedform_problpars{2}(jj,1); @@ -393,13 +457,13 @@ for j=2:min(length(indtotparam),max_dim_subsets_groups) % Check j-element subset % minimal_problpars{2}(minimal_problpars{2}(jj,2)==minimal_problpars{2}(:,1)) = minimal_problpars{2}(jj,1); % end % end -% lre_problpars{2} = unique(lre_problpars{2},'rows'); +% dynamic_problpars{2} = unique(dynamic_problpars{2},'rows'); % reducedform_problpars{2} = unique(reducedform_problpars{2},'rows'); % moments_problpars{2} = unique(moments_problpars{2},'rows'); % spectrum_problpars{2} = unique(spectrum_problpars{2},'rows'); % minimal_problpars{2} = unique(minimal_problpars{2},'rows'); % % in indparam we replace the second parameter of problematic 2-sets by the observational equivalent first parameter to speed up nchoosek -% idx2 = unique([lre_problpars{2}; reducedform_problpars{2}; moments_problpars{2}; spectrum_problpars{2}; minimal_problpars{2}],'rows'); +% idx2 = unique([dynamic_problpars{2}; reducedform_problpars{2}; moments_problpars{2}; spectrum_problpars{2}; minimal_problpars{2}],'rows'); % if ~isempty(idx2) % indtotparam(ismember(indtotparam,idx2(:,2))) = []; % end @@ -408,10 +472,10 @@ for j=2:min(length(indtotparam),max_dim_subsets_groups) % Check j-element subset end %% Save output variables -if ~isempty(lre_problpars{1}) - lre_problpars{1}(ismember(lre_problpars{1},1:(totparam_nbr-modparam_nbr))) = []; % get rid of stderr and corr variables for lre +if ~isempty(dynamic_problpars{1}) + dynamic_problpars{1}(ismember(dynamic_problpars{1},1:(totparam_nbr-modparam_nbr))) = []; % get rid of stderr and corr variables for dynamic end -ide_lre.problpars = lre_problpars; +ide_dynamic.problpars = dynamic_problpars; ide_reducedform.problpars = reducedform_problpars; ide_moments.problpars = moments_problpars; ide_spectrum.problpars = spectrum_problpars; diff --git a/matlab/identification_numerical_objective.m b/matlab/identification_numerical_objective.m index 3de182d9f..48ba28bfc 100644 --- a/matlab/identification_numerical_objective.m +++ b/matlab/identification_numerical_objective.m @@ -29,18 +29,16 @@ function out = identification_numerical_objective(params, outputflag, estim_para % transition equation, Sig_e the covariance of exogenous shocks, g1 the % Jacobian of the dynamic model equations, and Y_t selected variables % ------------------------------------------------------------------------- -% This function is called by -% * get_first_order_solution_params_deriv.m (previously getH.m) +% This function is called by % * get_identification_jacobians.m (previously getJJ.m) % ------------------------------------------------------------------------- % This function calls % * [M.fname,'.dynamic'] -% * dynare_resolve % * dyn_vech -% * lyapunov_symm +% * resol % * vec % ========================================================================= -% Copyright (C) 2011-2019 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -58,29 +56,19 @@ function out = identification_numerical_objective(params, outputflag, estim_para % along with Dynare. If not, see . % ========================================================================= -if nargin < 11 || isempty(useautocorr) - useautocorr = 0; -end -if nargin < 12 || isempty(nlags) - nlags = 3; -end -if nargin < 13 || isempty(grid_nbr) - grid_nbr = 0; -end - %% Update stderr, corr and model parameters %note that if no estimated_params_block is given, then all stderr and model parameters are selected but no corr parameters if length(params) > length(indpmodel) if isempty(indpstderr)==0 && isempty(estim_params.var_exo) %if there are stderr parameters but no estimated_params_block %provide temporary necessary information for stderr parameters estim_params.nvx = length(indpstderr); - estim_params.var_exo = indpstderr'; + estim_params.var_exo = indpstderr'; end if isempty(indpmodel)==0 && isempty(estim_params.param_vals) %if there are model parameters but no estimated_params_block %provide temporary necessary information for model parameters estim_params.np = length(indpmodel); - estim_params.param_vals = indpmodel'; - end + estim_params.param_vals = indpmodel'; + end M = set_all_parameters(params,estim_params,M); %this function can only be used if there is some information in estim_params else %if there are only model parameters, we don't need to use set_all_parameters @@ -88,71 +76,39 @@ else end %% compute Kalman transition matrices and steady state with updated parameters -[A, B, ~, ~, M, options, oo] = dynare_resolve(M, options, oo); -ys = oo.dr.ys; %steady state of model variables in declaration order -y0 = ys(oo.dr.order_var); %steady state of model variables in DR order - -%% out = [Yss; vec(A); vec(B); dyn_vech(Sig_e)]; of indvar variables only, in DR order -if outputflag == 0 - out = [y0(indvar); vec(A(indvar,indvar)); vec(B(indvar,:)); dyn_vech(M.Sigma_e)]; -end - -%% out = [Yss; vec(A); dyn_vech(Om)]; of indvar variables only, in DR order -if outputflag == -2 - Om = B*M.Sigma_e*transpose(B); - out = [y0(indvar); vec(A(indvar,indvar)); dyn_vech(Om(indvar,indvar))]; -end +[~,info,M,options,oo] = resol(0,M,options,oo); +options = rmfield(options,'options_ident'); +pruned = pruned_state_space_system(M, options, oo.dr, indvar, nlags, useautocorr, 0); %% out = [vech(cov(Y_t,Y_t)); vec(cov(Y_t,Y_{t-1}); ...; vec(cov(Y_t,Y_{t-nlags})] of indvar variables, in DR order. This is Iskrev (2010)'s J matrix. -if outputflag == 1 - % Denote Ezz0 = E_t(z_t * z_t'), then the following Lyapunov equation defines the autocovariagrom: Ezz0 -A*Ezz*A' = B*Sig_e*B' - Ezz0 = lyapunov_symm(A,B*M.Sigma_e*B',options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,[],options.debug); - indzeros = find(abs(Ezz0) < 1e-12); %set small values to zero - Ezz0(indzeros) = 0; +if outputflag == 1 if useautocorr - sy = sqrt(diag(Ezz0)); - sy = sy*sy'; - sy0 = sy-diag(diag(sy))+eye(length(sy)); - Ezz0corr = Ezz0./sy0; - out = dyn_vech(Ezz0corr(indvar,indvar)); %focus only on unique terms + out = dyn_vech(pruned.Corr_y); else - out = dyn_vech(Ezz0(indvar,indvar)); %focus only on unique terms - end - % compute autocovariances/autocorrelations of lagged observed variables - for ii = 1:nlags - Ezzii = A^(ii)*Ezz0; - if useautocorr - Ezzii = Ezzii./sy; - end - out = [out;vec(Ezzii(indvar,indvar))]; + out = dyn_vech(pruned.Var_y); end + for i = 1:nlags + if useautocorr + out = [out;vec(pruned.Corr_yi(:,:,i))]; + else + out = [out;vec(pruned.Var_yi(:,:,i))]; + end + end end %% out = vec(g_omega). This is needed for Qu and Tkachenko (2012)'s G matrix. if outputflag == 2 -% This computes the spectral density g_omega where the interval [-pi;\pi] is discretized by grid_nbr points + % This computes the spectral density g_omega where the interval [-pi;\pi] is discretized by grid_nbr points freqs = (0 : pi/(grid_nbr/2):pi);% we focus only on positive values including the 0 frequency tpos = exp( sqrt(-1)*freqs); %Fourier frequencies - C = A(indvar,:); - D = B(indvar,:); - IA = eye(size(A,1)); - var_nbr = length(indvar); + IA = eye(size(pruned.A,1)); + var_nbr = size(pruned.C,1); out = zeros(var_nbr^2*length(freqs),1); kk = 0; for ig = 1:length(freqs) - Transferfct = D + C*((tpos(ig)*IA-A)\B); - g_omega = (1/(2*pi))*(Transferfct*M.Sigma_e*Transferfct'); % note that ' is the conjugate transpose + Transferfct = pruned.D + pruned.C*((tpos(ig)*IA-pruned.A)\pruned.B); + g_omega = (1/(2*pi))*(Transferfct*pruned.Varinov*Transferfct'); % note that ' is the conjugate transpose kk = kk+1; out(1 + (kk-1)*var_nbr^2 : kk*var_nbr^2) = g_omega(:); - end -end - - -%% out = [Yss; vec(g1)]; of all endogenous variables, in DR order -if outputflag == -1 - [I,~] = find(M.lead_lag_incidence'); %I is used to evaluate dynamic model files - yy0 = oo.dr.ys(I); %steady state of dynamic model variables in DR order - ex0 = oo.exo_steady_state'; - [~, g1] = feval([M.fname,'.dynamic'], yy0, ex0, M.params, ys, 1); - out = [y0; g1(:)]; -end + end +end \ No newline at end of file diff --git a/matlab/imcforecast.m b/matlab/imcforecast.m index dc3bca34c..0cf282b7b 100644 --- a/matlab/imcforecast.m +++ b/matlab/imcforecast.m @@ -28,7 +28,7 @@ function imcforecast(constrained_paths, constrained_vars, options_cond_fcst) % [1] Results are stored in oo_.conditional_forecast. % [2] Use the function plot_icforecast to plot the results. -% Copyright (C) 2006-2019 Dynare Team +% Copyright (C) 2006-2020 Dynare Team % % This file is part of Dynare. % @@ -204,9 +204,6 @@ if ~estimated_model trend = repmat(ys(oo_.dr.order_var,:),1,options_cond_fcst.periods+1); %trend needs to contain correct steady state end - - - NumberOfStates = length(InitState); FORCS1 = zeros(NumberOfStates,options_cond_fcst.periods+1,options_cond_fcst.replic); @@ -252,13 +249,17 @@ for b=1:options_cond_fcst.replic %conditional forecast using cL set to constrain [FORCS1(:,:,b), FORCS1_shocks(:,:,b)] = mcforecast3(cL,options_cond_fcst.periods,constrained_paths,shocks,FORCS1(:,:,b),T,R,mv, mu); FORCS1(:,:,b)=FORCS1(:,:,b)+trend; %add trend end - +if max(max(max(abs(bsxfun(@minus,FORCS1(constrained_vars,1+1:1+cL,:),trend(constrained_vars,1:cL)+constrained_paths)))))>1e-4 + fprintf('\nconditional_forecasts: controlling of variables was not successful.\n') + fprintf('This can be due to numerical imprecision (e.g. explosive simulations)\n') + fprintf('or because the instrument(s) do not allow controlling the variable(s).\n') +end mFORCS1 = mean(FORCS1,3); mFORCS1_shocks = mean(FORCS1_shocks,3); tt = (1-options_cond_fcst.conditional_forecast.conf_sig)/2; -t1 = round(options_cond_fcst.replic*tt); -t2 = round(options_cond_fcst.replic*(1-tt)); +t1 = max(1,round(options_cond_fcst.replic*tt)); +t2 = min(options_cond_fcst.replic,round(options_cond_fcst.replic*(1-tt))); forecasts.controlled_variables = constrained_vars; forecasts.instruments = options_cond_fcst.controlled_varexo; @@ -268,7 +269,7 @@ for i = 1:EndoSize if size(FORCS1,2)>1 tmp = sort(squeeze(FORCS1(i,:,:))'); else - tmp = sort(squeeze(FORCS1(i,:,:))); + tmp = sort(squeeze(FORCS1(i,:,:))); end forecasts.cond.ci.(M_.endo_names{oo_.dr.order_var(i)}) = [tmp(t1,:)' ,tmp(t2,:)' ]'; end @@ -278,7 +279,7 @@ for i = 1:n1 if size(FORCS1_shocks,2)>1 tmp = sort(squeeze(FORCS1_shocks(i,:,:))'); else - tmp = sort(squeeze(FORCS1_shocks(i,:,:))); + tmp = sort(squeeze(FORCS1_shocks(i,:,:))); end forecasts.controlled_exo_variables.ci.(options_cond_fcst.controlled_varexo{i}) = [tmp(t1,:)' ,tmp(t2,:)' ]'; end diff --git a/matlab/initial_condition_decomposition.m b/matlab/initial_condition_decomposition.m index 0c846b1ff..4b8ee9173 100644 --- a/matlab/initial_condition_decomposition.m +++ b/matlab/initial_condition_decomposition.m @@ -38,20 +38,35 @@ function oo_ = initial_condition_decomposition(M_,oo_,options_,varlist,bayestopt % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +options_.plot_shock_decomp.colormap = options_.initial_condition_decomp.colormap; +options_.plot_shock_decomp.nodisplay = options_.initial_condition_decomp.nodisplay; +options_.plot_shock_decomp.graph_format = options_.initial_condition_decomp.graph_format; +options_.plot_shock_decomp.fig_name = options_.initial_condition_decomp.fig_name; options_.plot_shock_decomp.detail_plot = options_.initial_condition_decomp.detail_plot; +options_.plot_shock_decomp.init2shocks = options_.initial_condition_decomp.init2shocks; options_.plot_shock_decomp.steadystate = options_.initial_condition_decomp.steadystate; options_.plot_shock_decomp.write_xls = options_.initial_condition_decomp.write_xls; options_.plot_shock_decomp.type = options_.initial_condition_decomp.type; options_.plot_shock_decomp.plot_init_date = options_.initial_condition_decomp.plot_init_date; options_.plot_shock_decomp.plot_end_date = options_.initial_condition_decomp.plot_end_date; +options_.plot_shock_decomp.diff = options_.initial_condition_decomp.diff; +options_.plot_shock_decomp.flip = options_.initial_condition_decomp.flip; +options_.plot_shock_decomp.max_nrows = options_.initial_condition_decomp.max_nrows; +if isfield(options_.initial_condition_decomp,'init2shocks') % private trap for uimenu calls + init2shocks=options_.initial_condition_decomp.init2shocks; +else + init2shocks=[]; +end % indices of endogenous variables if isempty(varlist) varlist = M_.endo_names(1:M_.orig_endo_nbr); end -[i_var, nvar, index_uniques] = varlist_indices(varlist, M_.endo_names); -varlist = varlist(index_uniques); +if ~isequal(varlist,0) + [i_var, nvar, index_uniques] = varlist_indices(varlist, M_.endo_names); + varlist = varlist(index_uniques); +end % number of variables endo_nbr = M_.endo_nbr; @@ -71,7 +86,17 @@ if isempty(parameter_set) end end -if ~isfield(oo_,'initval_decomposition') +if ~isfield(oo_,'initval_decomposition') || isequal(varlist,0) + if isfield(oo_,'shock_decomposition_info') && isfield(oo_.shock_decomposition_info,'i_var') + if isfield (oo_,'realtime_conditional_shock_decomposition') ... + || isfield (oo_,'realtime_forecast_shock_decomposition') ... + || isfield (oo_,'realtime_shock_decomposition') ... + || isfield (oo_,'conditional_shock_decomposition') ... + || isfield (oo_,'shock_decomposition') + error('initval_decomposition::squeezed shock decompositions are already stored in oo_') + end + end + with_epilogue = options_.initial_condition_decomp.with_epilogue; options_.selected_variables_only = 0; %make sure all variables are stored options_.plot_priors=0; [oo,M,~,~,Smoothed_Variables_deviation_from_mean] = evaluate_smoother(parameter_set,varlist,M_,oo_,options_,bayestopt_,estim_params_); @@ -117,22 +142,36 @@ if ~isfield(oo_,'initval_decomposition') end - + if with_epilogue + [z, epilogue_steady_state] = epilogue_shock_decomposition(z, M_, oo_); + if ~isfield(oo_,'shock_decomposition_info') || ~isfield(oo_.shock_decomposition_info,'epilogue_steady_state') + oo_.shock_decomposition_info.epilogue_steady_state = epilogue_steady_state; + end + end oo_.initval_decomposition = z; end -% if ~options_.no_graph.shock_decomposition -oo=oo_; -oo.shock_decomposition = oo_.initval_decomposition; -M_.exo_names = M_.endo_names; -M_.exo_nbr = M_.endo_nbr; -options_.plot_shock_decomp.realtime=0; -options_.plot_shock_decomp.screen_shocks=1; -options_.plot_shock_decomp.use_shock_groups = ''; -fig_name = options_.plot_shock_decomp.fig_name; -if ~isempty(fig_name) - options_.plot_shock_decomp.fig_name=[fig_name '_initval']; -else -options_.plot_shock_decomp.fig_name='initval'; -end -plot_shock_decomposition(M_,oo,options_,varlist); -% end \ No newline at end of file + +% when varlist==0, we only store results in oo_ and do not make any plot +if ~isequal(varlist,0) + + % if ~options_.no_graph.shock_decomposition + oo=oo_; + oo.shock_decomposition = oo_.initval_decomposition; + if ~isempty(init2shocks) + init2shocks = M_.init2shocks.(init2shocks); + n=size(init2shocks,1); + for i=1:n + j=strmatch(init2shocks{i}{1},M_.endo_names,'exact'); + oo.shock_decomposition(:,end-1,:)=oo.shock_decomposition(:,j,:)+oo.shock_decomposition(:,end-1,:); + oo.shock_decomposition(:,j,:)=0; + end + end + M_.exo_names = M_.endo_names; + M_.exo_nbr = M_.endo_nbr; + options_.plot_shock_decomp.realtime=0; + options_.plot_shock_decomp.screen_shocks=1; + options_.plot_shock_decomp.use_shock_groups = ''; + options_.plot_shock_decomp.init_cond_decomp = 1; % private flag to plotting utilities + + plot_shock_decomposition(M_,oo,options_,varlist); +end diff --git a/matlab/initial_estimation_checks.m b/matlab/initial_estimation_checks.m index d384b5f86..39a45d155 100644 --- a/matlab/initial_estimation_checks.m +++ b/matlab/initial_estimation_checks.m @@ -41,8 +41,16 @@ function DynareResults = initial_estimation_checks(objective_function,xparam1,Dy %singularity check maximum_number_non_missing_observations=max(sum(~isnan(DynareDataset.data),2)); -if DynareOptions.order>1 && any(any(isnan(DynareDataset.data))) - error('initial_estimation_checks:: particle filtering does not support missing observations') +if DynareOptions.order>1 + if any(any(isnan(DynareDataset.data))) + error('initial_estimation_checks:: particle filtering does not support missing observations') + end + if DynareOptions.prefilter==1 + error('initial_estimation_checks:: particle filtering does not support the prefilter option') + end + if BayesInfo.with_trend + error('initial_estimation_checks:: particle filtering does not support trends') + end end non_zero_ME=length(EstimatedParameters.H_entries_to_check_for_positive_definiteness); diff --git a/matlab/interpret_resol_info.m b/matlab/interpret_resol_info.m deleted file mode 100644 index 43e21598d..000000000 --- a/matlab/interpret_resol_info.m +++ /dev/null @@ -1,60 +0,0 @@ -function message = interpret_resol_info(info) - -% Returns a message describing problem encountered during the resolution of -% a model. -% -% INPUTS -% - info [struct] Second output argument return by the resol routine -% -% OUTPUTS -% - message [string] Description of the issue preventing model's resolution. - -% Copyright (C) 2001-2017 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 . - -switch info(1) - case 0 - message = ''; - case 1 - message = 'The model doesn''t determine the current variable uniquely.'; - case 2 - message = 'MJDGGES (Generalized Schur decomposition) returned an error code.'; - case 3 - message = 'Blanchard & Kahn conditions are not satisfied: no stable equilibrium.'; - case 4 - message = 'Blanchard & Kahn conditions are not satisfied: indeterminacy.'; - case 5 - message = 'Blanchard & Kahn conditions are not satisfied: indeterminacy due to rank failure.'; - case 6 - message = 'The jacobian evaluated at the deterministic steady state is complex.'; - case 19 - message = 'The steadystate routine has thrown an exception (inconsistent deep parameters).'; - case 20 - message = sprintf('Cannot find the steady state (the sum of square residuals of the static equations is %s)', num2str(info(2))); - case 21 - message = sprintf('The steady state is complex (the sum of square residuals of imaginary parts of the steady state is %s)', num2str(info(2))); - case 22 - message = 'The steady state has NaNs.'; - case 23 - message = 'Parameters have been updated in the steadystate routine and some have complex values.'; - case 24 - message = 'Parameters have been updated in the steadystate routine and some are NaNs.'; - case 30 - message = 'Ergodic variance can''t be computed.'; - otherwise - message = 'Unknown issue!'; -end \ No newline at end of file diff --git a/matlab/irf.m b/matlab/irf.m index d1c7014e8..33f9e9fb1 100644 --- a/matlab/irf.m +++ b/matlab/irf.m @@ -43,7 +43,7 @@ end y = 0; local_order = iorder; -if M_.hessian_eq_zero && local_order~=1 +if local_order~=1 && M_.hessian_eq_zero local_order = 1; end diff --git a/matlab/isauxiliary.m b/matlab/isauxiliary.m index a668556c0..da57d5ed0 100644 --- a/matlab/isauxiliary.m +++ b/matlab/isauxiliary.m @@ -12,7 +12,7 @@ function b = isauxiliary(var, types) % REMARKS % % Types for auxiliary variables are as follows: -% +% % - 0, Lead on endogenous variable (substitute for endo leads >= 2) % - 1, Lag on endogenous variable (ubstitute for endo lags >= 2) % - 2, Lead on exogenous variable (ubstitute for exo leads >= 1) diff --git a/matlab/isdiff.m b/matlab/isdiff.m index b61967e37..9eae16dd4 100644 --- a/matlab/isdiff.m +++ b/matlab/isdiff.m @@ -1,6 +1,6 @@ function boo = isdiff(var) -% Returns true iff endogenous variable `var` is a v ariable in difference. +% Returns true iff endogenous variable `var` is a v ariable in difference. % % INPUTS % - var [string, integer] Variable name or index in M_.endo_names. @@ -33,5 +33,5 @@ boo = false; if ~ida, return, end if ismember(M_.aux_vars(ida).type, [8, 9]) - boo = true; + boo = true; end \ No newline at end of file diff --git a/matlab/k_order_pert.m b/matlab/k_order_pert.m index 7627970ce..beaa621b6 100644 --- a/matlab/k_order_pert.m +++ b/matlab/k_order_pert.m @@ -1,7 +1,7 @@ function [dr,info] = k_order_pert(dr,M,options) % Compute decision rules using the k-order DLL from Dynare++ -% Copyright (C) 2009-2018 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -30,8 +30,9 @@ if M.maximum_endo_lead == 0 && order>1 'backward models']) end -[err, dynpp_derivs, dyn_derivs] = k_order_perturbation(dr,M,options); -if err +try + [dynpp_derivs, dyn_derivs] = k_order_perturbation(dr,M,options); +catch info(1)=9; return end diff --git a/matlab/kalman/likelihood/kalman_filter.m b/matlab/kalman/likelihood/kalman_filter.m index 441ee8525..ec26524eb 100644 --- a/matlab/kalman/likelihood/kalman_filter.m +++ b/matlab/kalman/likelihood/kalman_filter.m @@ -158,6 +158,7 @@ else LIKK={likk,dlikk}; end +rescale_prediction_error_covariance0=rescale_prediction_error_covariance; while notsteady && t<=last s = t-start+1; if Zflag @@ -175,7 +176,12 @@ while notsteady && t<=last end else if rcond(F) 0.01 || isinf(marginal(1,2)) + if abs((marginal(9,2)-marginal(1,2))/marginal(9,2)) > options_.marginal_data_density.harmonic_mean.tolerance || isinf(marginal(1,2)) fprintf('\n') if increase == 1 disp('Estimation::marginal density: The support of the weighting density function is not large enough...') diff --git a/matlab/mcforecast3.m b/matlab/mcforecast3.m index 31215e434..5689ddc8e 100644 --- a/matlab/mcforecast3.m +++ b/matlab/mcforecast3.m @@ -1,5 +1,5 @@ function [forcs, e]= mcforecast3(cL,H,mcValue,shocks,forcs,T,R,mv,mu) -% forcs = mcforecast3(cL,H,mcValue,shocks,forcs,T,R,mv,mu) +% [forcs, e] = mcforecast3(cL,H,mcValue,shocks,forcs,T,R,mv,mu) % Computes the shock values for constrained forecasts necessary to keep % endogenous variables at their constrained paths % @@ -7,13 +7,15 @@ function [forcs, e]= mcforecast3(cL,H,mcValue,shocks,forcs,T,R,mv,mu) % o cL [scalar] number of controlled periods % o H [scalar] number of forecast periods % o mcValue [n_controlled_vars by cL double] paths for constrained variables -% o shocks [nexo by H double] shock values draws (with zeros for controlled_varexo) -% o forcs -% o T [n_endovars by n_endovars double] transition matrix of the state equation. -% o R [n_endovars by n_exo double] matrix relating the endogenous variables to the innovations in the state equation. -% o mv [n_controlled_exo by n_endovars boolean] indicator vector selecting constrained endogenous variables -% o mu [n_controlled_vars by nexo boolean] indicator vector -% selecting controlled exogenous variables +% o shocks [nexo by H double] shock values draws (with zeros for controlled_varexo) +% o forcs [n_endovars by H+1 double] matrix of endogenous variables storing the inital condition +% o T [n_endovars by n_endovars double] transition matrix of the state equation. +% o R [n_endovars by n_exo double] matrix relating the endogenous variables to the innovations in the state equation. +% o mv [n_controlled_exo by n_endovars boolean] indicator vector selecting constrained endogenous variables +% o mu [n_controlled_vars by nexo boolean] indicator vector selecting controlled exogenous variables +% OUTPUTS +% o forcs [n_endovars by H+1 double] matrix of forecasted endogenous variables +% o e [nexo by H double] matrix of exogenous variables % % Algorithm: % Relies on state-space form: @@ -29,7 +31,7 @@ function [forcs, e]= mcforecast3(cL,H,mcValue,shocks,forcs,T,R,mv,mu) % % Variable number of controlled vars are allowed in different % periods. Missing control information are indicated by NaN in -% y_t(controlled_vars_index). +% y_t(controlled_vars_index). % % After obtaining the shocks, and for uncontrolled periods, the state-space representation % y_t=T*y_{t-1}+R*shocks(:,t) diff --git a/matlab/mex/k_order_perturbation.m b/matlab/mex/k_order_perturbation.m index 2f4b1eec9..15e34a7ce 100644 --- a/matlab/mex/k_order_perturbation.m +++ b/matlab/mex/k_order_perturbation.m @@ -1,4 +1,4 @@ -% [err, dynpp_derivs, dyn_derivs] = k_order_perturbation(dr,DynareModel,DynareOptions,g1,g2,g3) +% [dynpp_derivs, dyn_derivs] = k_order_perturbation(dr,DynareModel,DynareOptions,g1,g2,g3) % computes a k_order_petrubation solution for k=1,2,3 % % INPUTS @@ -10,7 +10,6 @@ % g3: matrix Third order derivatives of the model (optional) % % OUTPUTS -% err: double error code % dynpp_derivs struct Derivatives of the decision rule in Dynare++ format. % The tensors are folded and the Taylor coefficients (1/n!) are % included. @@ -29,7 +28,7 @@ % dynare/mex/sources/k_order_perturbation.cc and it uses code provided by % dynare++ -% Copyright (C) 2013-2017 Dynare Team +% Copyright (C) 2013-2020 Dynare Team % % This file is part of Dynare. % diff --git a/matlab/missing/contains/contains.m b/matlab/missing/contains/contains.m index 56d6f981b..7c6470494 100644 --- a/matlab/missing/contains/contains.m +++ b/matlab/missing/contains/contains.m @@ -1,17 +1,17 @@ function tf = contains(string, pattern, varargin) % CONTAINS Returns 1 if the pattern is found in string, and 0 otherwise. -% +% % INPUTS % - string [string, char, cell(str)] String to be searhced. -% - pattern [string, char, cell(str)] The searched pattern. +% - pattern [string, char, cell(str)] The searched pattern. % -% If 'IgnoreCase',IGNORE is provided, the function ignores case if IGNORE is true. +% If 'IgnoreCase',IGNORE is provided, the function ignores case if IGNORE is true. % The default value is false. -% +% % OUTPUT % - tf [logical] -% +% % Copyright (C) 2019 Dynare Team % % This file is part of Dynare. diff --git a/matlab/missing/corrcoef/corrcoef.m b/matlab/missing/corrcoef/corrcoef.m deleted file mode 100644 index 893fd7c57..000000000 --- a/matlab/missing/corrcoef/corrcoef.m +++ /dev/null @@ -1,385 +0,0 @@ -function [R,sig,ci1,ci2,nan_sig] = corrcoef(X,Y,varargin) -% CORRCOEF calculates the correlation matrix from pairwise correlations. -% The input data can contain missing values encoded with NaN. -% Missing data (NaN's) are handled by pairwise deletion [15]. -% In order to avoid possible pitfalls, use case-wise deletion or -% or check the correlation of NaN's with your data (see below). -% A significance test for testing the Hypothesis -% 'correlation coefficient R is significantly different to zero' -% is included. -% -% [...] = CORRCOEF(X); -% calculates the (auto-)correlation matrix of X -% [...] = CORRCOEF(X,Y); -% calculates the crosscorrelation between X and Y -% -% [...] = CORRCOEF(..., Mode); -% Mode='Pearson' or 'parametric' [default] -% gives the correlation coefficient -% also known as the 'product-moment coefficient of correlation' -% or 'Pearson''s correlation' [1] -% Mode='Spearman' gives 'Spearman''s Rank Correlation Coefficient' -% This replaces SPEARMAN.M -% Mode='Rank' gives a nonparametric Rank Correlation Coefficient -% This is the "Spearman rank correlation with proper handling of ties" -% This replaces RANKCORR.M -% -% [...] = CORRCOEF(..., param1, value1, param2, value2, ... ); -% param value -% 'Mode' type of correlation -% 'Pearson','parametric' -% 'Spearman' -% 'rank' -% 'rows' how do deal with missing values encoded as NaN's. -% 'complete': remove all rows with at least one NaN -% 'pairwise': [default] -% 'alpha' 0.01 : significance level to compute confidence interval -% -% [R,p,ci1,ci2,nansig] = CORRCOEF(...); -% R is the correlation matrix -% R(i,j) is the correlation coefficient r between X(:,i) and Y(:,j) -% p gives the significance of R -% It tests the null hypothesis that the product moment correlation coefficient is zero -% using Student's t-test on the statistic t = r*sqrt(N-2)/sqrt(1-r^2) -% where N is the number of samples (Statistics, M. Spiegel, Schaum series). -% p > alpha: do not reject the Null hypothesis: 'R is zero'. -% p < alpha: The alternative hypothesis 'R is larger than zero' is true with probability (1-alpha). -% ci1 lower (1-alpha) confidence interval -% ci2 upper (1-alpha) confidence interval -% If no alpha is provided, the default alpha is 0.01. This can be changed with function flag_implicit_significance. -% nan_sig p-value whether H0: 'NaN''s are not correlated' could be correct -% if nan_sig < alpha, H1 ('NaNs are correlated') is very likely. -% -% The result is only valid if the occurence of NaN's is uncorrelated. In -% order to avoid this pitfall, the correlation of NaN's should be checked -% or case-wise deletion should be applied. -% Case-Wise deletion can be implemented -% ix = ~any(isnan([X,Y]),2); -% [...] = CORRCOEF(X(ix,:),Y(ix,:),...); -% -% Correlation (non-random distribution) of NaN's can be checked with -% [nan_R,nan_sig]=corrcoef(X,isnan(X)) -% or [nan_R,nan_sig]=corrcoef([X,Y],isnan([X,Y])) -% or [R,p,ci1,ci2] = CORRCOEF(...); -% -% Further recommandation related to the correlation coefficient: -% + LOOK AT THE SCATTERPLOTS to make sure that the relationship is linear -% + Correlation is not causation because -% it is not clear which parameter is 'cause' and which is 'effect' and -% the observed correlation between two variables might be due to the action of other, unobserved variables. -% -% see also: SUMSKIPNAN, COVM, COV, COR, SPEARMAN, RANKCORR, RANKS, -% PARTCORRCOEF, flag_implicit_significance -% -% REFERENCES: -% on the correlation coefficient -% [ 1] http://mathworld.wolfram.com/CorrelationCoefficient.html -% [ 2] http://www.geography.btinternet.co.uk/spearman.htm -% [ 3] Hogg, R. V. and Craig, A. T. Introduction to Mathematical Statistics, 5th ed. New York: Macmillan, pp. 338 and 400, 1995. -% [ 4] Lehmann, E. L. and D'Abrera, H. J. M. Nonparametrics: Statistical Methods Based on Ranks, rev. ed. Englewood Cliffs, NJ: Prentice-Hall, pp. 292, 300, and 323, 1998. -% [ 5] Press, W. H.; Flannery, B. P.; Teukolsky, S. A.; and Vetterling, W. T. Numerical Recipes in FORTRAN: The Art of Scientific Computing, 2nd ed. Cambridge, England: Cambridge University Press, pp. 634-637, 1992 -% [ 6] http://mathworld.wolfram.com/SpearmanRankCorrelationCoefficient.html -% on the significance test of the correlation coefficient -% [11] http://www.met.rdg.ac.uk/cag/STATS/corr.html -% [12] http://www.janda.org/c10/Lectures/topic06/L24-significanceR.htm -% [13] http://faculty.vassar.edu/lowry/ch4apx.html -% [14] http://davidmlane.com/hyperstat/B134689.html -% [15] http://www.statsoft.com/textbook/stbasic.html%Correlations -% others -% [20] http://www.tufts.edu/~gdallal/corr.htm -% [21] Fisher transformation http://en.wikipedia.org/wiki/Fisher_transformation - -% $Id: corrcoef.m 9387 2011-12-15 10:42:14Z schloegl $ -% Copyright (C) 2000-2004,2008,2009,2011 by Alois Schloegl -% Copyright (C) 2014-2017 Dynare Team -% This function is part of the NaN-toolbox -% http://pub.ist.ac.at/~schloegl/matlab/NaN/ - -% This program 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. -% -% This program 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 this program. If not, see . - -% Features: -% + handles missing values (encoded as NaN's) -% + pairwise deletion of missing data -% + checks independence of missing values (NaNs) -% + parametric and non-parametric (rank) correlation -% + Pearson's correlation -% + Spearman's rank correlation -% + Rank correlation (non-parametric, Spearman rank correlation with proper handling of ties) -% + is fast, using an efficient algorithm O(n.log(n)) for calculating the ranks -% + significance test for null-hypthesis: r=0 -% + confidence interval included -% - rank correlation works for cell arrays, too (no check for missing values). -% + compatible with Octave and Matlab - -global FLAG_NANS_OCCURED; - -NARG = nargout; % needed because nargout is not reentrant in Octave, and corrcoef is recursive -mode = []; - -if nargin==1 - Y = []; - Mode='Pearson'; -elseif nargin==0 - fprintf(2,'Error CORRCOEF: Missing argument(s)\n'); -elseif nargin>1 - if ischar(Y) - varg = [Y,varargin]; - Y=[]; - else - varg = varargin; - end - - if length(varg)<1 - Mode = 'Pearson'; - elseif length(varg)==1 - Mode = varg{1}; - else - for k = 2:2:length(varg) - mode = setfield(mode,lower(varg{k-1}),varg{k}); - end - if isfield(mode,'mode') - Mode = mode.mode; - end - end -end -if isempty(Mode), Mode='pearson'; end -Mode=[Mode,' ']; - - - -FLAG_WARNING = warning; % save warning status -warning('off'); - -[r1,c1]=size(X); -if ~isempty(Y) - [r2,c2]=size(Y); - if r1~=r2 - fprintf(2,'Error CORRCOEF: X and Y must have the same number of observations (rows).\n'); - return - end - NN = real(~isnan(X)')*real(~isnan(Y)); -else - [r2,c2]=size(X); - NN = real(~isnan(X)')*real(~isnan(X)); -end - -%%%%% generate combinations using indices for pairwise calculation of the correlation -YESNAN = any(isnan(X(:))) | any(isnan(Y(:))); -if YESNAN - FLAG_NANS_OCCURED=(1==1); - if isfield(mode,'rows') - if strcmp(mode.rows,'complete') - ix = ~any([X,Y],2); - X = X(ix,:); - if ~isempty(Y) - Y = Y(ix,:); - end - YESNAN = 0; - NN = size(X,1); - elseif strcmp(mode.rows,'all') - fprintf(1,'Warning: data contains NaNs, rows=pairwise is used.'); - %%NN(NN < size(X,1)) = NaN; - elseif strcmp(mode.rows,'pairwise') - %%% default - end - end -end -if isempty(Y) - IX = ones(c1)-diag(ones(c1,1)); - [jx, jy ] = find(IX); - [jxo,jyo] = find(IX); - R = eye(c1); -else - IX = sparse([],[],[],c1+c2,c1+c2,c1*c2); - IX(1:c1,c1+(1:c2)) = 1; - [jx,jy] = find(IX); - - IX = ones(c1,c2); - [jxo,jyo] = find(IX); - R = zeros(c1,c2); -end - -if strcmp(lower(Mode(1:7)),'pearson') - % see http://mathworld.wolfram.com/CorrelationCoefficient.html - if ~YESNAN - [S,N,SSQ] = sumskipnan(X,1); - if ~isempty(Y) - [S2,N2,SSQ2] = sumskipnan(Y,1); - CC = X'*Y; - M1 = S./N; - M2 = S2./N2; - cc = CC./NN - M1'*M2; - R = cc./sqrt((SSQ./N-M1.*M1)'*(SSQ2./N2-M2.*M2)); - else - CC = X'*X; - M = S./N; - cc = CC./NN - M'*M; - v = SSQ./N - M.*M; %max(N-1,0); - R = cc./sqrt(v'*v); - end - else - if ~isempty(Y) - X = [X,Y]; - end - for k = 1:length(jx) - %ik = ~any(isnan(X(:,[jx(k),jy(k)])),2); - ik = ~isnan(X(:,jx(k))) & ~isnan(X(:,jy(k))); - [s,n,s2] = sumskipnan(X(ik,[jx(k),jy(k)]),1); - v = (s2-s.*s./n)./n; - cc = X(ik,jx(k))'*X(ik,jy(k)); - cc = cc/n(1) - prod(s./n); - %r(k) = cc./sqrt(prod(v)); - R(jxo(k),jyo(k)) = cc./sqrt(prod(v)); - end - end - -elseif strcmp(lower(Mode(1:4)),'rank') - % see [ 6] http://mathworld.wolfram.com/SpearmanRankCorrelationCoefficient.html - if ~YESNAN - if isempty(Y) - R = corrcoef(ranks(X)); - else - R = corrcoef(ranks(X),ranks(Y)); - end - else - if ~isempty(Y) - X = [X,Y]; - end - for k = 1:length(jx) - %ik = ~any(isnan(X(:,[jx(k),jy(k)])),2); - ik = ~isnan(X(:,jx(k))) & ~isnan(X(:,jy(k))); - il = ranks(X(ik,[jx(k),jy(k)])); - R(jxo(k),jyo(k)) = corrcoef(il(:,1),il(:,2)); - end - X = ranks(X); - end - -elseif strcmp(lower(Mode(1:8)),'spearman') - % see [ 6] http://mathworld.wolfram.com/SpearmanRankCorrelationCoefficient.html - if ~isempty(Y) - X = [X,Y]; - end - - n = repmat(nan,c1,c2); - - if ~YESNAN - iy = ranks(X); % calculates ranks; - - for k = 1:length(jx) - [R(jxo(k),jyo(k)),n(jxo(k),jyo(k))] = sumskipnan((iy(:,jx(k)) - iy(:,jy(k))).^2); % NN is the number of non-missing values - end - else - for k = 1:length(jx) - %ik = ~any(isnan(X(:,[jx(k),jy(k)])),2); - ik = ~isnan(X(:,jx(k))) & ~isnan(X(:,jy(k))); - il = ranks(X(ik,[jx(k),jy(k)])); - % NN is the number of non-missing values - [R(jxo(k),jyo(k)),n(jxo(k),jyo(k))] = sumskipnan((il(:,1) - il(:,2)).^2); - end - X = ranks(X); - end - R = 1 - 6 * R ./ (n.*(n.*n-1)); - -elseif strcmp(lower(Mode(1:7)),'partial') - fprintf(2,'Error CORRCOEF: use PARTCORRCOEF \n',Mode); - - return - -elseif strcmp(lower(Mode(1:7)),'kendall') - fprintf(2,'Error CORRCOEF: mode ''%s'' not implemented yet.\n',Mode); - - return -else - fprintf(2,'Error CORRCOEF: unknown mode ''%s''\n',Mode); -end - -if (NARG<2) - warning(FLAG_WARNING); % restore warning status - return -end - - -% CONFIDENCE INTERVAL -if isfield(mode,'alpha') - alpha = mode.alpha; -elseif exist('flag_implicit_significance','file') - alpha = flag_implicit_significance; -else - alpha = 0.01; -end -% fprintf(1,'CORRCOEF: confidence interval is based on alpha=%f\n',alpha); - - -% SIGNIFICANCE TEST -R(isnan(R))=0; -tmp = 1 - R.*R; -tmp(tmp<0) = 0; % prevent tmp<0 i.e. imag(t)~=0 -t = R.*sqrt(max(NN-2,0)./tmp); - -if exist('t_cdf','file') - sig = t_cdf(t,NN-2); -elseif exist('tcdf','file')>1 - sig = tcdf(t,NN-2); -else - fprintf('CORRCOEF: significance test not completed because of missing TCDF-function\n') - sig = repmat(nan,size(R)); -end -sig = 2 * min(sig,1 - sig); - - -if NARG<3 - warning(FLAG_WARNING); % restore warning status - return -end - - -tmp = R; -%tmp(ix1 | ix2) = nan; % avoid division-by-zero warning -z = log((1+tmp)./(1-tmp))/2; % Fisher transformation [21] - %sz = 1./sqrt(NN-3); % standard error of z -sz = sqrt(2)*erfinv(1-alpha)./sqrt(NN-3); % confidence interval for alpha of z - -ci1 = tanh(z-sz); -ci2 = tanh(z+sz); - -%ci1(isnan(ci1))=R(isnan(ci1)); % in case of isnan(ci), the interval limits are exactly the R value -%ci2(isnan(ci2))=R(isnan(ci2)); - -if (NARG<5) || ~YESNAN - nan_sig = repmat(NaN,size(R)); - warning(FLAG_WARNING); % restore warning status - return -end - -%%%%% ----- check independence of NaNs (missing values) ----- -[nan_R, nan_sig] = corrcoef(X,double(isnan(X))); - -% remove diagonal elements, because these have not any meaning % -nan_sig(isnan(nan_R)) = nan; -% remove diagonal elements, because these have not any meaning % -nan_R(isnan(nan_R)) = 0; - -if 0, any(nan_sig(:) < alpha) - tmp = nan_sig(:); % Hack to skip NaN's in MIN(X) - min_sig = min(tmp(~isnan(tmp))); % Necessary, because Octave returns NaN rather than min(X) for min(NaN,X) - fprintf(1,'CORRCOFF Warning: Missing Values (i.e. NaNs) are not independent of data (p-value=%f)\n', min_sig); - fprintf(1,' Its recommended to remove all samples (i.e. rows) with any missing value (NaN).\n'); - fprintf(1,' The null-hypotheses (NaNs are uncorrelated) is rejected for the following parameter pair(s).\n'); - [ix,iy] = find(nan_sig < alpha); - disp([ix,iy]) -end - -%%%%% ----- end of independence check ------ - -warning(FLAG_WARNING); % restore warning status diff --git a/matlab/missing/corrcoef/flag_implicit_skip_nan.m b/matlab/missing/corrcoef/flag_implicit_skip_nan.m deleted file mode 100644 index e8fd0fec6..000000000 --- a/matlab/missing/corrcoef/flag_implicit_skip_nan.m +++ /dev/null @@ -1,67 +0,0 @@ -function FLAG = flag_implicit_skip_nan(i) -% FLAG_IMPLICIT_SKIP_NAN sets and gets default mode for handling NaNs -% 1 skips NaN's (the default mode if no mode is set) -% 0 NaNs are propagated; input NaN's give NaN's at the output -% -% FLAG = flag_implicit_skip_nan() -% gets current mode -% -% flag_implicit_skip_nan(FLAG) % sets mode -% -% prevFLAG = flag_implicit_skip_nan(nextFLAG) -% gets previous set FLAG and sets FLAG for the future -% flag_implicit_skip_nan(prevFLAG) -% resets FLAG to previous mode -% -% It is used in: -% SUMSKIPNAN, MEDIAN, QUANTILES, TRIMEAN -% and affects many other functions like: -% CENTER, KURTOSIS, MAD, MEAN, MOMENT, RMS, SEM, SKEWNESS, -% STATISTIC, STD, VAR, ZSCORE etc. -% -% The mode is stored in the global variable FLAG_implicit_skip_nan -% It is recommended to use flag_implicit_skip_nan(1) as default and -% flag_implicit_skip_nan(0) should be used for exceptional cases only. -% This feature might disappear without further notice, so you should really not -% rely on it. - - -% This program 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. -% -% This program 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 this program; if not, write to the Free Software -% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -% $Id: flag_implicit_skip_nan.m 8351 2011-06-24 17:35:07Z carandraug $ - -% Copyright (C) 2001-2003,2009 by Alois Schloegl -% Copyright (C) 2014-2017 Dynare Team -% -% This function is part of the NaN-toolbox -% http://pub.ist.ac.at/~schloegl/matlab/NaN/ - - -persistent FLAG_implicit_skip_nan; - -%% if strcmp(version,'3.6'), FLAG_implicit_skip_nan=(1==1); end; %% hack for the use with Freemat3.6 - -%%% set DEFAULT value of FLAG -if isempty(FLAG_implicit_skip_nan) - FLAG_implicit_skip_nan = (1==1); %logical(1); % logical.m not available on 2.0.16 -end - -FLAG = FLAG_implicit_skip_nan; -if nargin>0 - FLAG_implicit_skip_nan = (i~=0); %logical(i); %logical.m not available in 2.0.16 - if (~i) - warning('flag_implicit_skipnan(0): You are warned!!! You have turned off skipping NaN in sumskipnan. This is not recommended. Make sure you really know what you do.') - end -end diff --git a/matlab/missing/corrcoef/sumskipnan.m b/matlab/missing/corrcoef/sumskipnan.m deleted file mode 100644 index a1054c3f8..000000000 --- a/matlab/missing/corrcoef/sumskipnan.m +++ /dev/null @@ -1,192 +0,0 @@ -function [o,count,SSQ] = sumskipnan(x, DIM, W) -% SUMSKIPNAN adds all non-NaN values. -% -% All NaN's are skipped; NaN's are considered as missing values. -% SUMSKIPNAN of NaN's only gives O; and the number of valid elements is return. -% SUMSKIPNAN is also the elementary function for calculating -% various statistics (e.g. MEAN, STD, VAR, RMS, MEANSQ, SKEWNESS, -% KURTOSIS, MOMENT, STATISTIC etc.) from data with missing values. -% SUMSKIPNAN implements the DIMENSION-argument for data with missing values. -% Also the second output argument return the number of valid elements (not NaNs) -% -% Y = sumskipnan(x [,DIM]) -% [Y,N,SSQ] = sumskipnan(x [,DIM]) -% [...] = sumskipnan(x, DIM, W) -% -% x input data -% DIM dimension (default: []) -% empty DIM sets DIM to first non singleton dimension -% W weight vector for weighted sum, numel(W) must fit size(x,DIM) -% Y resulting sum -% N number of valid (not missing) elements -% SSQ sum of squares -% -% the function FLAG_NANS_OCCURED() returns whether any value in x -% is a not-a-number (NaN) -% -% features: -% - can deal with NaN's (missing values) -% - implements dimension argument. -% - computes weighted sum -% - compatible with Matlab and Octave -% -% see also: FLAG_NANS_OCCURED, SUM, NANSUM, MEAN, STD, VAR, RMS, MEANSQ, -% SSQ, MOMENT, SKEWNESS, KURTOSIS, SEM - - -% This program 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. -% -% This program 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 this program; If not, see . - -% $Id: sumskipnan.m 9033 2011-11-08 20:58:07Z schloegl $ -% -% Copyright (C) 2000-2005,2009,2011 by Alois Schloegl -% Copyright (C) 2014-2017 Dynare Team -% This function is part of the NaN-toolbox -% http://pub.ist.ac.at/~schloegl/matlab/NaN/ - - -global FLAG_NANS_OCCURED; - -if nargin<2 - DIM = []; -end -if nargin<3 - W = []; -end - -% an efficient implementation in C of the following lines -% could significantly increase performance -% only one loop and only one check for isnan is needed -% An MEX-Implementation is available in sumskipnan.cpp -% -% Outline of the algorithm: -% for { k=1,o=0,count=0; k++; k1,1); - if isempty(DIM), DIM = 1; end -end -if (DIM<1), DIM = 1; end %% Hack, because min([])=0 for FreeMat v3.5 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% non-float data -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -if (isempty(W) && (~(isa(x,'float') || isa(x,'double')))) || ~flag_implicit_skip_nan() %%% skip always NaN's - if ~isempty(W) - error('SUMSKIPNAN: weighted sum of integers not supported, yet'); - end - x = double(x); - o = sum(x,DIM); - if nargout>1 - sz = size(x); - N = sz(DIM); - sz(DIM) = 1; - count = repmat(N,sz); - if nargout>2 - x = x.*x; - SSQ = sum(x,DIM); - end - end - return -end - -if (length(size(x))=3) - [o,count,SSQ] = sumskipnan_mex(real(x),DIM,FLAG_NANS_OCCURED,W); - if (~isreal(x)) - [io,icount,iSSQ] = sumskipnan_mex(imag(x),DIM,FLAG_NANS_OCCURED,W); - if any(count(:)-icount(:)) - error('Number of NaNs differ for REAL and IMAG part'); - else - o = o+i*io; - SSQ = SSQ+iSSQ; - end - end - return - end -end - -if ~isempty(W) - error('weighted sumskipnan requires sumskipnan_mex'); -end - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% count non-NaN's -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -if nargout>1 - count = sum(x==x,DIM); - FLAG_NANS_OCCURED = any(count(:)2 - x = real(x).^2 + imag(x).^2; - SSQ = sum(x,DIM); -end - -%!assert(sumskipnan([1,2],1),[1,2]) -%!assert(sumskipnan([1,NaN],2),1) -%!assert(sumskipnan([1,NaN],2),1) -%!assert(sumskipnan([nan,1,4,5]),10) -%!assert(sumskipnan([nan,1,4,5]',1,[3;2;1;0]),6) diff --git a/matlab/missing/corrcoef/tcdf.m b/matlab/missing/corrcoef/tcdf.m deleted file mode 100644 index 8d76f7657..000000000 --- a/matlab/missing/corrcoef/tcdf.m +++ /dev/null @@ -1,64 +0,0 @@ -function p = tcdf(x,n) -% TCDF returns student cumulative distribtion function -% -% cdf = tcdf(x,DF); -% -% Computes the CDF of the students distribution -% with DF degrees of freedom -% x,DF must be matrices of same size, or any one can be a scalar. -% -% see also: NORMCDF, TPDF, TINV - -% Reference(s): - -% $Id: tcdf.m 9033 2011-11-08 20:58:07Z schloegl $ - -% Copyright (C) 2000-2003,2009 by Alois Schloegl -% Copyright (C) 2014-2017 Dynare Team -% -% This is part of the NaN-toolbox. For more details see -% http://pub.ist.ac.at/~schloegl/matlab/NaN/ - -% This program 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. -% -% This program 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 this program; If not, see . - - -% check size of arguments -if all(size(x)==1) - x = repmat(x,size(n)); -elseif all(size(n)==1) - n = repmat(n,size(x)); -elseif all(size(x)==size(n)) - % OK, do nothing -else - error('size of input arguments must be equal or scalar') -end - -% allocate memory -p = zeros(size(x)); -p((x==Inf) & (n>0)) = 1; - -% workaround for invalid arguments in BETAINC -ix = isnan(x) | ~(n>0); -p(ix)= NaN; - -ix = (x > -Inf) & (x < Inf) & (n > 0); -p(ix) = betainc (n(ix) ./ (n(ix) + x(ix).^2), n(ix)/2, 1/2) / 2; - -ix = find(x>0); -p(ix) = 1 - p(ix); - -% shape output -p = reshape(p,size(x)); - -%!assert(tcdf(NaN,4),NaN) diff --git a/matlab/missing/intersect_stable/intersect_stable.m b/matlab/missing/intersect_stable/intersect_stable.m index be897b6fb..9b6eb5433 100644 --- a/matlab/missing/intersect_stable/intersect_stable.m +++ b/matlab/missing/intersect_stable/intersect_stable.m @@ -19,45 +19,45 @@ function [c, ia, ib] = intersect_stable(a, b) - if nargin ~= 2 - error('intersect_stable: needs exactly 2 input arguments'); - end +if nargin ~= 2 + error('intersect_stable: needs exactly 2 input arguments'); +end - if isnumeric (a) && isnumeric (b) - c = []; - elseif iscell (b) - c = {}; - else - c = ''; - end - ia = []; - ib = []; +if isnumeric (a) && isnumeric (b) + c = []; +elseif iscell (b) + c = {}; +else + c = ''; +end +ia = []; +ib = []; - if isempty (a) || isempty (b) - return - else - isrowvec = isrow (a) && isrow (b); +if isempty (a) || isempty (b) + return +else + isrowvec = isrow (a) && isrow (b); - for i = 1:numel(a) - if iscellstr(c) - idx = strcmp(a(i), b); - else - idx = a(i) == b; - end - if any(idx) && ~ismember(a(i), c) - c = [c(:); a(i)]; - if nargout > 1 - ia = [ia, i]; - ib = [ib, find(idx)]; - end + for i = 1:numel(a) + if iscellstr(c) + idx = strcmp(a(i), b); + else + idx = a(i) == b; + end + if any(idx) && ~ismember(a(i), c) + c = [c(:); a(i)]; + if nargout > 1 + ia = [ia, i]; + ib = [ib, find(idx)]; end end - - %% Adjust output orientation for MATLAB compatibility - if isrowvec - c = c.'; - end end + + %% Adjust output orientation for MATLAB compatibility + if isrowvec + c = c.'; + end +end end %!test diff --git a/matlab/missing/isfile/isfile.m b/matlab/missing/isfile/isfile.m index 85347fa8e..e733f08dd 100644 --- a/matlab/missing/isfile/isfile.m +++ b/matlab/missing/isfile/isfile.m @@ -70,7 +70,7 @@ for i=1:n d = b(i); elseif cellofstringflag d = b{i}; - elseif ischar(b) && size(b, 1)==1 + elseif ischar(b) && size(b, 1)==1 d = b; else error('Wrong input argument type!') diff --git a/matlab/missing/mex/gensylv/gensylv.m b/matlab/missing/mex/gensylv/gensylv.m index 2920aca4d..462e7b1ea 100644 --- a/matlab/missing/mex/gensylv/gensylv.m +++ b/matlab/missing/mex/gensylv/gensylv.m @@ -1,5 +1,5 @@ -function [err, E] = gensylv(kron_prod,A,B,C0,D) -%function [err, E] = gensylv(fake,A,B,C,D) +function E = gensylv(kron_prod,A,B,C0,D) +%function E = gensylv(fake,A,B,C,D) % Solves a Sylvester equation. % % INPUTS @@ -19,7 +19,7 @@ function [err, E] = gensylv(kron_prod,A,B,C0,D) % SPECIAL REQUIREMENTS % none. -% Copyright (C) 1996-2017 Dynare Team +% Copyright (C) 1996-2020 Dynare Team % % This file is part of Dynare. % @@ -42,4 +42,3 @@ end x0 = sylvester3(A,B,C,D); E = sylvester3a(x0,A,B,C,D); -err = 0; \ No newline at end of file diff --git a/matlab/missing/mex/kronecker/A_times_B_kronecker_C.m b/matlab/missing/mex/kronecker/A_times_B_kronecker_C.m index 7a8d09498..db615145a 100644 --- a/matlab/missing/mex/kronecker/A_times_B_kronecker_C.m +++ b/matlab/missing/mex/kronecker/A_times_B_kronecker_C.m @@ -1,4 +1,4 @@ -function [D, err] = A_times_B_kronecker_C(A,B,C) +function D = A_times_B_kronecker_C(A,B,C) %@info: %! @deftypefn {Function File} {[@var{D}, @var{err}] =} A_times_B_kronecker_C (@var{A},@var{B},@var{C}) @@ -41,7 +41,7 @@ function [D, err] = A_times_B_kronecker_C(A,B,C) %! @end deftypefn %@eod: -% Copyright (C) 1996-2012 Dynare Team +% Copyright (C) 1996-2020 Dynare Team % % This file is part of Dynare. % @@ -109,4 +109,4 @@ else D = A * kron(B,B); end end -err = 0; + diff --git a/matlab/missing/mex/kronecker/sparse_hessian_times_B_kronecker_C.m b/matlab/missing/mex/kronecker/sparse_hessian_times_B_kronecker_C.m index fd6059f84..7857e2571 100644 --- a/matlab/missing/mex/kronecker/sparse_hessian_times_B_kronecker_C.m +++ b/matlab/missing/mex/kronecker/sparse_hessian_times_B_kronecker_C.m @@ -1,7 +1,7 @@ -function [D, err] = sparse_hessian_times_B_kronecker_C(varargin) +function D = sparse_hessian_times_B_kronecker_C(varargin) %@info: -%! @deftypefn {Function File} {[@var{D}, @var{err}] =} sparse_hessian_times_B_kronecker_C (@var{A},@var{B},@var{C},@var{fake}) +%! @deftypefn {Function File} {@var{D} =} sparse_hessian_times_B_kronecker_C (@var{A},@var{B},@var{C},@var{fake}) %! @anchor{kronecker/sparse_hessian_times_B_kronecker_C} %! @sp 1 %! Computes A*kron(B,C) where A is hessian matrix in sparse format. @@ -24,8 +24,6 @@ function [D, err] = sparse_hessian_times_B_kronecker_C(varargin) %! @table @ @var %! @item D %! mA*(nC*nB) or mA*(nB*nB) matrix of doubles. -%! @item err -%! Integer scalar equal to zero (if all goes well). %! @end table %! @sp 2 %! @strong{Remarks} @@ -45,7 +43,7 @@ function [D, err] = sparse_hessian_times_B_kronecker_C(varargin) %! @end deftypefn %@eod: -% Copyright (C) 1996-2012 Dynare Team +% Copyright (C) 1996-2020 Dynare Team % % This file is part of Dynare. % @@ -71,10 +69,9 @@ fake = varargin{nargin}; switch nargin case 4 - [D, fake] = A_times_B_kronecker_C(A,B,C,fake); + D = A_times_B_kronecker_C(A,B,C,fake); case 3 - [D, fake] = A_times_B_kronecker_C(A,B,C); + D = A_times_B_kronecker_C(A,B,C); otherwise error('Two or Three input arguments required!') end -err = 0; \ No newline at end of file diff --git a/matlab/missing/mex/mjdgges/mjdgges.m b/matlab/missing/mex/mjdgges/mjdgges.m index 6bd345a57..11d51d62f 100644 --- a/matlab/missing/mex/mjdgges/mjdgges.m +++ b/matlab/missing/mex/mjdgges/mjdgges.m @@ -1,4 +1,4 @@ -function [err, ss, tt, zz, sdim, eigval, info] = mjdgges(e, d, qz_criterium, zhreshold) +function [ss, tt, zz, sdim, eigval, info] = mjdgges(e, d, qz_criterium, zhreshold) % % INPUTS % e [double] real square (n*n) matrix. @@ -8,7 +8,6 @@ function [err, ss, tt, zz, sdim, eigval, info] = mjdgges(e, d, qz_criterium, zhr % detecting eigenvalues too close to 0/0) % % OUTPUTS -% err [integer] scalar: 1 indicates failure, 0 indicates success % ss [double] (n*n) quasi-triangular matrix. % tt [double] (n*n) quasi-triangular matrix. % zz [double] (n*n) orthogonal matrix. @@ -19,7 +18,7 @@ function [err, ss, tt, zz, sdim, eigval, info] = mjdgges(e, d, qz_criterium, zhr % SPECIAL REQUIREMENTS % none. -% Copyright (C) 1996-2018 Dynare Team +% Copyright (C) 1996-2020 Dynare Team % % This file is part of Dynare. % @@ -66,5 +65,3 @@ try catch info = 1; % Not as precise as lapack's info! end - -err = 0; diff --git a/matlab/missing/splitlines/splitlines.m b/matlab/missing/splitlines/splitlines.m index e08cd5515..bc6d23989 100644 --- a/matlab/missing/splitlines/splitlines.m +++ b/matlab/missing/splitlines/splitlines.m @@ -1,7 +1,7 @@ function s = splitlines(string) % SPLITLINES splits strings at newline characters into a string array. -% +% % INPUT % - string [string] String to be splitted with newline characters. % diff --git a/matlab/missing/stats/+gamrnd/best_1978.m b/matlab/missing/stats/+gamrnd/best_1978.m index e2820a4d9..1934c71cb 100644 --- a/matlab/missing/stats/+gamrnd/best_1978.m +++ b/matlab/missing/stats/+gamrnd/best_1978.m @@ -9,7 +9,7 @@ function g = best_1978(a ,b) % OUTPUTS % - g [double] n*1 vector, gamma variates. -% Copyright (C) 2006-2018 Dynare Team +% Copyright (C) 2006-2020 Dynare Team % % This file is part of Dynare. % @@ -44,7 +44,12 @@ while mm X(index) = bb(index)+Y(index); % x id1 = index(X(index)<0); % Reject. id2 = setdiff(index, id1); - Z(id2) = 64.0*(W(id2).^3).*(rand(length(id2),1).^2); % d + if numel(id2) ~= 0 || isoctave || ~matlab_ver_less_than('9.1') + % If id2=[], LHS of the .* has size [0,0], while RHS is [0,1]. + % Since there is no automatic broadcast in MATLAB < R2016b, skip the + % statement in that case. + Z(id2) = 64.0*(W(id2).^3).*(rand(length(id2),1).^2); % d + end id3 = id2(Z(id2)>1.0-2.0*Y(id2).*Y(id2)./X(id2)); % Reject. id4 = id3(log(Z(id3))>2.0*(bb(id3).*log(X(id3)./bb(id3))-Y(id3))); % Reject. index = [id1, id4]; diff --git a/matlab/missing/stats/+gamrnd/knuth.m b/matlab/missing/stats/+gamrnd/knuth.m index 02a3e2559..ed4ca4b51 100644 --- a/matlab/missing/stats/+gamrnd/knuth.m +++ b/matlab/missing/stats/+gamrnd/knuth.m @@ -9,7 +9,7 @@ function g = knuth(a, b) % OUTPUTS % - g [double] n*1 vector, gamma variates. -% Copyright (C) 2006-2018 Dynare Team +% Copyright (C) 2006-2020 Dynare Team % % This file is part of Dynare. % @@ -38,9 +38,17 @@ while mm X(index) = Y(index).*bb(index) + a(index) - 1; id1 = index(X(index)<=0); % Rejected draws. id2 = setdiff(index, id1); - id3 = id2(rand(length(id2), 1)>(1+Y(id2).*Y(id2)).*exp((a(id2)-1).*(log(X(id2))-log(a(id2)-1))-bb(id2).*Y(id2))); % Rejected draws. + if numel(id2) == 0 && ~isoctave && matlab_ver_less_than('9.1') + % The LHS of the > comparison in the "else" branch has size = [0, 1] + % while the RHS has size = [0, 0]. + % Automatic broadcasting was only introduced in MATLAB R2016b, so we + % must handle this case separately to avoid an error. + id3 = []; + else + id3 = id2(rand(length(id2), 1)>(1+Y(id2).*Y(id2)).*exp((a(id2)-1).*(log(X(id2))-log(a(id2)-1))-bb(id2).*Y(id2))); % Rejected draws. + end index = [id1, id3]; mm = length(index); end -g = X.*b; \ No newline at end of file +g = X.*b; diff --git a/matlab/missing/strjoin/strjoin.m b/matlab/missing/strjoin/strjoin.m index 666c5f83a..47f21287f 100644 --- a/matlab/missing/strjoin/strjoin.m +++ b/matlab/missing/strjoin/strjoin.m @@ -39,8 +39,8 @@ if numel(cstr) == 1 end if ischar(delimiter) - % There is no equivalent to do_string_escapes in MATLAB - %delimiter = do_string_escapes(delimiter); + % There is no equivalent to do_string_escapes in MATLAB + %delimiter = do_string_escapes(delimiter); delimiter = {delimiter}; end @@ -60,4 +60,3 @@ else tmp = [cstr(:).'; delimiter(:).']; rval = [tmp{:}]; end - diff --git a/matlab/mode_check.m b/matlab/mode_check.m index e061af3a2..5a9970981 100644 --- a/matlab/mode_check.m +++ b/matlab/mode_check.m @@ -130,7 +130,7 @@ for plt = 1:nbplt end l1 = max(lower_bound,-BayesInfo.p2(kk)); m1 = 0; %lower bound l2 = min(upper_bound,BayesInfo.p2(kk)); %upper bound - end + end binding_lower_bound=0; binding_upper_bound=0; if isequal(x(kk),BoundsInfo.lb(kk)) diff --git a/matlab/model_diagnostics.m b/matlab/model_diagnostics.m index 5696f7726..636713047 100644 --- a/matlab/model_diagnostics.m +++ b/matlab/model_diagnostics.m @@ -16,7 +16,7 @@ function model_diagnostics(M,options,oo) % none. % -% Copyright (C) 1996-2018 Dynare Team +% Copyright (C) 1996-2020 Dynare Team % % This file is part of Dynare. % @@ -71,7 +71,7 @@ end % check if ys is steady state options.debug=1; %locally set debug option to 1 -[dr.ys,params,check1]=evaluate_steady_state(oo.steady_state,M,options,oo,1); +[dr.ys,M.params,check1]=evaluate_steady_state(oo.steady_state,M,options,oo,options.steadystate.nocheck); % testing for problem if check1(1) @@ -107,11 +107,11 @@ exo = [oo.exo_steady_state; oo.exo_det_steady_state]; for b=1:nb if options.bytecode if nb == 1 - [chk, res, jacob] = bytecode(dr.ys, exo, M.params, dr.ys, 1, exo, ... - 'evaluate', 'static'); + [res, jacob] = bytecode(dr.ys, exo, M.params, dr.ys, 1, exo, ... + 'evaluate', 'static'); else - [chk, res, jacob] = bytecode(dr.ys, exo, M.params, dr.ys, 1, exo, ... - 'evaluate', 'static',['block=' ... + [res, jacob] = bytecode(dr.ys, exo, M.params, dr.ys, 1, exo, ... + 'evaluate', 'static',['block=' ... int2str(b)]); end else @@ -204,8 +204,8 @@ z = repmat(dr.ys,1,klen); if ~options.block if options.order == 1 if (options.bytecode) - [chck, ~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... - M.params, dr.ys, 1); + [~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... + M.params, dr.ys, 1); jacobia_ = [loc_dr.g1 loc_dr.g1_x loc_dr.g1_xd]; else [~,jacobia_] = feval([M.fname '.dynamic'],z(iyr0),exo_simul, ... @@ -213,8 +213,8 @@ if ~options.block end elseif options.order >= 2 if (options.bytecode) - [chck, ~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... - M.params, dr.ys, 1); + [~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... + M.params, dr.ys, 1); jacobia_ = [loc_dr.g1 loc_dr.g1_x]; else [~,jacobia_,hessian1] = feval([M.fname '.dynamic'],z(iyr0),... diff --git a/matlab/model_inversion.m b/matlab/model_inversion.m index f67288cc1..dbae93376 100644 --- a/matlab/model_inversion.m +++ b/matlab/model_inversion.m @@ -87,8 +87,8 @@ if ~DynareModel.maximum_lead else [endogenousvariables, exogenousvariables] = ... static_model_inversion(constraints, exogenousvariables, ... - endo_names, exo_names, freeinnovations, ... - DynareModel, DynareOptions, DynareOutput); + endo_names, exo_names, freeinnovations, ... + DynareModel, DynareOptions, DynareOutput); end return end diff --git a/matlab/ms-sbvar/ms_compute_mdd.m b/matlab/ms-sbvar/ms_compute_mdd.m index 499baf6a5..43372a6e0 100644 --- a/matlab/ms-sbvar/ms_compute_mdd.m +++ b/matlab/ms-sbvar/ms_compute_mdd.m @@ -14,7 +14,7 @@ function [options_, oo_]=ms_compute_mdd(M_, options_, oo_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2011-2013 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -51,8 +51,7 @@ if options_.ms.use_mean_center end % compute mdd -[err] = ms_sbvar_command_line(opt); -mexErrCheck('ms_compute_mdd',err); +ms_sbvar_command_line(opt); % grab the muller/bridge log mdd from the output file mull_exp = 'Muller \w+\(\w+\) \= (\d+.\d+e\+\d+)'; diff --git a/matlab/ms-sbvar/ms_compute_probabilities.m b/matlab/ms-sbvar/ms_compute_probabilities.m index 07b951f65..9a5b91de8 100644 --- a/matlab/ms-sbvar/ms_compute_probabilities.m +++ b/matlab/ms-sbvar/ms_compute_probabilities.m @@ -14,7 +14,7 @@ function [options_, oo_]=ms_compute_probabilities(M_, options_, oo_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2011 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -53,8 +53,7 @@ else end % compute probabilities -[err] = ms_sbvar_command_line(opt); -mexErrCheck('ms_compute_probabilities',err); +ms_sbvar_command_line(opt); % now we want to plot the probabilities for each chain if ischar(prob_out_file) diff --git a/matlab/ms-sbvar/ms_estimation.m b/matlab/ms-sbvar/ms_estimation.m index 495a483ee..2a8510a2a 100644 --- a/matlab/ms-sbvar/ms_estimation.m +++ b/matlab/ms-sbvar/ms_estimation.m @@ -14,7 +14,7 @@ function [options_, oo_]=ms_estimation(M_, options_, oo_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2011-2017 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -73,8 +73,7 @@ opt = [opt ' -random_tol_obj ' num2str(options_.ms.random_function_convergence_c opt = [opt ' -random_tol_parms ' num2str(options_.ms.random_parameter_convergence_criterion)]; % estimation -[err] = ms_sbvar_command_line(opt); -mexErrCheck('ms_estimation', err); +ms_sbvar_command_line(opt); [options_, oo_] = set_ms_estimation_file(options_.ms.output_file_tag, options_, oo_); end diff --git a/matlab/ms-sbvar/ms_forecast.m b/matlab/ms-sbvar/ms_forecast.m index e8949c9ae..b6e25aa84 100644 --- a/matlab/ms-sbvar/ms_forecast.m +++ b/matlab/ms-sbvar/ms_forecast.m @@ -14,7 +14,7 @@ function [options_, oo_]=ms_forecast(M_, options_, oo_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2011-2017 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -75,8 +75,7 @@ else end % forecast -[err] = ms_sbvar_command_line(opt); -mexErrCheck('ms_forecast',err); +ms_sbvar_command_line(opt); % Plot Forecasts if options_.ms.regimes diff --git a/matlab/ms-sbvar/ms_irf.m b/matlab/ms-sbvar/ms_irf.m index 47d1a8490..d06a1149c 100644 --- a/matlab/ms-sbvar/ms_irf.m +++ b/matlab/ms-sbvar/ms_irf.m @@ -15,7 +15,7 @@ function [options_, oo_]=ms_irf(varlist, M_, options_, oo_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2011-2017 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -77,8 +77,7 @@ else end % irf -[err] = ms_sbvar_command_line(opt); -mexErrCheck('ms_irf',err); +ms_sbvar_command_line(opt); % Plot IRFs if options_.ms.regimes diff --git a/matlab/ms-sbvar/ms_sbvar_setup.m b/matlab/ms-sbvar/ms_sbvar_setup.m index a195cc491..062eaca72 100644 --- a/matlab/ms-sbvar/ms_sbvar_setup.m +++ b/matlab/ms-sbvar/ms_sbvar_setup.m @@ -11,7 +11,7 @@ function ms_sbvar_setup(options_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2003-2017 Dynare Team +% Copyright (C) 2003-2020 Dynare Team % % This file is part of Dynare. % @@ -428,6 +428,5 @@ fclose(fidForC); %====================================================================== ms_write_markov_file(markov_file,options_) create_init_file = [matlab_filename,' ',markov_file,' ',options_.ms.file_tag]; -[err] = ms_sbvar_create_init_file(create_init_file); -mexErrCheck('ms_sbvar_create_init_file',err); +ms_sbvar_create_init_file(create_init_file); end diff --git a/matlab/ms-sbvar/ms_simulation.m b/matlab/ms-sbvar/ms_simulation.m index f7832e035..d311733b8 100644 --- a/matlab/ms-sbvar/ms_simulation.m +++ b/matlab/ms-sbvar/ms_simulation.m @@ -14,7 +14,7 @@ function [options_, oo_]=ms_simulation(M_, options_, oo_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2011-2013 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -50,6 +50,5 @@ if options_.ms.save_draws end % simulation -[err] = ms_sbvar_command_line(opt); -mexErrCheck('ms_simulation',err); +ms_sbvar_command_line(opt); end diff --git a/matlab/ms-sbvar/ms_variance_decomposition.m b/matlab/ms-sbvar/ms_variance_decomposition.m index 1fe73ddbc..746facf2c 100644 --- a/matlab/ms-sbvar/ms_variance_decomposition.m +++ b/matlab/ms-sbvar/ms_variance_decomposition.m @@ -14,7 +14,7 @@ function [options_, oo_]=ms_variance_decomposition(M_, options_, oo_) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2011-2017 Dynare Team +% Copyright (C) 2011-2020 Dynare Team % % This file is part of Dynare. % @@ -78,8 +78,7 @@ if options_.ms.error_bands end % variance_decomposition -[err] = ms_sbvar_command_line(opt); -mexErrCheck('ms_variance_decomposition',err); +ms_sbvar_command_line(opt); if options_.ms.regime || options_.ms.regimes outfile = [outfile 'regime_']; diff --git a/matlab/non_linear_dsge_likelihood.m b/matlab/non_linear_dsge_likelihood.m index 9f52b69f0..42d563a9b 100644 --- a/matlab/non_linear_dsge_likelihood.m +++ b/matlab/non_linear_dsge_likelihood.m @@ -1,113 +1,32 @@ function [fval,info,exit_flag,DLIK,Hess,ys,trend_coeff,Model,DynareOptions,BayesInfo,DynareResults] = non_linear_dsge_likelihood(xparam1,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults) + % Evaluates the posterior kernel of a dsge model using a non linear filter. +% +% INPUTS +% - xparam1 [double] n×1 vector, estimated parameters. +% - DynareDataset [struct] Matlab's structure containing the dataset (initialized by dynare, aka dataset_). +% - DatasetInfo [struct] Matlab's structure describing the dataset (initialized by dynare, aka dataset_info). +% - DynareOptions [struct] Matlab's structure describing the options (initialized by dynare, aka options_). +% - Model [struct] Matlab's structure describing the Model (initialized by dynare, aka M_). +% - EstimatedParameters [struct] Matlab's structure describing the estimated_parameters (initialized by dynare, aka estim_params_). +% - BayesInfo [struct] Matlab's structure describing the priors (initialized by dynare,aka bayesopt_). +% - BoundsInfo [struct] Matlab's structure specifying the bounds on the paramater values (initialized by dynare,aka bayesopt_). +% - DynareResults [struct] Matlab's structure gathering the results (initialized by dynare,aka oo_). +% +% OUTPUTS +% - fval [double] scalar, value of the likelihood or posterior kernel. +% - info [integer] 4×1 vector, informations resolution of the model and evaluation of the likelihood. +% - exit_flag [integer] scalar, equal to 1 (no issues when evaluating the likelihood) or 0 (not able to evaluate the likelihood). +% - DLIK [double] Empty array. +% - Hess [double] Empty array. +% - ys [double] Empty array. +% - trend_coeff [double] Empty array. +% - Model [struct] Updated Model structure described in INPUTS section. +% - DynareOptions [struct] Updated DynareOptions structure described in INPUTS section. +% - BayesInfo [struct] See INPUTS section. +% - DynareResults [struct] Updated DynareResults structure described in INPUTS section. -%@info: -%! @deftypefn {Function File} {[@var{fval},@var{exit_flag},@var{ys},@var{trend_coeff},@var{info},@var{Model},@var{DynareOptions},@var{BayesInfo},@var{DynareResults}] =} non_linear_dsge_likelihood (@var{xparam1},@var{DynareDataset},@var{DynareOptions},@var{Model},@var{EstimatedParameters},@var{BayesInfo},@var{DynareResults}) -%! @anchor{dsge_likelihood} -%! @sp 1 -%! Evaluates the posterior kernel of a dsge model using a non linear filter. -%! @sp 2 -%! @strong{Inputs} -%! @sp 1 -%! @table @ @var -%! @item xparam1 -%! Vector of doubles, current values for the estimated parameters. -%! @item DynareDataset -%! Matlab's structure describing the dataset (initialized by dynare, see @ref{dataset_}). -%! @item DynareOptions -%! Matlab's structure describing the options (initialized by dynare, see @ref{options_}). -%! @item Model -%! Matlab's structure describing the Model (initialized by dynare, see @ref{M_}). -%! @item EstimatedParamemeters -%! Matlab's structure describing the estimated_parameters (initialized by dynare, see @ref{estim_params_}). -%! @item BayesInfo -%! Matlab's structure describing the priors (initialized by dynare, see @ref{bayesopt_}). -%! @item DynareResults -%! Matlab's structure gathering the results (initialized by dynare, see @ref{oo_}). -%! @end table -%! @sp 2 -%! @strong{Outputs} -%! @sp 1 -%! @table @ @var -%! @item fval -%! Double scalar, value of (minus) the likelihood. -%! @item info -%! Double vector, fourth entry stores penalty, first entry the error code. -%! @table @ @code -%! @item info==0 -%! No error. -%! @item info==1 -%! The model doesn't determine the current variables uniquely. -%! @item info==2 -%! MJDGGES returned an error code. -%! @item info==3 -%! Blanchard & Kahn conditions are not satisfied: no stable equilibrium. -%! @item info==4 -%! Blanchard & Kahn conditions are not satisfied: indeterminacy. -%! @item info==5 -%! Blanchard & Kahn conditions are not satisfied: indeterminacy due to rank failure. -%! @item info==6 -%! The jacobian evaluated at the deterministic steady state is complex. -%! @item info==19 -%! The steadystate routine has thrown an exception (inconsistent deep parameters). -%! @item info==20 -%! Cannot find the steady state, info(2) contains the sum of square residuals (of the static equations). -%! @item info==21 -%! The steady state is complex, info(2) contains the sum of square of imaginary parts of the steady state. -%! @item info==22 -%! The steady has NaNs. -%! @item info==23 -%! M_.params has been updated in the steadystate routine and has complex valued scalars. -%! @item info==24 -%! M_.params has been updated in the steadystate routine and has some NaNs. -%! @item info==30 -%! Ergodic variance can't be computed. -%! @item info==41 -%! At least one parameter is violating a lower bound condition. -%! @item info==42 -%! At least one parameter is violating an upper bound condition. -%! @item info==43 -%! The covariance matrix of the structural innovations is not positive definite. -%! @item info==44 -%! The covariance matrix of the measurement errors is not positive definite. -%! @item info==45 -%! Likelihood is not a number (NaN). -%! @item info==45 -%! Likelihood is a complex valued number. -%! @end table -%! @item exit_flag -%! Integer scalar, equal to zero if the routine return with a penalty (one otherwise). -%! @item DLIK -%! Vector of doubles, placeholder for score of the likelihood, currently -%! not supported by non_linear_dsge_likelihood -%! @item AHess -%! Matrix of doubles, placeholder for asymptotic hessian matrix, currently -%! not supported by non_linear_dsge_likelihood -%! @item ys -%! Vector of doubles, steady state level for the endogenous variables. -%! @item trend_coeffs -%! Matrix of doubles, coefficients of the deterministic trend in the measurement equation. -%! @item Model -%! Matlab's structure describing the model (initialized by dynare, see @ref{M_}). -%! @item DynareOptions -%! Matlab's structure describing the options (initialized by dynare, see @ref{options_}). -%! @item BayesInfo -%! Matlab's structure describing the priors (initialized by dynare, see @ref{bayesopt_}). -%! @item DynareResults -%! Matlab's structure gathering the results (initialized by dynare, see @ref{oo_}). -%! @end table -%! @sp 2 -%! @strong{This function is called by:} -%! @sp 1 -%! @ref{dynare_estimation_1}, @ref{mode_check} -%! @sp 2 -%! @strong{This function calls:} -%! @sp 1 -%! @ref{dynare_resolve}, @ref{lyapunov_symm}, @ref{priordens} -%! @end deftypefn -%@eod: - -% Copyright (C) 2010-2017 Dynare Team +% Copyright (C) 2010-2019 Dynare Team % % This file is part of Dynare. % @@ -124,11 +43,6 @@ function [fval,info,exit_flag,DLIK,Hess,ys,trend_coeff,Model,DynareOptions,Bayes % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% Declaration of the penalty as a persistent variable. -persistent init_flag -persistent restrict_variables_idx observed_variables_idx state_variables_idx mf0 mf1 -persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations - % Initialization of the returned arguments. fval = []; ys = []; @@ -225,7 +139,7 @@ end %------------------------------------------------------------------------------ % Linearize the model around the deterministic sdteadystate and extract the matrices of the state equation (T and R). -[T,R,SteadyState,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict'); +[dr, info, Model, DynareOptions, DynareResults] = resol(0, Model, DynareOptions, DynareResults); if info(1) if info(1) == 3 || info(1) == 4 || info(1) == 5 || info(1)==6 ||info(1) == 19 || ... @@ -247,53 +161,20 @@ end % Define a vector of indices for the observed variables. Is this really usefull?... BayesInfo.mf = BayesInfo.mf1; -% Define the deterministic linear trend of the measurement equation. -if DynareOptions.noconstant - constant = zeros(DynareDataset.vobs,1); -else - constant = SteadyState(BayesInfo.mfys); -end - -% Define the deterministic linear trend of the measurement equation. -if BayesInfo.with_trend - [trend_addition, trend_coeff]=compute_trend_coefficients(Model,DynareOptions,DynareDataset.vobs,DynareDataset.nobs); - trend = repmat(constant,1,DynareDataset.info.ntobs)+trend_addition; -else - trend = repmat(constant,1,DynareDataset.nobs); -end - % Get needed informations for kalman filter routines. start = DynareOptions.presample+1; -np = size(T,1); -mf = BayesInfo.mf; -Y = transpose(DynareDataset.data); +Y = transpose(DynareDataset.data); %------------------------------------------------------------------------------ % 3. Initial condition of the Kalman filter %------------------------------------------------------------------------------ -% Get decision rules and transition equations. -dr = DynareResults.dr; +mf0 = BayesInfo.mf0; +mf1 = BayesInfo.mf1; +restrict_variables_idx = dr.restrict_var_list; +state_variables_idx = restrict_variables_idx(mf0); +number_of_state_variables = length(mf0); -% Set persistent variables (first call). -if isempty(init_flag) - mf0 = BayesInfo.mf0; - mf1 = BayesInfo.mf1; - restrict_variables_idx = dr.restrict_var_list; - observed_variables_idx = restrict_variables_idx(mf1); - state_variables_idx = restrict_variables_idx(mf0); - sample_size = size(Y,2); - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(Q); - init_flag = 1; -end - -ReducedForm.ghx = dr.ghx(restrict_variables_idx,:); -ReducedForm.ghu = dr.ghu(restrict_variables_idx,:); -ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); -ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); -ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); ReducedForm.steadystate = dr.ys(dr.order_var(restrict_variables_idx)); ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); ReducedForm.state_variables_steady_state = dr.ys(dr.order_var(state_variables_idx)); @@ -302,11 +183,24 @@ ReducedForm.H = H; ReducedForm.mf0 = mf0; ReducedForm.mf1 = mf1; +if DynareOptions.k_order_solver + ReducedForm.use_k_order_solver = true; + ReducedForm.dr = dr; +else + ReducedForm.use_k_order_solver = false; + ReducedForm.ghx = dr.ghx(restrict_variables_idx,:); + ReducedForm.ghu = dr.ghu(restrict_variables_idx,:); + ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); + ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); + ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); +end + % Set initial condition. switch DynareOptions.particle.initialization case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. StateVectorMean = ReducedForm.constant(mf0); - StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',DynareOptions.lyapunov_fixed_point_tol,DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold,[],DynareOptions.debug); + StateVectorVariance = lyapunov_symm(dr.ghx(mf0,:), dr.ghu(mf0,:)*Q*dr.ghu(mf0,:)', DynareOptions.lyapunov_fixed_point_tol, ... + DynareOptions.qz_criterium, DynareOptions.lyapunov_complex_threshold, [], DynareOptions.debug); case 2% Initial state vector covariance is a monte-carlo based estimate of the ergodic variance (consistent with a k-order Taylor-approximation of the model). StateVectorMean = ReducedForm.constant(mf0); old_DynareOptionsperiods = DynareOptions.periods; @@ -331,7 +225,7 @@ ReducedForm.StateVectorVariance = StateVectorVariance; %------------------------------------------------------------------------------ DynareOptions.warning_for_steadystate = 0; [s1,s2] = get_dynare_random_generator_state(); -LIK = feval(DynareOptions.particle.algorithm,ReducedForm,Y,start,DynareOptions.particle,DynareOptions.threads); +LIK = feval(DynareOptions.particle.algorithm, ReducedForm, Y, start, DynareOptions.particle, DynareOptions.threads, DynareOptions, Model); set_dynare_random_generator_state(s1,s2); if imag(LIK) likelihood = Inf; @@ -351,7 +245,7 @@ DynareOptions.warning_for_steadystate = 1; % Adds prior if necessary % ------------------------------------------------------------------------------ lnprior = priordens(xparam1(:),BayesInfo.pshape,BayesInfo.p6,BayesInfo.p7,BayesInfo.p3,BayesInfo.p4); -fval = (likelihood-lnprior); +fval = (likelihood-lnprior); if isnan(fval) fval = Inf; @@ -361,7 +255,7 @@ if isnan(fval) return end -if imag(fval)~=0 +if ~isreal(fval) fval = Inf; info(1) = 48; info(4) = 0.1; @@ -369,7 +263,7 @@ if imag(fval)~=0 return end -if isinf(LIK)~=0 +if isinf(LIK) fval = Inf; info(1) = 50; info(4) = 0.1; diff --git a/matlab/occbin/call_solve_one_constraint.m b/matlab/occbin/call_solve_one_constraint.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/call_solve_two_constraints.m b/matlab/occbin/call_solve_two_constraints.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/evaluate_model.m b/matlab/occbin/evaluate_model.m index 59172cf09..d5c6685f5 100644 --- a/matlab/occbin/evaluate_model.m +++ b/matlab/occbin/evaluate_model.m @@ -9,10 +9,10 @@ switch nargout M.params, ss, 1); case 2 [r,g1] = feval([M.fname '.dynamic'],y,x, ... - M.params, ss, 1); + M.params, ss, 1); case 3 [r,g1,g2] = feval([M.fname '.dynamic'],y,x, ... - M.params, ss, 1); + M.params, ss, 1); case 4 [r,g1,g2,g3] = feval([M.fname '.dynamic'],y,x, ... M.params, ss, 1); diff --git a/matlab/occbin/get_coef.m b/matlab/occbin/get_coef.m index 924be1b1c..138198259 100644 --- a/matlab/occbin/get_coef.m +++ b/matlab/occbin/get_coef.m @@ -11,15 +11,15 @@ if M.maximum_lag > 0 [~,c1,c2] = find(ll(2,:)); coef_y(:,c1+endo_nbr) = jacobian(:,c2); if M.maximum_lead > 0 - [~,c1,c2] = find(ll(3,:)); - coef_y(:,c1+2*endo_nbr) = jacobian(:,c2); + [~,c1,c2] = find(ll(3,:)); + coef_y(:,c1+2*endo_nbr) = jacobian(:,c2); end else [~,c1,c2] = find(ll(1,:)); coef_y(:,c1+endo_nbr) = jacobian(:,c2); if M.maximum_lead > 0 - [~,c1,c2] = find(ll(2,:)); - coef_y(:,c1+2*endo_nbr) = jacobian(:,c2); + [~,c1,c2] = find(ll(2,:)); + coef_y(:,c1+2*endo_nbr) = jacobian(:,c2); end end diff --git a/matlab/occbin/get_complementarity_conditions.m b/matlab/occbin/get_complementarity_conditions.m index 5f5564802..f49ae2497 100644 --- a/matlab/occbin/get_complementarity_conditions.m +++ b/matlab/occbin/get_complementarity_conditions.m @@ -43,14 +43,14 @@ for i=1:size(etags,1) str = etags{i,3}; kop = strfind(etags{i,3},'<'); if ~isempty(kop) - k = find(strcmp(strtrim(str(1:kop-1)), M.endo_names)); - if isempty(k) - error(sprintf(['Complementarity condition %s: variable %s is ' ... - 'not recognized',etags{i,3},b{1}])) - end - ub(k) = str2num(str(kop+1:end)); - eq_index(etags{i,1}) = k; - eq_index(k) = etags{i,1}; + k = find(strcmp(strtrim(str(1:kop-1)), M.endo_names)); + if isempty(k) + error(sprintf(['Complementarity condition %s: variable %s is ' ... + 'not recognized',etags{i,3},b{1}])) + end + ub(k) = str2num(str(kop+1:end)); + eq_index(etags{i,1}) = k; + eq_index(k) = etags{i,1}; else kop = strfind(etags{i,3},'>'); if ~isempty(kop) @@ -69,4 +69,3 @@ for i=1:size(etags,1) end end end - diff --git a/matlab/occbin/get_deriv.m b/matlab/occbin/get_deriv.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/get_occbin_complementarity_conditions.m b/matlab/occbin/get_occbin_complementarity_conditions.m index 60aba2b26..eb1182288 100644 --- a/matlab/occbin/get_occbin_complementarity_conditions.m +++ b/matlab/occbin/get_occbin_complementarity_conditions.m @@ -45,14 +45,14 @@ for i=1:size(etags,1) str = etags{i,3}; kop = strfind(etags{i,3},'<'); if ~isempty(kop) - k = find(strcmp(strtrim(str(1:kop-1)), M.endo_names)); - if isempty(k) - error(sprintf(['Complementarity condition %s: variable %s is ' ... - 'not recognized',etags{i,3},b{1}])) - end - ivar(nrow) = k; - ieq(nrow) = etags{i,1}; - ub(nrow) = eval(str(kop+1:end)); + k = find(strcmp(strtrim(str(1:kop-1)), M.endo_names)); + if isempty(k) + error(sprintf(['Complementarity condition %s: variable %s is ' ... + 'not recognized',etags{i,3},b{1}])) + end + ivar(nrow) = k; + ieq(nrow) = etags{i,1}; + ub(nrow) = eval(str(kop+1:end)); else kop = strfind(etags{i,3},'>'); if ~isempty(kop) @@ -72,4 +72,3 @@ for i=1:size(etags,1) nrow = nrow + 1; end end - diff --git a/matlab/occbin/get_pq.m b/matlab/occbin/get_pq.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/makechart.m b/matlab/occbin/makechart.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/makechart9.m b/matlab/occbin/makechart9.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/map_regime.m b/matlab/occbin/map_regime.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/mkdata.m b/matlab/occbin/mkdata.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/mkdatap_anticipated.m b/matlab/occbin/mkdatap_anticipated.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/mkdatap_anticipated_2constraints.m b/matlab/occbin/mkdatap_anticipated_2constraints.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/occbin.m b/matlab/occbin/occbin.m index ea0780d21..2e467524f 100644 --- a/matlab/occbin/occbin.m +++ b/matlab/occbin/occbin.m @@ -8,10 +8,10 @@ constraint_nbr = sum(strcmp(upper(M.equations_tags(:,2)),'OCCBIN'))/2; switch(constraint_nbr) case 1 [zdatalinear_ zdatapiecewise_ zdatass_ oobase_ ] = ... - solve_one_constraint(M,oo,options); + solve_one_constraint(M,oo,options); case 2 [zdatalinear_ zdatapiecewise_ zdatass_ oobase_ ] = ... - solve_two_constraints(M,oo,options); + solve_two_constraints(M,oo,options); otherwise error('OCCBIN can only handle two constraints in a model') end diff --git a/matlab/occbin/pickaxes.m b/matlab/occbin/pickaxes.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/process_constraint.m b/matlab/occbin/process_constraint.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/setss.m b/matlab/occbin/setss.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/solve_no_constraint.m b/matlab/occbin/solve_no_constraint.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/solve_no_constraint_noclear.m b/matlab/occbin/solve_no_constraint_noclear.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/solve_one_constraint.1.m b/matlab/occbin/solve_one_constraint.1.m old mode 100755 new mode 100644 index 64a13c9ed..b197d4527 --- a/matlab/occbin/solve_one_constraint.1.m +++ b/matlab/occbin/solve_one_constraint.1.m @@ -26,8 +26,8 @@ function [zdatalinear_ zdatapiecewise_ zdatass_ oobase_ Mbase_ ] = ... solve_one_constraint.1(modnam_,modnamstar_,... - constraint_, constraint_relax_,... - shockssequence_,irfshock_,nperiods_,maxiter_,init_) + constraint_, constraint_relax_,... + shockssequence_,irfshock_,nperiods_,maxiter_,init_) global M_ oo_ diff --git a/matlab/occbin/solve_one_constraint.m b/matlab/occbin/solve_one_constraint.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/solve_two_constraints.m b/matlab/occbin/solve_two_constraints.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/strmerge.m b/matlab/occbin/strmerge.m old mode 100755 new mode 100644 diff --git a/matlab/occbin/tokenize.m b/matlab/occbin/tokenize.m old mode 100755 new mode 100644 diff --git a/matlab/one_sided_hp_filter.m b/matlab/one_sided_hp_filter.m index 5d2965b2c..6ffbdc54b 100644 --- a/matlab/one_sided_hp_filter.m +++ b/matlab/one_sided_hp_filter.m @@ -37,7 +37,7 @@ function [ytrend,ycycle]=one_sided_hp_filter(y,lambda,x_user,P_user,discard) % Time Series Analysis, with the exception of H, which is equivalent to his H'. -% Copyright (C) 200?-2015 Alexander Meyer-Gohde +% Copyright (C) 2010-2015 Alexander Meyer-Gohde % Copyright (C) 2015-2017 Dynare Team % % This file is part of Dynare. @@ -110,4 +110,4 @@ x=F*x+K*(obs -H*x); %State estimate Temp=F-K*H; P=Temp*P*Temp'; P=P+Q+K*R*K';%MSE estimate -end \ No newline at end of file +end diff --git a/matlab/optimization/cmaes.m b/matlab/optimization/cmaes.m index 2ead9b50e..dba7a368c 100644 --- a/matlab/optimization/cmaes.m +++ b/matlab/optimization/cmaes.m @@ -1033,724 +1033,724 @@ while irun <= myeval(opts.Restarts) % for-loop does not work with resume end % handle boundaries % ----- end handle boundaries ----- - % compute noise measurement and reduce fitness arrays to size lambda - if noiseHandling - [noiseS] = local_noisemeasurement(fitness.sel(1:lambda), ... - fitness.sel(lambda+(1:noiseReevals)), ... - noiseReevals, noiseTheta, noiseCutOff); - if countiter == 1 % TODO: improve this very rude way of initialization - noiseSS = 0; - noiseN = 0; % counter for mean - end - noiseSS = noiseSS + noisecum * (noiseS - noiseSS); - - % noise-handling could be done here, but the original sigma is still needed - % disp([noiseS noiseSS noisecum]) - - fitness.rawar12 = fitness.raw; % just documentary - fitness.selar12 = fitness.sel; % just documentary - % qqq refine fitness based on both values - if 11 < 3 % TODO: in case of outliers this mean is counterproductive - % median out of three would be ok - fitness.raw(1:noiseReevals) = ... % not so raw anymore - (fitness.raw(1:noiseReevals) + fitness.raw(lambda+(1:noiseReevals))) / 2; - fitness.sel(1:noiseReevals) = ... - (fitness.sel(1:noiseReevals) + fitness.sel(lambda+(1:noiseReevals))) / 2; - end - fitness.raw = fitness.raw(1:lambda); - fitness.sel = fitness.sel(1:lambda); + % compute noise measurement and reduce fitness arrays to size lambda + if noiseHandling + [noiseS] = local_noisemeasurement(fitness.sel(1:lambda), ... + fitness.sel(lambda+(1:noiseReevals)), ... + noiseReevals, noiseTheta, noiseCutOff); + if countiter == 1 % TODO: improve this very rude way of initialization + noiseSS = 0; + noiseN = 0; % counter for mean end + noiseSS = noiseSS + noisecum * (noiseS - noiseSS); - % Sort by fitness - [fitness.raw, fitness.idx] = sort(fitness.raw); - [fitness.sel, fitness.idxsel] = sort(fitness.sel); % minimization - fitness.hist(2:end) = fitness.hist(1:end-1); % record short history of - fitness.hist(1) = fitness.raw(1); % best fitness values - if length(fitness.histbest) < 120+ceil(30*N/lambda) || ... - (mod(countiter, 5) == 0 && length(fitness.histbest) < 2e4) % 20 percent of 1e5 gen. - fitness.histbest = [fitness.raw(1) fitness.histbest]; % best fitness values - fitness.histmedian = [median(fitness.raw) fitness.histmedian]; % median fitness values + % noise-handling could be done here, but the original sigma is still needed + % disp([noiseS noiseSS noisecum]) + + fitness.rawar12 = fitness.raw; % just documentary + fitness.selar12 = fitness.sel; % just documentary + % qqq refine fitness based on both values + if 11 < 3 % TODO: in case of outliers this mean is counterproductive + % median out of three would be ok + fitness.raw(1:noiseReevals) = ... % not so raw anymore + (fitness.raw(1:noiseReevals) + fitness.raw(lambda+(1:noiseReevals))) / 2; + fitness.sel(1:noiseReevals) = ... + (fitness.sel(1:noiseReevals) + fitness.sel(lambda+(1:noiseReevals))) / 2; + end + fitness.raw = fitness.raw(1:lambda); + fitness.sel = fitness.sel(1:lambda); + end + + % Sort by fitness + [fitness.raw, fitness.idx] = sort(fitness.raw); + [fitness.sel, fitness.idxsel] = sort(fitness.sel); % minimization + fitness.hist(2:end) = fitness.hist(1:end-1); % record short history of + fitness.hist(1) = fitness.raw(1); % best fitness values + if length(fitness.histbest) < 120+ceil(30*N/lambda) || ... + (mod(countiter, 5) == 0 && length(fitness.histbest) < 2e4) % 20 percent of 1e5 gen. + fitness.histbest = [fitness.raw(1) fitness.histbest]; % best fitness values + fitness.histmedian = [median(fitness.raw) fitness.histmedian]; % median fitness values + else + fitness.histbest(2:end) = fitness.histbest(1:end-1); + fitness.histmedian(2:end) = fitness.histmedian(1:end-1); + fitness.histbest(1) = fitness.raw(1); % best fitness values + fitness.histmedian(1) = median(fitness.raw); % median fitness values + end + fitness.histsel(2:end) = fitness.histsel(1:end-1); % record short history of + fitness.histsel(1) = fitness.sel(1); % best sel fitness values + + % Calculate new xmean, this is selection and recombination + xold = xmean; % for speed up of Eq. (2) and (3) + xmean = arx(:,fitness.idxsel(1:mu))*weights; + zmean = arz(:,fitness.idxsel(1:mu))*weights;%==D^-1*B'*(xmean-xold)/sigma + if mu == 1 + fmean = fitness.sel(1); + else + fmean = NaN; % [] does not work in the latter assignment + % fmean = feval(fitfun, xintobounds(xmean, lbounds, ubounds), varargin{:}); + % counteval = counteval + 1; + end + + % Cumulation: update evolution paths + ps = (1-cs)*ps + sqrt(cs*(2-cs)*mueff) * (B*zmean); % Eq. (4) + hsig = norm(ps)/sqrt(1-(1-cs)^(2*countiter))/chiN < 1.4 + 2/(N+1); + if flg_future_setting + hsig = sum(ps.^2) / (1-(1-cs)^(2*countiter)) / N < 2 + 4/(N+1); % just simplified + end + % hsig = norm(ps)/sqrt(1-(1-cs)^(2*countiter))/chiN < 1.4 + 2/(N+1); + % hsig = norm(ps)/sqrt(1-(1-cs)^(2*countiter))/chiN < 1.5 + 1/(N-0.5); + % hsig = norm(ps) < 1.5 * sqrt(N); + % hsig = 1; + + pc = (1-cc)*pc ... + + hsig*(sqrt(cc*(2-cc)*mueff)/sigma) * (xmean-xold); % Eq. (2) + if hsig == 0 + % disp([num2str(countiter) ' ' num2str(counteval) ' pc update stalled']); + end + + % Adapt covariance matrix + neg.ccov = 0; % TODO: move parameter setting upwards at some point + if ccov1 + ccovmu > 0 % Eq. (3) + if flgDiagonalOnly % internal linear(?) complexity + diagC = (1-ccov1_sep-ccovmu_sep+(1-hsig)*ccov1_sep*cc*(2-cc)) * diagC ... % regard old matrix + + ccov1_sep * pc.^2 ... % plus rank one update + + ccovmu_sep ... % plus rank mu update + * (diagC .* (arz(:,fitness.idxsel(1:mu)).^2 * weights)); + % * (repmat(diagC,1,mu) .* arz(:,fitness.idxsel(1:mu)).^2 * weights); + diagD = sqrt(diagC); % replaces eig(C) else - fitness.histbest(2:end) = fitness.histbest(1:end-1); - fitness.histmedian(2:end) = fitness.histmedian(1:end-1); - fitness.histbest(1) = fitness.raw(1); % best fitness values - fitness.histmedian(1) = median(fitness.raw); % median fitness values - end - fitness.histsel(2:end) = fitness.histsel(1:end-1); % record short history of - fitness.histsel(1) = fitness.sel(1); % best sel fitness values - - % Calculate new xmean, this is selection and recombination - xold = xmean; % for speed up of Eq. (2) and (3) - xmean = arx(:,fitness.idxsel(1:mu))*weights; - zmean = arz(:,fitness.idxsel(1:mu))*weights;%==D^-1*B'*(xmean-xold)/sigma - if mu == 1 - fmean = fitness.sel(1); - else - fmean = NaN; % [] does not work in the latter assignment - % fmean = feval(fitfun, xintobounds(xmean, lbounds, ubounds), varargin{:}); - % counteval = counteval + 1; - end - - % Cumulation: update evolution paths - ps = (1-cs)*ps + sqrt(cs*(2-cs)*mueff) * (B*zmean); % Eq. (4) - hsig = norm(ps)/sqrt(1-(1-cs)^(2*countiter))/chiN < 1.4 + 2/(N+1); - if flg_future_setting - hsig = sum(ps.^2) / (1-(1-cs)^(2*countiter)) / N < 2 + 4/(N+1); % just simplified - end - % hsig = norm(ps)/sqrt(1-(1-cs)^(2*countiter))/chiN < 1.4 + 2/(N+1); - % hsig = norm(ps)/sqrt(1-(1-cs)^(2*countiter))/chiN < 1.5 + 1/(N-0.5); - % hsig = norm(ps) < 1.5 * sqrt(N); - % hsig = 1; - - pc = (1-cc)*pc ... - + hsig*(sqrt(cc*(2-cc)*mueff)/sigma) * (xmean-xold); % Eq. (2) - if hsig == 0 - % disp([num2str(countiter) ' ' num2str(counteval) ' pc update stalled']); - end - - % Adapt covariance matrix - neg.ccov = 0; % TODO: move parameter setting upwards at some point - if ccov1 + ccovmu > 0 % Eq. (3) - if flgDiagonalOnly % internal linear(?) complexity - diagC = (1-ccov1_sep-ccovmu_sep+(1-hsig)*ccov1_sep*cc*(2-cc)) * diagC ... % regard old matrix - + ccov1_sep * pc.^2 ... % plus rank one update - + ccovmu_sep ... % plus rank mu update - * (diagC .* (arz(:,fitness.idxsel(1:mu)).^2 * weights)); - % * (repmat(diagC,1,mu) .* arz(:,fitness.idxsel(1:mu)).^2 * weights); - diagD = sqrt(diagC); % replaces eig(C) - else - arpos = (arx(:,fitness.idxsel(1:mu))-repmat(xold,1,mu)) / sigma; - % "active" CMA update: negative update, in case controlling pos. definiteness - if flgActiveCMA > 0 - % set parameters - neg.mu = mu; - neg.mueff = mueff; - if flgActiveCMA > 10 % flat weights with mu=lambda/2 - neg.mu = floor(lambda/2); - neg.mueff = neg.mu; - end - % neg.mu = ceil(min([N, lambda/4, mueff])); neg.mueff = mu; % i.e. neg.mu <= N - % Parameter study: in 3-D lambda=50,100, 10-D lambda=200,400, 30-D lambda=1000,2000 a - % three times larger neg.ccov does not work. - % increasing all ccov rates three times does work (probably because of the factor (1-ccovmu)) - % in 30-D to looks fine - - neg.ccov = (1 - ccovmu) * 0.25 * neg.mueff / ((N+2)^1.5 + 2*neg.mueff); - neg.minresidualvariance = 0.66; % keep at least 0.66 in all directions, small popsize are most critical - neg.alphaold = 0.5; % where to make up for the variance loss, 0.5 means no idea what to do - % 1 is slightly more robust and gives a better "guaranty" for pos. def., - % but does it make sense from the learning perspective for large ccovmu? - - neg.ccovfinal = neg.ccov; - - % prepare vectors, compute negative updating matrix Cneg and checking matrix Ccheck - arzneg = arz(:,fitness.idxsel(lambda:-1:lambda - neg.mu + 1)); - % i-th longest becomes i-th shortest - % TODO: this is not in compliance with the paper Hansen&Ros2010, - % where simply arnorms = arnorms(end:-1:1) ? - [arnorms, idxnorms] = sort(sqrt(sum(arzneg.^2, 1))); - [ignore, idxnorms] = sort(idxnorms); % inverse index - arnormfacs = arnorms(end:-1:1) ./ arnorms; - % arnormfacs = arnorms(randperm(neg.mu)) ./ arnorms; - arnorms = arnorms(end:-1:1); % for the record - if flgActiveCMA < 20 - arzneg = arzneg .* repmat(arnormfacs(idxnorms), N, 1); % E x*x' is N - % arzneg = sqrt(N) * arzneg ./ repmat(sqrt(sum(arzneg.^2, 1)), N, 1); % E x*x' is N - end - if flgActiveCMA < 10 && neg.mu == mu % weighted sum - if mod(flgActiveCMA, 10) == 1 % TODO: prevent this with a less tight but more efficient check (see below) - Ccheck = arzneg * diag(weights) * arzneg'; % in order to check the largest EV - end - artmp = BD * arzneg; - Cneg = artmp * diag(weights) * artmp'; - else % simple sum - if mod(flgActiveCMA, 10) == 1 - Ccheck = (1/neg.mu) * arzneg*arzneg'; % in order to check largest EV - end - artmp = BD * arzneg; - Cneg = (1/neg.mu) * artmp*artmp'; - - end - - % check pos.def. and set learning rate neg.ccov accordingly, - % this check makes the original choice of neg.ccov extremly failsafe - % still assuming C == BD*BD', which is only approxim. correct - if mod(flgActiveCMA, 10) == 1 && 1 - neg.ccov * arnorms(idxnorms).^2 * weights < neg.minresidualvariance - % TODO: the simple and cheap way would be to set - % fac = 1 - ccovmu - ccov1 OR 1 - mueff/lambda and - % neg.ccov = fac*(1 - neg.minresidualvariance) / (arnorms(idxnorms).^2 * weights) - % this is the more sophisticated way: - % maxeigenval = eigs(arzneg * arzneg', 1, 'lm', eigsopts); % not faster - maxeigenval = max(eig(Ccheck)); % norm is much slower, because (norm()==max(svd()) - %disp([countiter log10([neg.ccov, maxeigenval, arnorms(idxnorms).^2 * weights, max(arnorms)^2]), ... - % neg.ccov * arnorms(idxnorms).^2 * weights]) - % pause - % remove less than ??34*(1-cmu)%?? of variance in any direction - % 1-ccovmu is the variance left from the old C - neg.ccovfinal = min(neg.ccov, (1-ccovmu)*(1-neg.minresidualvariance)/maxeigenval); - % -ccov1 removed to avoid error message?? - if neg.ccovfinal < neg.ccov - disp(['active CMA at iteration ' num2str(countiter) ... - ': max EV ==', num2str([maxeigenval, neg.ccov, neg.ccovfinal])]); - end - end - % xmean = xold; % the distribution does not degenerate!? - % update C - C = (1-ccov1-ccovmu+neg.alphaold*neg.ccovfinal+(1-hsig)*ccov1*cc*(2-cc)) * C ... % regard old matrix - + ccov1 * pc*pc' ... % plus rank one update - + (ccovmu + (1-neg.alphaold)*neg.ccovfinal) ... % plus rank mu update - * arpos * (repmat(weights,1,N) .* arpos') ... - - neg.ccovfinal * Cneg; % minus rank mu update - else % no active (negative) update - C = (1-ccov1-ccovmu+(1-hsig)*ccov1*cc*(2-cc)) * C ... % regard old matrix - + ccov1 * pc*pc' ... % plus rank one update - + ccovmu ... % plus rank mu update - * arpos * (repmat(weights,1,N) .* arpos'); - % is now O(mu*N^2 + mu*N), was O(mu*N^2 + mu^2*N) when using diag(weights) - % for mu=30*N it is now 10 times faster, overall 3 times faster + arpos = (arx(:,fitness.idxsel(1:mu))-repmat(xold,1,mu)) / sigma; + % "active" CMA update: negative update, in case controlling pos. definiteness + if flgActiveCMA > 0 + % set parameters + neg.mu = mu; + neg.mueff = mueff; + if flgActiveCMA > 10 % flat weights with mu=lambda/2 + neg.mu = floor(lambda/2); + neg.mueff = neg.mu; end - diagC = diag(C); - end - end + % neg.mu = ceil(min([N, lambda/4, mueff])); neg.mueff = mu; % i.e. neg.mu <= N + % Parameter study: in 3-D lambda=50,100, 10-D lambda=200,400, 30-D lambda=1000,2000 a + % three times larger neg.ccov does not work. + % increasing all ccov rates three times does work (probably because of the factor (1-ccovmu)) + % in 30-D to looks fine - % the following is de-preciated and will be removed in future - % better setting for cc makes this hack obsolete - if 11 < 2 && ~flgscience - % remove momentum in ps, if ps is large and fitness is getting worse. - % this should rarely happen. - % this might very well be counterproductive in dynamic environments - if sum(ps.^2)/N > 1.5 + 10*(2/N)^.5 && ... - fitness.histsel(1) > max(fitness.histsel(2:3)) - ps = ps * sqrt(N*(1+max(0,log(sum(ps.^2)/N))) / sum(ps.^2)); - if flgdisplay - disp(['Momentum in ps removed at [niter neval]=' ... - num2str([countiter counteval]) ']']); + neg.ccov = (1 - ccovmu) * 0.25 * neg.mueff / ((N+2)^1.5 + 2*neg.mueff); + neg.minresidualvariance = 0.66; % keep at least 0.66 in all directions, small popsize are most critical + neg.alphaold = 0.5; % where to make up for the variance loss, 0.5 means no idea what to do + % 1 is slightly more robust and gives a better "guaranty" for pos. def., + % but does it make sense from the learning perspective for large ccovmu? + + neg.ccovfinal = neg.ccov; + + % prepare vectors, compute negative updating matrix Cneg and checking matrix Ccheck + arzneg = arz(:,fitness.idxsel(lambda:-1:lambda - neg.mu + 1)); + % i-th longest becomes i-th shortest + % TODO: this is not in compliance with the paper Hansen&Ros2010, + % where simply arnorms = arnorms(end:-1:1) ? + [arnorms, idxnorms] = sort(sqrt(sum(arzneg.^2, 1))); + [ignore, idxnorms] = sort(idxnorms); % inverse index + arnormfacs = arnorms(end:-1:1) ./ arnorms; + % arnormfacs = arnorms(randperm(neg.mu)) ./ arnorms; + arnorms = arnorms(end:-1:1); % for the record + if flgActiveCMA < 20 + arzneg = arzneg .* repmat(arnormfacs(idxnorms), N, 1); % E x*x' is N + % arzneg = sqrt(N) * arzneg ./ repmat(sqrt(sum(arzneg.^2, 1)), N, 1); % E x*x' is N end - end - end + if flgActiveCMA < 10 && neg.mu == mu % weighted sum + if mod(flgActiveCMA, 10) == 1 % TODO: prevent this with a less tight but more efficient check (see below) + Ccheck = arzneg * diag(weights) * arzneg'; % in order to check the largest EV + end + artmp = BD * arzneg; + Cneg = artmp * diag(weights) * artmp'; + else % simple sum + if mod(flgActiveCMA, 10) == 1 + Ccheck = (1/neg.mu) * arzneg*arzneg'; % in order to check largest EV + end + artmp = BD * arzneg; + Cneg = (1/neg.mu) * artmp*artmp'; - % Adapt sigma - if flg_future_setting % according to a suggestion from Dirk Arnold (2000) - % exp(1) is still not reasonably small enough - sigma = sigma * exp(min(1, (sum(ps.^2)/N - 1)/2 * cs/damps)); % Eq. (5) - else - % exp(1) is still not reasonably small enough - sigma = sigma * exp(min(1, (sqrt(sum(ps.^2))/chiN - 1) * cs/damps)); % Eq. (5) - end - % disp([countiter norm(ps)/chiN]); - - if 11 < 3 % testing with optimal step-size - if countiter == 1 - disp('*********** sigma set to const * ||x|| ******************'); - end - sigma = 0.04 * mueff * sqrt(sum(xmean.^2)) / N; % 20D,lam=1000:25e3 - sigma = 0.3 * mueff * sqrt(sum(xmean.^2)) / N; % 20D,lam=(40,1000):17e3 - % 75e3 with def (1.5) - % 35e3 with damps=0.25 - end - if 11 < 3 - if countiter == 1 - disp('*********** xmean set to const ******************'); - end - xmean = ones(N,1); - end - - % Update B and D from C - - if ~flgDiagonalOnly && (ccov1+ccovmu+neg.ccov) > 0 && mod(countiter, 1/(ccov1+ccovmu+neg.ccov)/N/10) < 1 - C=triu(C)+triu(C,1)'; % enforce symmetry to prevent complex numbers - [B,tmp] = eig(C); % eigen decomposition, B==normalized eigenvectors - % effort: approx. 15*N matrix-vector multiplications - diagD = diag(tmp); - - if any(~isfinite(diagD)) - clear idx; % prevents error under octave - save(['tmp' opts.SaveFilename]); - error(['function eig returned non-finited eigenvalues, cond(C)=' ... - num2str(cond(C)) ]); - end - if any(any(~isfinite(B))) - clear idx; % prevents error under octave - save(['tmp' opts.SaveFilename]); - error(['function eig returned non-finited eigenvectors, cond(C)=' ... - num2str(cond(C)) ]); - end - - % limit condition of C to 1e14 + 1 - if min(diagD) <= 0 - if stopOnWarnings - stopflag(end+1) = {'warnconditioncov'}; - else - warning(['Iteration ' num2str(countiter) ... - ': Eigenvalue (smaller) zero']); - diagD(diagD<0) = 0; - tmp = max(diagD)/1e14; - C = C + tmp*eye(N,N); diagD = diagD + tmp*ones(N,1); end - end - if max(diagD) > 1e14*min(diagD) - if stopOnWarnings - stopflag(end+1) = {'warnconditioncov'}; - else - warning(['Iteration ' num2str(countiter) ': condition of C ' ... - 'at upper limit' ]); - tmp = max(diagD)/1e14 - min(diagD); - C = C + tmp*eye(N,N); diagD = diagD + tmp*ones(N,1); - end - end + % check pos.def. and set learning rate neg.ccov accordingly, + % this check makes the original choice of neg.ccov extremly failsafe + % still assuming C == BD*BD', which is only approxim. correct + if mod(flgActiveCMA, 10) == 1 && 1 - neg.ccov * arnorms(idxnorms).^2 * weights < neg.minresidualvariance + % TODO: the simple and cheap way would be to set + % fac = 1 - ccovmu - ccov1 OR 1 - mueff/lambda and + % neg.ccov = fac*(1 - neg.minresidualvariance) / (arnorms(idxnorms).^2 * weights) + % this is the more sophisticated way: + % maxeigenval = eigs(arzneg * arzneg', 1, 'lm', eigsopts); % not faster + maxeigenval = max(eig(Ccheck)); % norm is much slower, because (norm()==max(svd()) + %disp([countiter log10([neg.ccov, maxeigenval, arnorms(idxnorms).^2 * weights, max(arnorms)^2]), ... + % neg.ccov * arnorms(idxnorms).^2 * weights]) + % pause + % remove less than ??34*(1-cmu)%?? of variance in any direction + % 1-ccovmu is the variance left from the old C + neg.ccovfinal = min(neg.ccov, (1-ccovmu)*(1-neg.minresidualvariance)/maxeigenval); + % -ccov1 removed to avoid error message?? + if neg.ccovfinal < neg.ccov + disp(['active CMA at iteration ' num2str(countiter) ... + ': max EV ==', num2str([maxeigenval, neg.ccov, neg.ccovfinal])]); + end + end + % xmean = xold; % the distribution does not degenerate!? + % update C + C = (1-ccov1-ccovmu+neg.alphaold*neg.ccovfinal+(1-hsig)*ccov1*cc*(2-cc)) * C ... % regard old matrix + + ccov1 * pc*pc' ... % plus rank one update + + (ccovmu + (1-neg.alphaold)*neg.ccovfinal) ... % plus rank mu update + * arpos * (repmat(weights,1,N) .* arpos') ... + - neg.ccovfinal * Cneg; % minus rank mu update + else % no active (negative) update + C = (1-ccov1-ccovmu+(1-hsig)*ccov1*cc*(2-cc)) * C ... % regard old matrix + + ccov1 * pc*pc' ... % plus rank one update + + ccovmu ... % plus rank mu update + * arpos * (repmat(weights,1,N) .* arpos'); + % is now O(mu*N^2 + mu*N), was O(mu*N^2 + mu^2*N) when using diag(weights) + % for mu=30*N it is now 10 times faster, overall 3 times faster + end diagC = diag(C); - diagD = sqrt(diagD); % D contains standard deviations now - % diagD = diagD / prod(diagD)^(1/N); C = C / prod(diagD)^(2/N); - BD = B.*repmat(diagD',N,1); % O(n^2) - end % if mod + end + end - % Align/rescale order of magnitude of scales of sigma and C for nicer output - % not a very usual case - if 1 < 2 && sigma > 1e10*max(diagD) - fac = sigma / max(diagD); - sigma = sigma/fac; - pc = fac * pc; - diagD = fac * diagD; - if ~flgDiagonalOnly - C = fac^2 * C; % disp(fac); - BD = B.*repmat(diagD',N,1); % O(n^2), but repmat might be inefficient todo? + % the following is de-preciated and will be removed in future + % better setting for cc makes this hack obsolete + if 11 < 2 && ~flgscience + % remove momentum in ps, if ps is large and fitness is getting worse. + % this should rarely happen. + % this might very well be counterproductive in dynamic environments + if sum(ps.^2)/N > 1.5 + 10*(2/N)^.5 && ... + fitness.histsel(1) > max(fitness.histsel(2:3)) + ps = ps * sqrt(N*(1+max(0,log(sum(ps.^2)/N))) / sum(ps.^2)); + if flgdisplay + disp(['Momentum in ps removed at [niter neval]=' ... + num2str([countiter counteval]) ']']); end - diagC = fac^2 * diagC; + end + end + + % Adapt sigma + if flg_future_setting % according to a suggestion from Dirk Arnold (2000) + % exp(1) is still not reasonably small enough + sigma = sigma * exp(min(1, (sum(ps.^2)/N - 1)/2 * cs/damps)); % Eq. (5) + else + % exp(1) is still not reasonably small enough + sigma = sigma * exp(min(1, (sqrt(sum(ps.^2))/chiN - 1) * cs/damps)); % Eq. (5) + end + % disp([countiter norm(ps)/chiN]); + + if 11 < 3 % testing with optimal step-size + if countiter == 1 + disp('*********** sigma set to const * ||x|| ******************'); + end + sigma = 0.04 * mueff * sqrt(sum(xmean.^2)) / N; % 20D,lam=1000:25e3 + sigma = 0.3 * mueff * sqrt(sum(xmean.^2)) / N; % 20D,lam=(40,1000):17e3 + % 75e3 with def (1.5) + % 35e3 with damps=0.25 + end + if 11 < 3 + if countiter == 1 + disp('*********** xmean set to const ******************'); + end + xmean = ones(N,1); + end + + % Update B and D from C + + if ~flgDiagonalOnly && (ccov1+ccovmu+neg.ccov) > 0 && mod(countiter, 1/(ccov1+ccovmu+neg.ccov)/N/10) < 1 + C=triu(C)+triu(C,1)'; % enforce symmetry to prevent complex numbers + [B,tmp] = eig(C); % eigen decomposition, B==normalized eigenvectors + % effort: approx. 15*N matrix-vector multiplications + diagD = diag(tmp); + + if any(~isfinite(diagD)) + clear idx; % prevents error under octave + save(['tmp' opts.SaveFilename]); + error(['function eig returned non-finited eigenvalues, cond(C)=' ... + num2str(cond(C)) ]); + end + if any(any(~isfinite(B))) + clear idx; % prevents error under octave + save(['tmp' opts.SaveFilename]); + error(['function eig returned non-finited eigenvectors, cond(C)=' ... + num2str(cond(C)) ]); end - if flgDiagonalOnly > 1 && countiter > flgDiagonalOnly - % full covariance matrix from now on - flgDiagonalOnly = 0; - B = eye(N,N); - BD = diag(diagD); - C = diag(diagC); % is better, because correlations are spurious anyway + % limit condition of C to 1e14 + 1 + if min(diagD) <= 0 + if stopOnWarnings + stopflag(end+1) = {'warnconditioncov'}; + else + warning(['Iteration ' num2str(countiter) ... + ': Eigenvalue (smaller) zero']); + diagD(diagD<0) = 0; + tmp = max(diagD)/1e14; + C = C + tmp*eye(N,N); diagD = diagD + tmp*ones(N,1); + end + end + if max(diagD) > 1e14*min(diagD) + if stopOnWarnings + stopflag(end+1) = {'warnconditioncov'}; + else + warning(['Iteration ' num2str(countiter) ': condition of C ' ... + 'at upper limit' ]); + tmp = max(diagD)/1e14 - min(diagD); + C = C + tmp*eye(N,N); diagD = diagD + tmp*ones(N,1); + end end - if noiseHandling - if countiter == 1 % assign firstvarargin for noise treatment e.g. as #reevaluations - if ~isempty(varargin) && length(varargin{1}) == 1 && isnumeric(varargin{1}) - if irun == 1 - firstvarargin = varargin{1}; - else - varargin{1} = firstvarargin; % reset varargin{1} - end + diagC = diag(C); + diagD = sqrt(diagD); % D contains standard deviations now + % diagD = diagD / prod(diagD)^(1/N); C = C / prod(diagD)^(2/N); + BD = B.*repmat(diagD',N,1); % O(n^2) + end % if mod + + % Align/rescale order of magnitude of scales of sigma and C for nicer output + % not a very usual case + if 1 < 2 && sigma > 1e10*max(diagD) + fac = sigma / max(diagD); + sigma = sigma/fac; + pc = fac * pc; + diagD = fac * diagD; + if ~flgDiagonalOnly + C = fac^2 * C; % disp(fac); + BD = B.*repmat(diagD',N,1); % O(n^2), but repmat might be inefficient todo? + end + diagC = fac^2 * diagC; + end + + if flgDiagonalOnly > 1 && countiter > flgDiagonalOnly + % full covariance matrix from now on + flgDiagonalOnly = 0; + B = eye(N,N); + BD = diag(diagD); + C = diag(diagC); % is better, because correlations are spurious anyway + end + + if noiseHandling + if countiter == 1 % assign firstvarargin for noise treatment e.g. as #reevaluations + if ~isempty(varargin) && length(varargin{1}) == 1 && isnumeric(varargin{1}) + if irun == 1 + firstvarargin = varargin{1}; else - firstvarargin = 0; + varargin{1} = firstvarargin; % reset varargin{1} end + else + firstvarargin = 0; end - if noiseSS < 0 && noiseMinMaxEvals(2) > noiseMinMaxEvals(1) && firstvarargin - varargin{1} = max(noiseMinMaxEvals(1), varargin{1} / noiseAlphaEvals^(1/4)); % still experimental - elseif noiseSS > 0 - if ~isempty(noiseCallback) % to be removed? - res = feval(noiseCallback); % should also work without output argument!? - if ~isempty(res) && res > 1 % TODO: decide for interface of callback - % also a dynamic popsize could be done here - sigma = sigma * noiseAlpha; - end - else - if noiseMinMaxEvals(2) > noiseMinMaxEvals(1) && firstvarargin - varargin{1} = min(noiseMinMaxEvals(2), varargin{1} * noiseAlphaEvals); - end - + end + if noiseSS < 0 && noiseMinMaxEvals(2) > noiseMinMaxEvals(1) && firstvarargin + varargin{1} = max(noiseMinMaxEvals(1), varargin{1} / noiseAlphaEvals^(1/4)); % still experimental + elseif noiseSS > 0 + if ~isempty(noiseCallback) % to be removed? + res = feval(noiseCallback); % should also work without output argument!? + if ~isempty(res) && res > 1 % TODO: decide for interface of callback + % also a dynamic popsize could be done here sigma = sigma * noiseAlpha; - % lambda = ceil(0.1 * sqrt(lambda) + lambda); - % TODO: find smallest increase of lambda with log-linear - % convergence in iterations end - % qqq experimental: take a mean to estimate the true optimum - noiseN = noiseN + 1; - if noiseN == 1 - noiseX = xmean; - else - noiseX = noiseX + (3/noiseN) * (xmean - noiseX); - end - end - end - - % ----- numerical error management ----- - % Adjust maximal coordinate axis deviations - if any(sigma*sqrt(diagC) > maxdx) - sigma = min(maxdx ./ sqrt(diagC)); - %warning(['Iteration ' num2str(countiter) ': coordinate axis std ' ... - % 'deviation at upper limit of ' num2str(maxdx)]); - % stopflag(end+1) = {'maxcoorddev'}; - end - % Adjust minimal coordinate axis deviations - if any(sigma*sqrt(diagC) < mindx) - sigma = max(mindx ./ sqrt(diagC)) * exp(0.05+cs/damps); - %warning(['Iteration ' num2str(countiter) ': coordinate axis std ' ... - % 'deviation at lower limit of ' num2str(mindx)]); - % stopflag(end+1) = {'mincoorddev'};; - end - % Adjust too low coordinate axis deviations - if any(xmean == xmean + 0.2*sigma*sqrt(diagC)) - if stopOnWarnings - stopflag(end+1) = {'warnnoeffectcoord'}; else - warning(['Iteration ' num2str(countiter) ': coordinate axis std ' ... - 'deviation too low' ]); - if flgDiagonalOnly - diagC = diagC + (ccov1_sep+ccovmu_sep) * (diagC .* ... - (xmean == xmean + 0.2*sigma*sqrt(diagC))); - else - C = C + (ccov1+ccovmu) * diag(diagC .* ... - (xmean == xmean + 0.2*sigma*sqrt(diagC))); + if noiseMinMaxEvals(2) > noiseMinMaxEvals(1) && firstvarargin + varargin{1} = min(noiseMinMaxEvals(2), varargin{1} * noiseAlphaEvals); end - sigma = sigma * exp(0.05+cs/damps); + + sigma = sigma * noiseAlpha; + % lambda = ceil(0.1 * sqrt(lambda) + lambda); + % TODO: find smallest increase of lambda with log-linear + % convergence in iterations + end + % qqq experimental: take a mean to estimate the true optimum + noiseN = noiseN + 1; + if noiseN == 1 + noiseX = xmean; + else + noiseX = noiseX + (3/noiseN) * (xmean - noiseX); end end - % Adjust step size in case of (numerical) precision problem - if flgDiagonalOnly - tmp = 0.1*sigma*diagD; + end + + % ----- numerical error management ----- + % Adjust maximal coordinate axis deviations + if any(sigma*sqrt(diagC) > maxdx) + sigma = min(maxdx ./ sqrt(diagC)); + %warning(['Iteration ' num2str(countiter) ': coordinate axis std ' ... + % 'deviation at upper limit of ' num2str(maxdx)]); + % stopflag(end+1) = {'maxcoorddev'}; + end + % Adjust minimal coordinate axis deviations + if any(sigma*sqrt(diagC) < mindx) + sigma = max(mindx ./ sqrt(diagC)) * exp(0.05+cs/damps); + %warning(['Iteration ' num2str(countiter) ': coordinate axis std ' ... + % 'deviation at lower limit of ' num2str(mindx)]); + % stopflag(end+1) = {'mincoorddev'};; + end + % Adjust too low coordinate axis deviations + if any(xmean == xmean + 0.2*sigma*sqrt(diagC)) + if stopOnWarnings + stopflag(end+1) = {'warnnoeffectcoord'}; else - tmp = 0.1*sigma*BD(:,1+floor(mod(countiter,N))); - end - if all(xmean == xmean + tmp) - i = 1+floor(mod(countiter,N)); - if stopOnWarnings - stopflag(end+1) = {'warnnoeffectaxis'}; + warning(['Iteration ' num2str(countiter) ': coordinate axis std ' ... + 'deviation too low' ]); + if flgDiagonalOnly + diagC = diagC + (ccov1_sep+ccovmu_sep) * (diagC .* ... + (xmean == xmean + 0.2*sigma*sqrt(diagC))); else + C = C + (ccov1+ccovmu) * diag(diagC .* ... + (xmean == xmean + 0.2*sigma*sqrt(diagC))); + end + sigma = sigma * exp(0.05+cs/damps); + end + end + % Adjust step size in case of (numerical) precision problem + if flgDiagonalOnly + tmp = 0.1*sigma*diagD; + else + tmp = 0.1*sigma*BD(:,1+floor(mod(countiter,N))); + end + if all(xmean == xmean + tmp) + i = 1+floor(mod(countiter,N)); + if stopOnWarnings + stopflag(end+1) = {'warnnoeffectaxis'}; + else + warning(['Iteration ' num2str(countiter) ... + ': main axis standard deviation ' ... + num2str(sigma*diagD(i)) ' has no effect' ]); + sigma = sigma * exp(0.2+cs/damps); + end + end + % Adjust step size in case of equal function values (flat fitness) + % isequalfuncvalues = 0; + if fitness.sel(1) == fitness.sel(1+ceil(0.1+lambda/4)) + % isequalfuncvalues = 1; + if stopOnEqualFunctionValues + arrEqualFunvals = [countiter arrEqualFunvals(1:end-1)]; + % stop if this happens in more than 33% + if arrEqualFunvals(end) > countiter - 3 * length(arrEqualFunvals) + stopflag(end+1) = {'equalfunvals'}; + end + else + if flgWarnOnEqualFunctionValues warning(['Iteration ' num2str(countiter) ... - ': main axis standard deviation ' ... - num2str(sigma*diagD(i)) ' has no effect' ]); - sigma = sigma * exp(0.2+cs/damps); + ': equal function values f=' num2str(fitness.sel(1)) ... + ' at maximal main axis sigma ' ... + num2str(sigma*max(diagD))]); end + sigma = sigma * exp(0.2+cs/damps); end - % Adjust step size in case of equal function values (flat fitness) - % isequalfuncvalues = 0; - if fitness.sel(1) == fitness.sel(1+ceil(0.1+lambda/4)) - % isequalfuncvalues = 1; - if stopOnEqualFunctionValues - arrEqualFunvals = [countiter arrEqualFunvals(1:end-1)]; - % stop if this happens in more than 33% - if arrEqualFunvals(end) > countiter - 3 * length(arrEqualFunvals) - stopflag(end+1) = {'equalfunvals'}; + end + % Adjust step size in case of equal function values + if countiter > 2 && myrange([fitness.hist fitness.sel(1)]) == 0 + if stopOnWarnings + stopflag(end+1) = {'warnequalfunvalhist'}; + else + warning(['Iteration ' num2str(countiter) ... + ': equal function values in history at maximal main ' ... + 'axis sigma ' num2str(sigma*max(diagD))]); + sigma = sigma * exp(0.2+cs/damps); + end + end + + % ----- end numerical error management ----- + + % Keep overall best solution + out.evals = counteval; + out.solutions.evals = counteval; + out.solutions.mean.x = xmean; + out.solutions.mean.f = fmean; + out.solutions.mean.evals = counteval; + out.solutions.recentbest.x = arxvalid(:, fitness.idx(1)); + out.solutions.recentbest.f = fitness.raw(1); + out.solutions.recentbest.evals = counteval + fitness.idx(1) - lambda; + out.solutions.recentworst.x = arxvalid(:, fitness.idx(end)); + out.solutions.recentworst.f = fitness.raw(end); + out.solutions.recentworst.evals = counteval + fitness.idx(end) - lambda; + if fitness.hist(1) < out.solutions.bestever.f + out.solutions.bestever.x = arxvalid(:, fitness.idx(1)); + out.solutions.bestever.f = fitness.hist(1); + out.solutions.bestever.evals = counteval + fitness.idx(1) - lambda; + bestever = out.solutions.bestever; + end + + % Set stop flag + if fitness.raw(1) <= stopFitness, stopflag(end+1) = {'fitness'}; end + if counteval >= stopMaxFunEvals, stopflag(end+1) = {'maxfunevals'}; end + if countiter >= stopMaxIter, stopflag(end+1) = {'maxiter'}; end + if all(sigma*(max(abs(pc), sqrt(diagC))) < stopTolX) + stopflag(end+1) = {'tolx'}; + end + if any(sigma*sqrt(diagC) > stopTolUpX) + stopflag(end+1) = {'tolupx'}; + end + if sigma*max(diagD) == 0 % should never happen + stopflag(end+1) = {'bug'}; + end + if countiter > 2 && myrange([fitness.sel fitness.hist]) <= stopTolFun + stopflag(end+1) = {'tolfun'}; + end + if countiter >= length(fitness.hist) && myrange(fitness.hist) <= stopTolHistFun + stopflag(end+1) = {'tolhistfun'}; + end + l = floor(length(fitness.histbest)/3); + if 1 < 2 && stopOnStagnation && ... % leads sometimes early stop on ftablet, fcigtab + countiter > N * (5+100/lambda) && ... + length(fitness.histbest) > 100 && ... + median(fitness.histmedian(1:l)) >= median(fitness.histmedian(end-l:end)) && ... + median(fitness.histbest(1:l)) >= median(fitness.histbest(end-l:end)) + stopflag(end+1) = {'stagnation'}; + end + + if counteval >= stopFunEvals || countiter >= stopIter + stopflag(end+1) = {'stoptoresume'}; + if length(stopflag) == 1 && flgsaving == 0 + error('To resume later the saving option needs to be set'); + end + end + % read stopping message from file signals.par + if flgreadsignals + fid = fopen('./signals.par', 'rt'); % can be performance critical + while fid > 0 + strline = fgetl(fid); %fgets(fid, 300); + if strline < 0 % fgets and fgetl returns -1 at end of file + break + end + % 'stop filename' sets stopflag to manual + str = sscanf(strline, ' %s %s', 2); + if strcmp(str, ['stop' opts.LogFilenamePrefix]) + stopflag(end+1) = {'manual'}; + break + end + % 'skip filename run 3' skips a run, but not the last + str = sscanf(strline, ' %s %s %s', 3); + if strcmp(str, ['skip' opts.LogFilenamePrefix 'run']) + i = strfind(strline, 'run'); + if irun == sscanf(strline(i+3:end), ' %d ', 1) && irun <= myeval(opts.Restarts) + stopflag(end+1) = {'skipped'}; end + end + end % while, break + if fid > 0 + fclose(fid); + clear fid; % prevents strange error under octave + end + end + + out.stopflag = stopflag; + + % ----- output generation ----- + if verbosemodulo > 0 && isfinite(verbosemodulo) + if countiter == 1 || mod(countiter, 10*verbosemodulo) < 1 + disp(['Iterat, #Fevals: Function Value (median,worst) ' ... + '|Axis Ratio|' ... + 'idx:Min SD idx:Max SD']); + end + if mod(countiter, verbosemodulo) < 1 ... + || (verbosemodulo > 0 && isfinite(verbosemodulo) && ... + (countiter < 3 || ~isempty(stopflag))) + [minstd, minstdidx] = min(sigma*sqrt(diagC)); + [maxstd, maxstdidx] = max(sigma*sqrt(diagC)); + % format display nicely + disp([repmat(' ',1,4-floor(log10(countiter))) ... + num2str(countiter) ' , ' ... + repmat(' ',1,5-floor(log10(counteval))) ... + num2str(counteval) ' : ' ... + num2str(fitness.hist(1), '%.13e') ... + ' +(' num2str(median(fitness.raw)-fitness.hist(1), '%.0e ') ... + ',' num2str(max(fitness.raw)-fitness.hist(1), '%.0e ') ... + ') | ' ... + num2str(max(diagD)/min(diagD), '%4.2e') ' | ' ... + repmat(' ',1,1-floor(log10(minstdidx))) num2str(minstdidx) ':' ... + num2str(minstd, ' %.1e') ' ' ... + repmat(' ',1,1-floor(log10(maxstdidx))) num2str(maxstdidx) ':' ... + num2str(maxstd, ' %.1e')]); + end + end + + % measure time for recording data + if countiter < 3 + time.c = 0.05; + time.nonoutput = 0; + time.recording = 0; + time.saving = 0.15; % first saving after 3 seconds of 100 iterations + time.plotting = 0; + elseif countiter > 300 + % set backward horizon, must be long enough to cover infrequent plotting etc + % time.c = min(1, time.nonoutput/3 + 1e-9); + time.c = max(1e-5, 0.1/sqrt(countiter)); % mean over all or 1e-5 + end + % get average time per iteration + time.t1 = clock; + time.act = max(0,etime(time.t1, time.t0)); + time.nonoutput = (1-time.c) * time.nonoutput ... + + time.c * time.act; + + time.recording = (1-time.c) * time.recording; % per iteration + time.saving = (1-time.c) * time.saving; + time.plotting = (1-time.c) * time.plotting; + + % record output data, concerning time issues + if savemodulo && savetime && (countiter < 1e2 || ~isempty(stopflag) || ... + countiter >= outiter + savemodulo) + outiter = countiter; + % Save output data to files + for namecell = filenames(:)' + name = namecell{:}; + + [fid, err] = fopen(['./' filenameprefix name '.dat'], 'a'); + if fid < 1 % err ~= 0 + warning(['could not open ' filenameprefix name '.dat']); else - if flgWarnOnEqualFunctionValues - warning(['Iteration ' num2str(countiter) ... - ': equal function values f=' num2str(fitness.sel(1)) ... - ' at maximal main axis sigma ' ... - num2str(sigma*max(diagD))]); - end - sigma = sigma * exp(0.2+cs/damps); - end - end - % Adjust step size in case of equal function values - if countiter > 2 && myrange([fitness.hist fitness.sel(1)]) == 0 - if stopOnWarnings - stopflag(end+1) = {'warnequalfunvalhist'}; - else - warning(['Iteration ' num2str(countiter) ... - ': equal function values in history at maximal main ' ... - 'axis sigma ' num2str(sigma*max(diagD))]); - sigma = sigma * exp(0.2+cs/damps); - end - end - - % ----- end numerical error management ----- - - % Keep overall best solution - out.evals = counteval; - out.solutions.evals = counteval; - out.solutions.mean.x = xmean; - out.solutions.mean.f = fmean; - out.solutions.mean.evals = counteval; - out.solutions.recentbest.x = arxvalid(:, fitness.idx(1)); - out.solutions.recentbest.f = fitness.raw(1); - out.solutions.recentbest.evals = counteval + fitness.idx(1) - lambda; - out.solutions.recentworst.x = arxvalid(:, fitness.idx(end)); - out.solutions.recentworst.f = fitness.raw(end); - out.solutions.recentworst.evals = counteval + fitness.idx(end) - lambda; - if fitness.hist(1) < out.solutions.bestever.f - out.solutions.bestever.x = arxvalid(:, fitness.idx(1)); - out.solutions.bestever.f = fitness.hist(1); - out.solutions.bestever.evals = counteval + fitness.idx(1) - lambda; - bestever = out.solutions.bestever; - end - - % Set stop flag - if fitness.raw(1) <= stopFitness, stopflag(end+1) = {'fitness'}; end - if counteval >= stopMaxFunEvals, stopflag(end+1) = {'maxfunevals'}; end - if countiter >= stopMaxIter, stopflag(end+1) = {'maxiter'}; end - if all(sigma*(max(abs(pc), sqrt(diagC))) < stopTolX) - stopflag(end+1) = {'tolx'}; - end - if any(sigma*sqrt(diagC) > stopTolUpX) - stopflag(end+1) = {'tolupx'}; - end - if sigma*max(diagD) == 0 % should never happen - stopflag(end+1) = {'bug'}; - end - if countiter > 2 && myrange([fitness.sel fitness.hist]) <= stopTolFun - stopflag(end+1) = {'tolfun'}; - end - if countiter >= length(fitness.hist) && myrange(fitness.hist) <= stopTolHistFun - stopflag(end+1) = {'tolhistfun'}; - end - l = floor(length(fitness.histbest)/3); - if 1 < 2 && stopOnStagnation && ... % leads sometimes early stop on ftablet, fcigtab - countiter > N * (5+100/lambda) && ... - length(fitness.histbest) > 100 && ... - median(fitness.histmedian(1:l)) >= median(fitness.histmedian(end-l:end)) && ... - median(fitness.histbest(1:l)) >= median(fitness.histbest(end-l:end)) - stopflag(end+1) = {'stagnation'}; - end - - if counteval >= stopFunEvals || countiter >= stopIter - stopflag(end+1) = {'stoptoresume'}; - if length(stopflag) == 1 && flgsaving == 0 - error('To resume later the saving option needs to be set'); - end - end - % read stopping message from file signals.par - if flgreadsignals - fid = fopen('./signals.par', 'rt'); % can be performance critical - while fid > 0 - strline = fgetl(fid); %fgets(fid, 300); - if strline < 0 % fgets and fgetl returns -1 at end of file - break - end - % 'stop filename' sets stopflag to manual - str = sscanf(strline, ' %s %s', 2); - if strcmp(str, ['stop' opts.LogFilenamePrefix]) - stopflag(end+1) = {'manual'}; - break - end - % 'skip filename run 3' skips a run, but not the last - str = sscanf(strline, ' %s %s %s', 3); - if strcmp(str, ['skip' opts.LogFilenamePrefix 'run']) - i = strfind(strline, 'run'); - if irun == sscanf(strline(i+3:end), ' %d ', 1) && irun <= myeval(opts.Restarts) - stopflag(end+1) = {'skipped'}; + if strcmp(name, 'axlen') + fprintf(fid, '%d %d %e %e %e ', countiter, counteval, sigma, ... + max(diagD), min(diagD)); + fprintf(fid, '%e ', sort(diagD)); + fprintf(fid, '\n'); + elseif strcmp(name, 'disp') % TODO + elseif strcmp(name, 'fit') + fprintf(fid, '%ld %ld %e %e %25.18e %25.18e %25.18e %25.18e', ... + countiter, counteval, sigma, max(diagD)/min(diagD), ... + out.solutions.bestever.f, ... + fitness.raw(1), median(fitness.raw), fitness.raw(end)); + if ~isempty(varargin) && length(varargin{1}) == 1 && isnumeric(varargin{1}) && varargin{1} ~= 0 + fprintf(fid, ' %f', varargin{1}); end - end - end % while, break - if fid > 0 - fclose(fid); - clear fid; % prevents strange error under octave - end - end - - out.stopflag = stopflag; - - % ----- output generation ----- - if verbosemodulo > 0 && isfinite(verbosemodulo) - if countiter == 1 || mod(countiter, 10*verbosemodulo) < 1 - disp(['Iterat, #Fevals: Function Value (median,worst) ' ... - '|Axis Ratio|' ... - 'idx:Min SD idx:Max SD']); - end - if mod(countiter, verbosemodulo) < 1 ... - || (verbosemodulo > 0 && isfinite(verbosemodulo) && ... - (countiter < 3 || ~isempty(stopflag))) - [minstd, minstdidx] = min(sigma*sqrt(diagC)); - [maxstd, maxstdidx] = max(sigma*sqrt(diagC)); - % format display nicely - disp([repmat(' ',1,4-floor(log10(countiter))) ... - num2str(countiter) ' , ' ... - repmat(' ',1,5-floor(log10(counteval))) ... - num2str(counteval) ' : ' ... - num2str(fitness.hist(1), '%.13e') ... - ' +(' num2str(median(fitness.raw)-fitness.hist(1), '%.0e ') ... - ',' num2str(max(fitness.raw)-fitness.hist(1), '%.0e ') ... - ') | ' ... - num2str(max(diagD)/min(diagD), '%4.2e') ' | ' ... - repmat(' ',1,1-floor(log10(minstdidx))) num2str(minstdidx) ':' ... - num2str(minstd, ' %.1e') ' ' ... - repmat(' ',1,1-floor(log10(maxstdidx))) num2str(maxstdidx) ':' ... - num2str(maxstd, ' %.1e')]); - end - end - - % measure time for recording data - if countiter < 3 - time.c = 0.05; - time.nonoutput = 0; - time.recording = 0; - time.saving = 0.15; % first saving after 3 seconds of 100 iterations - time.plotting = 0; - elseif countiter > 300 - % set backward horizon, must be long enough to cover infrequent plotting etc - % time.c = min(1, time.nonoutput/3 + 1e-9); - time.c = max(1e-5, 0.1/sqrt(countiter)); % mean over all or 1e-5 - end - % get average time per iteration - time.t1 = clock; - time.act = max(0,etime(time.t1, time.t0)); - time.nonoutput = (1-time.c) * time.nonoutput ... - + time.c * time.act; - - time.recording = (1-time.c) * time.recording; % per iteration - time.saving = (1-time.c) * time.saving; - time.plotting = (1-time.c) * time.plotting; - - % record output data, concerning time issues - if savemodulo && savetime && (countiter < 1e2 || ~isempty(stopflag) || ... - countiter >= outiter + savemodulo) - outiter = countiter; - % Save output data to files - for namecell = filenames(:)' - name = namecell{:}; - - [fid, err] = fopen(['./' filenameprefix name '.dat'], 'a'); - if fid < 1 % err ~= 0 - warning(['could not open ' filenameprefix name '.dat']); - else - if strcmp(name, 'axlen') - fprintf(fid, '%d %d %e %e %e ', countiter, counteval, sigma, ... - max(diagD), min(diagD)); - fprintf(fid, '%e ', sort(diagD)); - fprintf(fid, '\n'); - elseif strcmp(name, 'disp') % TODO - elseif strcmp(name, 'fit') - fprintf(fid, '%ld %ld %e %e %25.18e %25.18e %25.18e %25.18e', ... - countiter, counteval, sigma, max(diagD)/min(diagD), ... - out.solutions.bestever.f, ... - fitness.raw(1), median(fitness.raw), fitness.raw(end)); - if ~isempty(varargin) && length(varargin{1}) == 1 && isnumeric(varargin{1}) && varargin{1} ~= 0 - fprintf(fid, ' %f', varargin{1}); - end - fprintf(fid, '\n'); - elseif strcmp(name, 'stddev') - fprintf(fid, '%ld %ld %e 0 0 ', countiter, counteval, sigma); - fprintf(fid, '%e ', sigma*sqrt(diagC)); - fprintf(fid, '\n'); - elseif strcmp(name, 'xmean') - if isnan(fmean) - fprintf(fid, '%ld %ld 0 0 0 ', countiter, counteval); - else - fprintf(fid, '%ld %ld 0 0 %e ', countiter, counteval, fmean); - end - fprintf(fid, '%e ', xmean); - fprintf(fid, '\n'); - elseif strcmp(name, 'xrecentbest') - % TODO: fitness is inconsistent with x-value - fprintf(fid, '%ld %ld %25.18e 0 0 ', countiter, counteval, fitness.raw(1)); - fprintf(fid, '%e ', arx(:,fitness.idx(1))); - fprintf(fid, '\n'); - end - fclose(fid); - end - end - - % get average time for recording data - time.t2 = clock; - time.recording = time.recording + time.c * max(0,etime(time.t2, time.t1)); - - % plot - if flgplotting && countiter > 1 - if countiter == 2 - iterplotted = 0; - end - if ~isempty(stopflag) || ... - ((time.nonoutput+time.recording) * (countiter - iterplotted) > 1 && ... - time.plotting < 0.05 * (time.nonoutput+time.recording)) - local_plotcmaesdat(324, filenameprefix); - iterplotted = countiter; - % outplot(out); % outplot defined below - if time.plotting == 0 % disregard opening of the window - time.plotting = time.nonoutput+time.recording; + fprintf(fid, '\n'); + elseif strcmp(name, 'stddev') + fprintf(fid, '%ld %ld %e 0 0 ', countiter, counteval, sigma); + fprintf(fid, '%e ', sigma*sqrt(diagC)); + fprintf(fid, '\n'); + elseif strcmp(name, 'xmean') + if isnan(fmean) + fprintf(fid, '%ld %ld 0 0 0 ', countiter, counteval); else - time.plotting = time.plotting + time.c * max(0,etime(clock, time.t2)); + fprintf(fid, '%ld %ld 0 0 %e ', countiter, counteval, fmean); end + fprintf(fid, '%e ', xmean); + fprintf(fid, '\n'); + elseif strcmp(name, 'xrecentbest') + % TODO: fitness is inconsistent with x-value + fprintf(fid, '%ld %ld %25.18e 0 0 ', countiter, counteval, fitness.raw(1)); + fprintf(fid, '%e ', arx(:,fitness.idx(1))); + fprintf(fid, '\n'); end - end - if countiter > 100 + 20 && savemodulo && ... - time.recording * countiter > 0.1 && ... % absolute time larger 0.1 second - time.recording > savetime * (time.nonoutput+time.recording) / 100 - savemodulo = floor(1.1 * savemodulo) + 1; - % disp('++savemodulo'); %qqq - end - end % if output - - % save everything - time.t3 = clock; - if ~isempty(stopflag) || time.saving < 0.05 * time.nonoutput || countiter == 100 - xmin = arxvalid(:, fitness.idx(1)); - fmin = fitness.raw(1); - if flgsaving && countiter > 2 - clear idx; % prevents error under octave - % -v6 : non-compressed non-unicode for version 6 and earlier - if ~isempty(strsaving) && ~isoctave - save('-mat', strsaving, opts.SaveFilename); % for inspection and possible restart - else - save('-mat', opts.SaveFilename); % for inspection and possible restart - end - time.saving = time.saving + time.c * max(0,etime(clock, time.t3)); + fclose(fid); end end - time.t0 = clock; - % ----- end output generation ----- + % get average time for recording data + time.t2 = clock; + time.recording = time.recording + time.c * max(0,etime(time.t2, time.t1)); + + % plot + if flgplotting && countiter > 1 + if countiter == 2 + iterplotted = 0; + end + if ~isempty(stopflag) || ... + ((time.nonoutput+time.recording) * (countiter - iterplotted) > 1 && ... + time.plotting < 0.05 * (time.nonoutput+time.recording)) + local_plotcmaesdat(324, filenameprefix); + iterplotted = countiter; + % outplot(out); % outplot defined below + if time.plotting == 0 % disregard opening of the window + time.plotting = time.nonoutput+time.recording; + else + time.plotting = time.plotting + time.c * max(0,etime(clock, time.t2)); + end + end + end + if countiter > 100 + 20 && savemodulo && ... + time.recording * countiter > 0.1 && ... % absolute time larger 0.1 second + time.recording > savetime * (time.nonoutput+time.recording) / 100 + savemodulo = floor(1.1 * savemodulo) + 1; + % disp('++savemodulo'); %qqq + end + end % if output + + % save everything + time.t3 = clock; + if ~isempty(stopflag) || time.saving < 0.05 * time.nonoutput || countiter == 100 + xmin = arxvalid(:, fitness.idx(1)); + fmin = fitness.raw(1); + if flgsaving && countiter > 2 + clear idx; % prevents error under octave + % -v6 : non-compressed non-unicode for version 6 and earlier + if ~isempty(strsaving) && ~isoctave + save('-mat', strsaving, opts.SaveFilename); % for inspection and possible restart + else + save('-mat', opts.SaveFilename); % for inspection and possible restart + end + time.saving = time.saving + time.c * max(0,etime(clock, time.t3)); + end + end + time.t0 = clock; + + % ----- end output generation ----- end % while, end generation loop - % -------------------- Final Procedures ------------------------------- + % -------------------- Final Procedures ------------------------------- - % Evaluate xmean and return best recent point in xmin - fmin = fitness.raw(1); - xmin = arxvalid(:, fitness.idx(1)); % Return best point of last generation. - if length(stopflag) > sum(strcmp(stopflag, 'stoptoresume')) % final stopping - out.solutions.mean.f = ... - feval(fitfun, xintobounds(xmean, lbounds, ubounds), varargin{:}); - counteval = counteval + 1; - out.solutions.mean.evals = counteval; - if out.solutions.mean.f < fitness.raw(1) - fmin = out.solutions.mean.f; - xmin = xintobounds(xmean, lbounds, ubounds); % Return xmean as best point - end - if out.solutions.mean.f < out.solutions.bestever.f - out.solutions.bestever = out.solutions.mean; % Return xmean as bestever point - out.solutions.bestever.x = xintobounds(xmean, lbounds, ubounds); - bestever = out.solutions.bestever; - end + % Evaluate xmean and return best recent point in xmin + fmin = fitness.raw(1); + xmin = arxvalid(:, fitness.idx(1)); % Return best point of last generation. + if length(stopflag) > sum(strcmp(stopflag, 'stoptoresume')) % final stopping + out.solutions.mean.f = ... + feval(fitfun, xintobounds(xmean, lbounds, ubounds), varargin{:}); + counteval = counteval + 1; + out.solutions.mean.evals = counteval; + if out.solutions.mean.f < fitness.raw(1) + fmin = out.solutions.mean.f; + xmin = xintobounds(xmean, lbounds, ubounds); % Return xmean as best point end + if out.solutions.mean.f < out.solutions.bestever.f + out.solutions.bestever = out.solutions.mean; % Return xmean as bestever point + out.solutions.bestever.x = xintobounds(xmean, lbounds, ubounds); + bestever = out.solutions.bestever; + end + end - % Save everything and display final message - if flgsavingfinal - clear idx; % prevents error under octave - if ~isempty(strsaving) && ~isoctave - save('-mat', strsaving, opts.SaveFilename); % for inspection and possible restart - else - save('-mat', opts.SaveFilename); % for inspection and possible restart - end - message = [' (saved to ' opts.SaveFilename ')']; + % Save everything and display final message + if flgsavingfinal + clear idx; % prevents error under octave + if ~isempty(strsaving) && ~isoctave + save('-mat', strsaving, opts.SaveFilename); % for inspection and possible restart else - message = []; + save('-mat', opts.SaveFilename); % for inspection and possible restart end + message = [' (saved to ' opts.SaveFilename ')']; + else + message = []; + end - if flgdisplay - disp(['#Fevals: f(returned x) | bestever.f | stopflag' ... - message]); - if isoctave - strstop = stopflag(:); - else - strcat(stopflag(:), '.'); - end - strstop = stopflag(:); %strcat(stopflag(:), '.'); - disp([repmat(' ',1,6-floor(log10(counteval))) ... - num2str(counteval, '%6.0f') ': ' num2str(fmin, '%.11e') ' | ' ... - num2str(out.solutions.bestever.f, '%.11e') ' | ' ... - strstop{1:end}]); - if N < 102 - disp(['mean solution:' sprintf(' %+.1e', xmean)]); - disp(['std deviation:' sprintf(' %.1e', sigma*sqrt(diagC))]); - disp(sprintf('use plotcmaesdat.m for plotting the output at any time (option LogModulo must not be zero)')); - end - if exist('sfile', 'var') - disp(['Results saved in ' sfile]); - end + if flgdisplay + disp(['#Fevals: f(returned x) | bestever.f | stopflag' ... + message]); + if isoctave + strstop = stopflag(:); + else + strcat(stopflag(:), '.'); end + strstop = stopflag(:); %strcat(stopflag(:), '.'); + disp([repmat(' ',1,6-floor(log10(counteval))) ... + num2str(counteval, '%6.0f') ': ' num2str(fmin, '%.11e') ' | ' ... + num2str(out.solutions.bestever.f, '%.11e') ' | ' ... + strstop{1:end}]); + if N < 102 + disp(['mean solution:' sprintf(' %+.1e', xmean)]); + disp(['std deviation:' sprintf(' %.1e', sigma*sqrt(diagC))]); + disp(sprintf('use plotcmaesdat.m for plotting the output at any time (option LogModulo must not be zero)')); + end + if exist('sfile', 'var') + disp(['Results saved in ' sfile]); + end + end - out.arstopflags{irun} = stopflag; - if any(strcmp(stopflag, 'fitness')) ... - || any(strcmp(stopflag, 'maxfunevals')) ... - || any(strcmp(stopflag, 'stoptoresume')) ... - || any(strcmp(stopflag, 'manual')) - break - end + out.arstopflags{irun} = stopflag; + if any(strcmp(stopflag, 'fitness')) ... + || any(strcmp(stopflag, 'maxfunevals')) ... + || any(strcmp(stopflag, 'stoptoresume')) ... + || any(strcmp(stopflag, 'manual')) + break + end end % while irun <= Restarts % --------------------------------------------------------------- diff --git a/matlab/optimization/dynare_minimize_objective.m b/matlab/optimization/dynare_minimize_objective.m index b0b25403b..13d1eae6e 100644 --- a/matlab/optimization/dynare_minimize_objective.m +++ b/matlab/optimization/dynare_minimize_objective.m @@ -91,13 +91,13 @@ switch minimizer_algorithm end if ~isoctave [opt_par_values,fval,exitflag,output,lamdba,grad,hessian_mat] = ... - fmincon(objective_function,start_par_value,[],[],[],[],bounds(:,1),bounds(:,2),[],optim_options,varargin{:}); + fmincon(objective_function,start_par_value,[],[],[],[],bounds(:,1),bounds(:,2),[],optim_options,varargin{:}); else % Under Octave, use a wrapper, since fmincon() does not have an 11th % arg. Also, only the first 4 output arguments are available. func = @(x) objective_function(x,varargin{:}); [opt_par_values,fval,exitflag,output] = ... - fmincon(func,start_par_value,[],[],[],[],bounds(:,1),bounds(:,2),[],optim_options); + fmincon(func,start_par_value,[],[],[],[],bounds(:,1),bounds(:,2),[],optim_options); end case 2 %simulating annealing @@ -418,7 +418,8 @@ switch minimizer_algorithm [opt_par_values, fval, exitflag] = simpsa(func2str(objective_function),start_par_value,LB,UB,simpsaOptions,varargin{:}); case 11 options_.cova_compute = 0; - [opt_par_values, stdh, lb_95, ub_95, med_param] = online_auxiliary_filter(start_par_value, varargin{:}); + subvarargin = [varargin(1), varargin(3:6), varargin(8)]; + [opt_par_values, stdh, lb_95, ub_95, med_param] = online_auxiliary_filter(start_par_value, subvarargin{:}); case 12 if isoctave error('Option mode_compute=12 is not available under Octave') diff --git a/matlab/optimization/gmhmaxlik_core.m b/matlab/optimization/gmhmaxlik_core.m index 3e94d30ab..bfa99441d 100644 --- a/matlab/optimization/gmhmaxlik_core.m +++ b/matlab/optimization/gmhmaxlik_core.m @@ -116,7 +116,7 @@ while j<=MaxNumberOfTuningSimulations ilogpo2 = logpo2; isux = isux + 1; jsux = jsux + 1; - end% ... otherwise I don't move. + end % ... otherwise I don't move. prtfrc = j/MaxNumberOfTuningSimulations; if mod(j, 10)==0 dyn_waitbar(prtfrc,hh,sprintf('Acceptance ratio [during last 500]: %f [%f]',isux/j,jsux/jj)); @@ -165,7 +165,7 @@ while j<= NumberOfIterations ilogpo2 = logpo2; isux = isux + 1; jsux = jsux + 1; - end% ... otherwise I don't move. + end % ... otherwise I don't move. prtfrc = j/NumberOfIterations; if mod(j, 10)==0 dyn_waitbar(prtfrc,hh,sprintf('Acceptance ratio: %f',isux/j)); @@ -209,7 +209,7 @@ if strcmpi(info,'LastCall') ilogpo2 = logpo2; isux = isux + 1; jsux = jsux + 1; - end% ... otherwise I don't move. + end % ... otherwise I don't move. prtfrc = j/MaxNumberOfTuningSimulations; if mod(j, 10)==0 dyn_waitbar(prtfrc,hh,sprintf('Acceptance ratio [during last 1000]: %f [%f]',isux/j,jsux/jj)); @@ -251,7 +251,7 @@ if strcmpi(info,'LastCall') ModePar = proposal; mlogpo2 = logpo2; jsux = jsux + 1; - end% otherwise I don't move... + end % otherwise I don't move... prtfrc = j/MaxNumberOfClimbingSimulations; if mod(j, 10)==0 dyn_waitbar(prtfrc,hh,sprintf('%f Jumps / MaxStepSize %f',jsux,sqrt(max(diag(iScale*CovJump))))); @@ -276,7 +276,7 @@ if strcmpi(info,'LastCall') jj = jj + 1; end dyn_waitbar_close(hh); - end%climb + end %climb else Scale = iScale; end diff --git a/matlab/optimization/simplex_optimization_routine.m b/matlab/optimization/simplex_optimization_routine.m index af11953f6..9626bf461 100644 --- a/matlab/optimization/simplex_optimization_routine.m +++ b/matlab/optimization/simplex_optimization_routine.m @@ -491,7 +491,7 @@ while (func_count < max_func_calls) && (iter_count < max_iterations) && (simplex break end end -end% while loop. +end % while loop. x(:) = v(:,1); fval = fv(1); diff --git a/matlab/optimization/simpsa.m b/matlab/optimization/simpsa.m index 760298a13..baf07c1d9 100644 --- a/matlab/optimization/simpsa.m +++ b/matlab/optimization/simpsa.m @@ -317,7 +317,7 @@ while 1 OUTPUT.COSTS(nITERATIONS,:) = Y; OUTPUT.COST_BEST(nITERATIONS) = YBEST; end - + if strcmp(OPTIONS.DISPLAY,'iter') disp(sprintf('%5.0f %5.0f %12.6g %15.6g %12.6g %s',nITERATIONS,nFUN_EVALS,Y(1),YBEST,TEMP,ALGOSTEP)); end @@ -458,17 +458,17 @@ FVAL = YBEST; if nargout>3 % store number of function evaluations OUTPUT.nFUN_EVALS = nFUN_EVALS; - + % store number of iterations OUTPUT.nITERATIONS = nITERATIONS; - + % trim OUTPUT data structure OUTPUT.TEMPERATURE(nITERATIONS+1:end) = []; OUTPUT.SIMPLEX(:,:,nITERATIONS+1:end) = []; OUTPUT.SIMPLEX_BEST(nITERATIONS+1:end,:) = []; OUTPUT.COSTS(nITERATIONS+1:end,:) = []; OUTPUT.COST_BEST(nITERATIONS+1:end) = []; - + % store the amount of time needed in OUTPUT data structure OUTPUT.TIME = toc; end diff --git a/matlab/optimization/solvopt.m b/matlab/optimization/solvopt.m index c4a819a26..04bf44db1 100644 --- a/matlab/optimization/solvopt.m +++ b/matlab/optimization/solvopt.m @@ -1240,4 +1240,4 @@ while 1 end % restart % end of the function % - end \ No newline at end of file +end \ No newline at end of file diff --git a/matlab/osr.m b/matlab/osr.m index 25db19bdd..3a0d463f2 100644 --- a/matlab/osr.m +++ b/matlab/osr.m @@ -62,4 +62,4 @@ if ~options_.noprint end osr_res = osr1(i_params,i_var,W); -[~, oo_, options_] = stoch_simul(M_, options_, oo_, var_list); +[~, oo_, options_, M_] = stoch_simul(M_, options_, oo_, var_list); diff --git a/matlab/osr1.m b/matlab/osr1.m index 8300daa9a..673f69bdc 100644 --- a/matlab/osr1.m +++ b/matlab/osr1.m @@ -124,7 +124,7 @@ else end %%do actual optimization [p, f] = dynare_minimize_objective(str2func('osr_obj'),t0,options_.osr.opt_algo,options_,M_.osr.param_bounds,M_.param_names(i_params),[],[], i_params,... - inv_order_var(i_var),weights(i_var,i_var)); + inv_order_var(i_var),weights(i_var,i_var)); end osr_res.objective_function = f; diff --git a/matlab/parallel/AnalyseComputationalEnvironment.m b/matlab/parallel/AnalyseComputationalEnvironment.m index d03a9d16a..08bf0d2ed 100644 --- a/matlab/parallel/AnalyseComputationalEnvironment.m +++ b/matlab/parallel/AnalyseComputationalEnvironment.m @@ -558,7 +558,7 @@ for Node=1:length(DataInput) % To obtain a recoursive function remove the 'for' disp('The command causing the error was:') disp(command_string) disp('The system returned:') - disp(de0) + disp(de0) skipline(2) end diff --git a/matlab/parallel/dynareParallelDelete.m b/matlab/parallel/dynareParallelDelete.m index 478b8c8e4..abbfd05d3 100644 --- a/matlab/parallel/dynareParallelDelete.m +++ b/matlab/parallel/dynareParallelDelete.m @@ -11,7 +11,7 @@ function dynareParallelDelete(fname,pname,Parallel) % None % % -% Copyright (C) 2009-2017 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -28,25 +28,31 @@ function dynareParallelDelete(fname,pname,Parallel) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -if nargin ==0 - disp('dynareParallelDelete(fname)') +if nargin ~= 3 + disp('dynareParallelDelete(fname,pname,Parallel)') return end -if nargin ==1 - pname=''; -else +if ~isempty(pname) pname=[pname,filesep]; end for indPC=1:length(Parallel) if ~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem) if ~isempty(Parallel(indPC).Port) - ssh_token = ['-p ',Parallel(indPC).Port]; + ssh_token = ['-p ',Parallel(indPC).Port ' ']; else - ssh_token = ''; + ssh_token = ' '; end - [NonServeS NonServeD]=system(['ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' rm -f ',Parallel(indPC).RemoteDirectory,'/',pname,fname]); + username = Parallel(indPC).UserName; + if ~isempty(username) + username = [username '@']; + end + directory = Parallel(indPC).RemoteDirectory; + if ~isempty(directory) + directory = [directory '/']; + end + [~, ~] = system(['ssh ',ssh_token,username,Parallel(indPC).ComputerName,' ''/bin/bash --norc -c "rm -f ',directory,pname,fname,'"''']); else fname_temp=['\\',Parallel(indPC).ComputerName,'\',Parallel(indPC).RemoteDrive,'$\',Parallel(indPC).RemoteDirectory,'\',pname,fname]; if exist(fname_temp,'file') diff --git a/matlab/parallel/masterParallel.m b/matlab/parallel/masterParallel.m index 4fbe69a8c..1c102ecf4 100644 --- a/matlab/parallel/masterParallel.m +++ b/matlab/parallel/masterParallel.m @@ -107,332 +107,264 @@ if nargin>8 && initialize==1 return end -if isfield(Parallel_info,'local_files') - if isempty(NamFileInput) - NamFileInput=Parallel_info.local_files; - else - NamFileInput=[NamFileInput;Parallel_info.local_files]; - end -end - -% Deactivate some 'Parallel/Warning' messages in Octave! -% Comment the line 'warning('off');' in order to view the warning messages -% in Octave! - -if isoctave - warning('off') -end - -% check if there are function_handles in the input or global vars when -% octave is used -if isHybridMatlabOctave || isoctave - fInputNames = fieldnames(fInputVar); - for j=1:length(fInputNames) - TargetVar = fInputVar.(fInputNames{j}); - if isa(TargetVar,'function_handle') - TargetVar=func2str(TargetVar); - fInputVar.(fInputNames{j})=TargetVar; - end - end - - if exist('fGlobalVar','var') && ~isempty(fGlobalVar) - fInputNames = fieldnames(fGlobalVar); - for j=1:length(fInputNames) - TargetVar = fGlobalVar.(fInputNames{j}); - if isa(TargetVar,'function_handle') - TargetVar=func2str(TargetVar); - fGlobalVar.(fInputNames{j})=TargetVar; - end - end - end -end - -if Strategy==1 - totCPU=0; -end - - -% Determine my hostname and my working directory. - -DyMo=pwd; -% fInputVar.DyMo=DyMo; -if ispc - [tempo, MasterName]=system('hostname'); - MasterName=deblank(MasterName); -end -% fInputVar.MasterName = MasterName; - - -% Save input data for use by the slaves. -switch Strategy - case 0 - storeGlobalVars([fname,'_input.mat']); - save([fname,'_input.mat'],'fInputVar','Parallel','-append') - - case 1 - if exist('fGlobalVar','var') - save(['temp_input.mat'],'fInputVar','fGlobalVar') - else - save(['temp_input.mat'],'fInputVar') - end - save(['temp_input.mat'],'Parallel','-append') - closeSlave(Parallel,PRCDir,-1); -end - - % Determine the total number of available CPUs, and the number of threads % to run on each CPU. [nCPU, totCPU, nBlockPerCPU, totSlaves] = distributeJobs(Parallel, fBlock, nBlock); -for j=1:totSlaves - PRCDirSnapshot{j}={}; -end -offset0 = fBlock-1; -% Clean up remnants of previous runs. -mydelete(['comp_status_',fname,'*.mat']); -mydelete(['P_',fname,'*End.txt']); -mydelete([fname,'_output_*.mat']); -mydelete('slaveParallel_break.mat'); +parallel_recover = 0; -dynareParallelDelete([fname,'_output_*.mat'],PRCDir,Parallel); -dynareParallelDelete(['comp_status_',fname,'*.mat'],PRCDir,Parallel); -dynareParallelDelete('slaveParallel_break.mat',PRCDir,Parallel); - - -% Create a shell script containing the commands to launch the required -% tasks on the slaves. -fid = fopen('ConcurrentCommand1.bat','w+'); - - -% Create the directory devoted to remote computation. -if isempty(PRCDir) && ~islocal - error('PRCDir not initialized!') -else - dynareParallelMkDir(PRCDir,Parallel(1:totSlaves)); +if isfield(Parallel_info,'parallel_recover') && Parallel_info.parallel_recover + parallel_recover = 1; end -% Testing Zone - -% 1. Display the User Strategy: - -% if Strategy==0 -% disp('User Strategy Now Is Open/Close (0)'); -% else -% disp('User Strategy Now Is Always Open (1)'); -% end - - -% 2. Display the output of 'NEW' distributeJobs.m: -% -% fBlock -% nBlock -% -% -% nCPU -% totCPU -% nBlockPerCPU -% totSlaves -% -% keyboard - -% End - -for j=1:totCPU - - if Strategy==1 - command1 = ' '; - end - - indPC=min(find(nCPU>=j)); - - % According to the information contained in configuration file, compThread can limit MATLAB - % to a single computational thread. By default, MATLAB makes use of the multithreading - % capabilities of the computer on which it is running. Nevertheless - % exsperimental results show as matlab native - % multithreading limit the performaces when the parallel computing is active. - - - if strcmp('true',Parallel(indPC).SingleCompThread) - compThread = '-singleCompThread'; - else - compThread = ''; - end - - nthreads=Parallel(indPC).NumberOfThreadsPerJob; - if indPC>1 - nCPU0 = nCPU(indPC-1); - else - nCPU0=0; - end - offset = sum(nBlockPerCPU(1:j-1))+offset0; - - % Create a file used to monitoring if a parallel block (core) - % computation is finished or not. - - fid1=fopen(['P_',fname,'_',int2str(j),'End.txt'],'w+'); - fclose(fid1); - - if Strategy==1 - - fblck = offset+1; - nblck = sum(nBlockPerCPU(1:j)); - save temp_input.mat fblck nblck fname -append; - copyfile('temp_input.mat',['slaveJob',int2str(j),'.mat']); - if Parallel(indPC).Local ==0 - fid1=fopen(['stayalive',int2str(j),'.txt'],'w+'); - fclose(fid1); - dynareParallelSendFiles(['stayalive',int2str(j),'.txt'],PRCDir,Parallel(indPC)); - mydelete(['stayalive',int2str(j),'.txt']); +if parallel_recover ==0 + if isfield(Parallel_info,'local_files') + if isempty(NamFileInput) + NamFileInput=Parallel_info.local_files; + else + NamFileInput=[NamFileInput;Parallel_info.local_files]; end - % Wait for possibly local alive CPU to start the new job or close by - % internal criteria. - pause(1); - newInstance = 0; + end - % Check if j CPU is already alive. - if isempty(dynareParallelDir(['P_slave_',int2str(j),'End.txt'],PRCDir,Parallel(indPC))) - fid1=fopen(['P_slave_',int2str(j),'End.txt'],'w+'); - fclose(fid1); - if Parallel(indPC).Local==0 - dynareParallelSendFiles(['P_slave_',int2str(j),'End.txt'],PRCDir,Parallel(indPC)); - delete(['P_slave_',int2str(j),'End.txt']); + % Deactivate some 'Parallel/Warning' messages in Octave! + % Comment the line 'warning('off');' in order to view the warning messages + % in Octave! + + if isoctave + warning('off') + end + + % check if there are function_handles in the input or global vars when + % octave is used + if isHybridMatlabOctave || isoctave + fInputNames = fieldnames(fInputVar); + for j=1:length(fInputNames) + TargetVar = fInputVar.(fInputNames{j}); + if isa(TargetVar,'function_handle') + TargetVar=func2str(TargetVar); + fInputVar.(fInputNames{j})=TargetVar; end - - newInstance = 1; - storeGlobalVars( ['slaveParallel_input',int2str(j),'.mat']); - save( ['slaveParallel_input',int2str(j),'.mat'],'Parallel','-append'); - % Prepare global vars for Slave. - end - else - - % If the computation is executed remotely all the necessary files - % are created localy, then copied in remote directory and then - % deleted (loacal)! - - save( ['slaveParallel_input',int2str(j),'.mat'],'j'); - - if Parallel(indPC).Local==0 - dynareParallelSendFiles(['P_',fname,'_',int2str(j),'End.txt'],PRCDir,Parallel(indPC)); - delete(['P_',fname,'_',int2str(j),'End.txt']); - - dynareParallelSendFiles(['slaveParallel_input',int2str(j),'.mat'],PRCDir,Parallel(indPC)); - delete(['slaveParallel_input',int2str(j),'.mat']); - end + if exist('fGlobalVar','var') && ~isempty(fGlobalVar) + fInputNames = fieldnames(fGlobalVar); + for j=1:length(fInputNames) + TargetVar = fGlobalVar.(fInputNames{j}); + if isa(TargetVar,'function_handle') + TargetVar=func2str(TargetVar); + fGlobalVar.(fInputNames{j})=TargetVar; + end + end + end end - % set affinity range on win CPU's - affinity_range = [1:nthreads]+(j-1-nCPU0)*nthreads; - my_affinity = int2str(Parallel(indPC).CPUnbr(affinity_range(1))); - for jaff=2:length(affinity_range) - my_affinity = [my_affinity ',' int2str(Parallel(indPC).CPUnbr(affinity_range(jaff)))]; - end - % % % int2str(Parallel(indPC).CPUnbr(j-nCPU0)) - % DA SINTETIZZARE: + % if Strategy==1 + % totCPU=0; + % end - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The following 'switch - case' code is the core of this function! + + % Determine my hostname and my working directory. + + DyMo=pwd; + % fInputVar.DyMo=DyMo; + if ispc + [tempo, MasterName]=system('hostname'); + MasterName=deblank(MasterName); + end + % fInputVar.MasterName = MasterName; + + + % Save input data for use by the slaves. switch Strategy case 0 - - if Parallel(indPC).Local == 1 % 0.1 Run on the local machine (localhost). - - if ~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem) % Hybrid computing Windows <-> Unix! - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! - command1=[Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')" &']; - else - command1=[Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')" &']; - end - else % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') - command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; - else - command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; - end - end - else % 0.2 Parallel(indPC).Local==0: Run using network on remote machine or also on local machine. - if j==nCPU0+1 - dynareParallelSendFiles([fname,'_input.mat'],PRCDir,Parallel(indPC)); - dynareParallelSendFiles(NamFileInput,PRCDir,Parallel(indPC)); - end - - if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) % Hybrid computing Windows <-> Unix! - if ispc - token='start /B '; - else - token = ''; - end - if ~isempty(Parallel(indPC).Port) - ssh_token = ['-p ',Parallel(indPC).Port]; - else - ssh_token = ''; - end - % To manage the diferences in Unix/Windows OS syntax. - remoteFile=['remoteDynare',int2str(j)]; - fidRemote=fopen([remoteFile,'.m'],'w+'); - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! - remoteString=['default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')']; - command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir, '; ',Parallel(indPC).MatlabOctavePath,' -f --eval ',remoteFile,' " &']; - else - remoteString=['addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')']; - command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir, '; ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r ',remoteFile,';" &']; - end - fprintf(fidRemote,'%s\n',remoteString); - fclose(fidRemote); - dynareParallelSendFiles([remoteFile,'.m'],PRCDir,Parallel(indPC)); - delete([remoteFile,'.m']); - else - if ~strcmpi(Parallel(indPC).ComputerName,MasterName) % 0.3 Run on a remote machine! - % Hybrid computing Matlab(Master)-> Octave(Slaves) and Vice Versa! - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') - command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -u ',Parallel(indPC).UserName,' -p ',Parallel(indPC).Password,' -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; - else - - command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -u ',Parallel(indPC).UserName,' -p ',Parallel(indPC).Password,' -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; - end - else % 0.4 Run on the local machine via the network - % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') - command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; - else - command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; - end - end - end - end - + storeGlobalVars([fname,'_input.mat']); + save([fname,'_input.mat'],'fInputVar','Parallel','-append') case 1 - if Parallel(indPC).Local == 1 && newInstance % 1.1 Run on the local machine. - if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) % Hybrid computing Windows <-> Unix! - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)-> Octave(Slaves) and Vice Versa! - command1=[Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')" &']; - else - command1=[Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')" &']; - end - else % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') - command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7'');addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; - else - command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; - end + if exist('fGlobalVar','var') + save(['temp_input.mat'],'fInputVar','fGlobalVar') + else + save(['temp_input.mat'],'fInputVar') + end + save(['temp_input.mat'],'Parallel','-append') + closeSlave(Parallel,PRCDir,-1); + end + + for j=1:totSlaves + PRCDirSnapshot{j}={}; + end + offset0 = fBlock-1; + + % Clean up remnants of previous runs. + mydelete(['comp_status_',fname,'*.mat']); + mydelete(['P_',fname,'*End.txt']); + mydelete([fname,'_output_*.mat']); + mydelete('slaveParallel_break.mat'); + + dynareParallelDelete([fname,'_output_*.mat'],PRCDir,Parallel); + dynareParallelDelete(['comp_status_',fname,'*.mat'],PRCDir,Parallel); + dynareParallelDelete('slaveParallel_break.mat',PRCDir,Parallel); + + + % Create a shell script containing the commands to launch the required + % tasks on the slaves. + fid = fopen('ConcurrentCommand1.bat','w+'); + + + % Create the directory devoted to remote computation. + if isempty(PRCDir) && ~islocal + error('PRCDir not initialized!') + else + dynareParallelMkDir(PRCDir,Parallel(1:totSlaves)); + end + + % Testing Zone + + % 1. Display the User Strategy: + + % if Strategy==0 + % disp('User Strategy Now Is Open/Close (0)'); + % else + % disp('User Strategy Now Is Always Open (1)'); + % end + + + % 2. Display the output of 'NEW' distributeJobs.m: + % + % fBlock + % nBlock + % + % + % nCPU + % totCPU + % nBlockPerCPU + % totSlaves + % + % keyboard + + % End + + for j=1:totCPU + + if Strategy==1 + command1 = ' '; + end + + indPC=min(find(nCPU>=j)); + + % According to the information contained in configuration file, compThread can limit MATLAB + % to a single computational thread. By default, MATLAB makes use of the multithreading + % capabilities of the computer on which it is running. Nevertheless + % exsperimental results show as matlab native + % multithreading limit the performaces when the parallel computing is active. + + + if strcmp('true',Parallel(indPC).SingleCompThread) + compThread = '-singleCompThread'; + else + compThread = ''; + end + + nthreads=Parallel(indPC).NumberOfThreadsPerJob; + if indPC>1 + nCPU0 = nCPU(indPC-1); + else + nCPU0=0; + end + offset = sum(nBlockPerCPU(1:j-1))+offset0; + + % Create a file used to monitoring if a parallel block (core) + % computation is finished or not. + + fid1=fopen(['P_',fname,'_',int2str(j),'End.txt'],'w+'); + fclose(fid1); + + if Strategy==1 + + fblck = offset+1; + nblck = sum(nBlockPerCPU(1:j)); + save temp_input.mat fblck nblck fname -append; + copyfile('temp_input.mat',['slaveJob',int2str(j),'.mat']); + if Parallel(indPC).Local ==0 + fid1=fopen(['stayalive',int2str(j),'.txt'],'w+'); + fclose(fid1); + dynareParallelSendFiles(['stayalive',int2str(j),'.txt'],PRCDir,Parallel(indPC)); + mydelete(['stayalive',int2str(j),'.txt']); end - elseif Parallel(indPC).Local==0 % 1.2 Run using network on remote machine or also on local machine. - if j==nCPU0+1 - dynareParallelSendFiles(NamFileInput,PRCDir,Parallel(indPC)); + % Wait for possibly local alive CPU to start the new job or close by + % internal criteria. + pause(1); + newInstance = 0; + + % Check if j CPU is already alive. + if isempty(dynareParallelDir(['P_slave_',int2str(j),'End.txt'],PRCDir,Parallel(indPC))) + fid1=fopen(['P_slave_',int2str(j),'End.txt'],'w+'); + fclose(fid1); + if Parallel(indPC).Local==0 + dynareParallelSendFiles(['P_slave_',int2str(j),'End.txt'],PRCDir,Parallel(indPC)); + delete(['P_slave_',int2str(j),'End.txt']); + end + + newInstance = 1; + storeGlobalVars( ['slaveParallel_input',int2str(j),'.mat']); + save( ['slaveParallel_input',int2str(j),'.mat'],'Parallel','-append'); + % Prepare global vars for Slave. end - dynareParallelSendFiles(['P_',fname,'_',int2str(j),'End.txt'],PRCDir,Parallel(indPC)); - delete(['P_',fname,'_',int2str(j),'End.txt']); - if newInstance - dynareParallelSendFiles(['slaveJob',int2str(j),'.mat'],PRCDir,Parallel(indPC)); - delete(['slaveJob',int2str(j),'.mat']); - dynareParallelSendFiles(['slaveParallel_input',int2str(j),'.mat'],PRCDir,Parallel(indPC)) + else + + % If the computation is executed remotely all the necessary files + % are created localy, then copied in remote directory and then + % deleted (loacal)! + + save( ['slaveParallel_input',int2str(j),'.mat'],'j'); + + if Parallel(indPC).Local==0 + dynareParallelSendFiles(['P_',fname,'_',int2str(j),'End.txt'],PRCDir,Parallel(indPC)); + delete(['P_',fname,'_',int2str(j),'End.txt']); + + dynareParallelSendFiles(['slaveParallel_input',int2str(j),'.mat'],PRCDir,Parallel(indPC)); + delete(['slaveParallel_input',int2str(j),'.mat']); + + end + + end + + % set affinity range on win CPU's + affinity_range = [1:nthreads]+(j-1-nCPU0)*nthreads; + my_affinity = int2str(Parallel(indPC).CPUnbr(affinity_range(1))); + for jaff=2:length(affinity_range) + my_affinity = [my_affinity ',' int2str(Parallel(indPC).CPUnbr(affinity_range(jaff)))]; + end + % % % int2str(Parallel(indPC).CPUnbr(j-nCPU0)) + % DA SINTETIZZARE: + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % The following 'switch - case' code is the core of this function! + switch Strategy + case 0 + + if Parallel(indPC).Local == 1 % 0.1 Run on the local machine (localhost). + + if ~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem) % Hybrid computing Windows <-> Unix! + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + command1=[Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')" &']; + else + command1=[Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')" &']; + end + else % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') + command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; + else + command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; + end + end + else % 0.2 Parallel(indPC).Local==0: Run using network on remote machine or also on local machine. + if j==nCPU0+1 + dynareParallelSendFiles([fname,'_input.mat'],PRCDir,Parallel(indPC)); + dynareParallelSendFiles(NamFileInput,PRCDir,Parallel(indPC)); + end + if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) % Hybrid computing Windows <-> Unix! if ispc token='start /B '; @@ -447,329 +379,409 @@ for j=1:totCPU % To manage the diferences in Unix/Windows OS syntax. remoteFile=['remoteDynare',int2str(j)]; fidRemote=fopen([remoteFile,'.m'],'w+'); - if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)-> Octave(Slaves) and Vice Versa! - remoteString=['default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),');']; - command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir '; ',Parallel(indPC).MatlabOctavePath,' -f --eval ',remoteFile,' " &']; + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + remoteString=['default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')']; + command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir, '; ',Parallel(indPC).MatlabOctavePath,' -f --eval ',remoteFile,' " &']; else - remoteString=['addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),');']; - command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir '; ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r ',remoteFile,';" &']; + remoteString=['addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')']; + command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir, '; ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r ',remoteFile,';" &']; end fprintf(fidRemote,'%s\n',remoteString); fclose(fidRemote); dynareParallelSendFiles([remoteFile,'.m'],PRCDir,Parallel(indPC)); delete([remoteFile,'.m']); else - if ~strcmpi(Parallel(indPC).ComputerName,MasterName) % 1.3 Run on a remote machine. - % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + if ~strcmpi(Parallel(indPC).ComputerName,MasterName) % 0.3 Run on a remote machine! + % Hybrid computing Matlab(Master)-> Octave(Slaves) and Vice Versa! if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -u ',Parallel(indPC).UserName,' -p ',Parallel(indPC).Password,' -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7'');addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; else + command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -u ',Parallel(indPC).UserName,' -p ',Parallel(indPC).Password,' -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; end - else % 1.4 Run on the local machine via the network. - % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + else % 0.4 Run on the local machine via the network + % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; else command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... - ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); fParallel(',int2str(offset+1),',',int2str(sum(nBlockPerCPU(1:j))),',',int2str(j),',',int2str(indPC),',''',fname,''')"']; end end end - else - % When the user user strategy is equal to 1, you must - % do PRCDirSnapshot here to to avoid problems of - % synchronization. - - if isempty(PRCDirSnapshot{indPC}) - PRCDirSnapshot(indPC)=dynareParallelSnapshot(PRCDir,Parallel(indPC)); - PRCDirSnapshotInit(indPC) = PRCDirSnapshot(indPC); - else - PRCDirSnapshot(indPC)=dynareParallelGetNewFiles(PRCDir,Parallel(indPC),PRCDirSnapshot(indPC)); - end - dynareParallelSendFiles(['slaveJob',int2str(j),'.mat'],PRCDir,Parallel(indPC)); - delete(['slaveJob',int2str(j),'.mat']); - end + + + case 1 + if Parallel(indPC).Local == 1 && newInstance % 1.1 Run on the local machine. + if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) % Hybrid computing Windows <-> Unix! + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)-> Octave(Slaves) and Vice Versa! + command1=[Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')" &']; + else + command1=[Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')" &']; + end + else % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') + command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7'');addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + else + command1=['psexec -accepteula -d -W "',DyMo, '" -a ',my_affinity,' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + end + end + elseif Parallel(indPC).Local==0 % 1.2 Run using network on remote machine or also on local machine. + if j==nCPU0+1 + dynareParallelSendFiles(NamFileInput,PRCDir,Parallel(indPC)); + end + dynareParallelSendFiles(['P_',fname,'_',int2str(j),'End.txt'],PRCDir,Parallel(indPC)); + delete(['P_',fname,'_',int2str(j),'End.txt']); + if newInstance + dynareParallelSendFiles(['slaveJob',int2str(j),'.mat'],PRCDir,Parallel(indPC)); + delete(['slaveJob',int2str(j),'.mat']); + dynareParallelSendFiles(['slaveParallel_input',int2str(j),'.mat'],PRCDir,Parallel(indPC)) + if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) % Hybrid computing Windows <-> Unix! + if ispc + token='start /B '; + else + token = ''; + end + if ~isempty(Parallel(indPC).Port) + ssh_token = ['-p ',Parallel(indPC).Port]; + else + ssh_token = ''; + end + % To manage the diferences in Unix/Windows OS syntax. + remoteFile=['remoteDynare',int2str(j)]; + fidRemote=fopen([remoteFile,'.m'],'w+'); + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') % Hybrid computing Matlab(Master)-> Octave(Slaves) and Vice Versa! + remoteString=['default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),');']; + command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir '; ',Parallel(indPC).MatlabOctavePath,' -f --eval ',remoteFile,' " &']; + else + remoteString=['addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),');']; + command1=[token, 'ssh ',ssh_token,' ',Parallel(indPC).UserName,'@',Parallel(indPC).ComputerName,' "cd ',Parallel(indPC).RemoteDirectory,'/',PRCDir '; ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r ',remoteFile,';" &']; + end + fprintf(fidRemote,'%s\n',remoteString); + fclose(fidRemote); + dynareParallelSendFiles([remoteFile,'.m'],PRCDir,Parallel(indPC)); + delete([remoteFile,'.m']); + else + if ~strcmpi(Parallel(indPC).ComputerName,MasterName) % 1.3 Run on a remote machine. + % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') + command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -u ',Parallel(indPC).UserName,' -p ',Parallel(indPC).Password,' -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... + ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7'');addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + else + command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -u ',Parallel(indPC).UserName,' -p ',Parallel(indPC).Password,' -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... + ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + end + else % 1.4 Run on the local machine via the network. + % Hybrid computing Matlab(Master)->Octave(Slaves) and Vice Versa! + if regexpi([Parallel(indPC).MatlabOctavePath], 'octave') + command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... + ' -low ',Parallel(indPC).MatlabOctavePath,' -f --eval "default_save_options(''-v7''); addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + else + command1=['psexec \\',Parallel(indPC).ComputerName,' -accepteula -d -e -W "',Parallel(indPC).RemoteDrive,':\',Parallel(indPC).RemoteDirectory,'\',PRCDir,'\" -a ',my_affinity, ... + ' -low ',Parallel(indPC).MatlabOctavePath,' -nosplash -nodesktop -minimize ',compThread,' -r "addpath(''',Parallel(indPC).DynarePath,'''), dynareroot = dynare_config(); slaveParallel(',int2str(j),',',int2str(indPC),')"']; + end + end + end + else + % When the user user strategy is equal to 1, you must + % do PRCDirSnapshot here to to avoid problems of + % synchronization. + + if isempty(PRCDirSnapshot{indPC}) + PRCDirSnapshot(indPC)=dynareParallelSnapshot(PRCDir,Parallel(indPC)); + PRCDirSnapshotInit(indPC) = PRCDirSnapshot(indPC); + else + PRCDirSnapshot(indPC)=dynareParallelGetNewFiles(PRCDir,Parallel(indPC),PRCDirSnapshot(indPC)); + end + dynareParallelSendFiles(['slaveJob',int2str(j),'.mat'],PRCDir,Parallel(indPC)); + delete(['slaveJob',int2str(j),'.mat']); + + end + end + end + fprintf(fid,'%s\n',command1); + end - fprintf(fid,'%s\n',command1); - -end - -% In This way we are sure that the file 'ConcurrentCommand1.bat' is -% closed and then it can be deleted! -while (1) - StatusOfCC1_bat = fclose(fid); - if StatusOfCC1_bat==0 - break + % In This way we are sure that the file 'ConcurrentCommand1.bat' is + % closed and then it can be deleted! + while (1) + StatusOfCC1_bat = fclose(fid); + if StatusOfCC1_bat==0 + break + end end -end -% Snapshot of the contents of all the directories involved in parallel -% computing. This is necessary when I want to copy continuously the files produced by -% the slaves ... -% If the compuation is 'Local' it is not necessary to do it ... + % Snapshot of the contents of all the directories involved in parallel + % computing. This is necessary when I want to copy continuously the files produced by + % the slaves ... + % If the compuation is 'Local' it is not necessary to do it ... -if Strategy==0 || newInstance % See above. - PRCDirSnapshot=dynareParallelSnapshot(PRCDir,Parallel(1:totSlaves)); - PRCDirSnapshotInit = PRCDirSnapshot; + if Strategy==0 || newInstance % See above. + PRCDirSnapshot=dynareParallelSnapshot(PRCDir,Parallel(1:totSlaves)); + PRCDirSnapshotInit = PRCDirSnapshot; - % Run the slaves. - if ~ispc - system('sh ConcurrentCommand1.bat &'); - pause(1) - else - - if isoctave - % Redirect the standard output to the file 'OctaveStandardOutputMessage.txt'! - % This file is saved in the Model directory. - system('ConcurrentCommand1.bat > OctaveStandardOutputMessage.txt'); + % Run the slaves. + if ~ispc + system('sh ConcurrentCommand1.bat &'); + pause(1) else - system('ConcurrentCommand1.bat'); - end - end -end - -% For matlab enviroment with options_.console_mode = 0: -% create a parallel (local/remote) specialized computational status bars! - -global options_ - - -% Create a parallel (local/remote) specialized computational status bars! - -if isoctave || options_.console_mode - diary off; - if isoctave - printf('\n'); - else - fprintf('\n'); - end -else - hfigstatus = figure('name',['Parallel ',fname],... - 'DockControls','off', ... - 'IntegerHandle','off', ... - 'Interruptible','off', ... - 'MenuBar', 'none', ... - 'NumberTitle','off', ... - 'Renderer','Painters', ... - 'Resize','off'); - - ncol = ceil(totCPU/10); - hspace = 0.9/ncol; - hstatus(1) = axes('position',[0.05/ncol 0.92 0.9/ncol 0.03], ... - 'box','on','xtick',[],'ytick',[],'xlim',[0 1],'ylim',[0 1]); - set(hstatus(1),'Units','pixels') - hpixel = get(hstatus(1),'Position'); - hfigure = get(hfigstatus,'Position'); - hfigure(4)=hpixel(4)*10/3*min(10,totCPU); - set(hfigstatus,'Position',hfigure) - set(hstatus(1),'Units','normalized'), - vspace = max(0.1,1/totCPU); - vstart = 1-vspace+0.2*vspace; - for j=1:totCPU - jrow = mod(j-1,10)+1; - jcol = ceil(j/10); - hstatus(j) = axes('position',[0.05/ncol+(jcol-1)/ncol vstart-vspace*(jrow-1) 0.9/ncol 0.3*vspace], ... - 'box','on','xtick',[],'ytick',[],'xlim',[0 1],'ylim',[0 1]); - hpat(j) = patch([0 0 0 0],[0 1 1 0],'r','EdgeColor','r'); - htit(j) = title(['Initialize ...']); - - end - - cumBlockPerCPU = cumsum(nBlockPerCPU); -end -pcerdone = NaN(1,totCPU); -idCPU = NaN(1,totCPU); - - - -% Wait for the slaves to finish their job, and display some progress -% information meanwhile. - -% Caption for console mode computing ... - -if options_.console_mode || isoctave - - if ~isoctave - if strcmpi([Parallel(indPC).MatlabOctavePath], 'octave') - RjInformation='Hybrid Computing Is Active: Remote jobs are computed by Octave!'; - fprintf([RjInformation,'\n\n']); - end - end - - fnameTemp=fname; - - L=length(fnameTemp); - - PoCo=strfind(fnameTemp,'_core'); - - for i=PoCo:L - if i==PoCo - fnameTemp(i)=' '; - else - fnameTemp(i)='.'; - end - end - - for i=1:L - if fnameTemp(i)=='_' - fnameTemp(i)=' '; - end - end - - fnameTemp(L)=''; - - Information=['Parallel ' fnameTemp ' Computing ...']; - if isoctave - if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) && (Strategy==0) - printf('\n'); - pause(2); - end - - printf([Information,'\n\n']); - else - fprintf([Information,'\n\n']); - end - -end - - -% Testing Zone - -% Check the new copy file strategy ... -global NuoviFilecopiati -NuoviFilecopiati=zeros(1,totSlaves); -% End - -ForEver=1; -statusString = ''; -flag_CloseAllSlaves=0; - -while (ForEver) - - waitbarString = ''; - statusString0 = repmat('\b',1,length(sprintf(statusString, 100 .* pcerdone))); - statusString = ''; - - pause(1) - - try - if islocal ==0 - dynareParallelGetFiles(['comp_status_',fname,'*.mat'],PRCDir,Parallel(1:totSlaves)); - end - catch - end - - for j=1:totCPU - try - if ~isempty(['comp_status_',fname,int2str(j),'.mat']) - load(['comp_status_',fname,int2str(j),'.mat']); - % whoCloseAllSlaves = who(['comp_status_',fname,int2str(j),'.mat','CloseAllSlaves']); - if exist('CloseAllSlaves') && flag_CloseAllSlaves==0 - flag_CloseAllSlaves=1; - whoiamCloseAllSlaves=j; - closeSlave(Parallel(1:totSlaves),PRCDir,1); - end - end - pcerdone(j) = prtfrc; - idCPU(j) = njob; - if isoctave || options_.console_mode - if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) - statusString = [statusString, int2str(j), ' %3.f%% done! ']; - else - statusString = [statusString, int2str(j), ' %3.f%% done! ']; - end + if isoctave + % Redirect the standard output to the file 'OctaveStandardOutputMessage.txt'! + % This file is saved in the Model directory. + system('ConcurrentCommand1.bat > OctaveStandardOutputMessage.txt'); else - status_String{j} = waitbarString; - status_Title{j} = waitbarTitle; - end - catch % ME - % To define! - if isoctave || options_.console_mode - if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) - statusString = [statusString, int2str(j), ' %3.f%% done! ']; - else - statusString = [statusString, int2str(j), ' %3.f%% done! ']; - end + system('ConcurrentCommand1.bat'); end end end + + + % For matlab enviroment with options_.console_mode = 0: + % create a parallel (local/remote) specialized computational status bars! + + global options_ + + + % Create a parallel (local/remote) specialized computational status bars! + if isoctave || options_.console_mode + diary off; if isoctave - printf([statusString,'\r'], 100 .* pcerdone); + printf('\n'); else - if ~isempty(statusString) - fprintf([statusString0,statusString], 100 .* pcerdone); - end + fprintf('\n'); end else - for j=1:totCPU - try - set(hpat(j),'XData',[0 0 pcerdone(j) pcerdone(j)]); - set(htit(j),'String',[status_Title{j},' - ',status_String{j}]); - catch + hfigstatus = figure('name',['Parallel ',fname],... + 'DockControls','off', ... + 'IntegerHandle','off', ... + 'Interruptible','off', ... + 'MenuBar', 'none', ... + 'NumberTitle','off', ... + 'Renderer','Painters', ... + 'Resize','off'); + ncol = ceil(totCPU/10); + hspace = 0.9/ncol; + hstatus(1) = axes('position',[0.05/ncol 0.92 0.9/ncol 0.03], ... + 'box','on','xtick',[],'ytick',[],'xlim',[0 1],'ylim',[0 1]); + set(hstatus(1),'Units','pixels') + hpixel = get(hstatus(1),'Position'); + hfigure = get(hfigstatus,'Position'); + hfigure(4)=hpixel(4)*10/3*min(10,totCPU); + set(hfigstatus,'Position',hfigure) + set(hstatus(1),'Units','normalized'), + vspace = max(0.1,1/totCPU); + vstart = 1-vspace+0.2*vspace; + for j=1:totCPU + jrow = mod(j-1,10)+1; + jcol = ceil(j/10); + hstatus(j) = axes('position',[0.05/ncol+(jcol-1)/ncol vstart-vspace*(jrow-1) 0.9/ncol 0.3*vspace], ... + 'box','on','xtick',[],'ytick',[],'xlim',[0 1],'ylim',[0 1]); + hpat(j) = patch([0 0 0 0],[0 1 1 0],'r','EdgeColor','r'); + htit(j) = title(['Initialize ...']); + + end + + cumBlockPerCPU = cumsum(nBlockPerCPU); + end + pcerdone = NaN(1,totCPU); + idCPU = NaN(1,totCPU); + + + + % Wait for the slaves to finish their job, and display some progress + % information meanwhile. + + % Caption for console mode computing ... + + if options_.console_mode || isoctave + + if ~isoctave + if strcmpi([Parallel(indPC).MatlabOctavePath], 'octave') + RjInformation='Hybrid Computing Is Active: Remote jobs are computed by Octave!'; + fprintf([RjInformation,'\n\n']); end end + + fnameTemp=fname; + + L=length(fnameTemp); + + PoCo=strfind(fnameTemp,'_core'); + + for i=PoCo:L + if i==PoCo + fnameTemp(i)=' '; + else + fnameTemp(i)='.'; + end + end + + for i=1:L + if fnameTemp(i)=='_' + fnameTemp(i)=' '; + end + end + + fnameTemp(L)=''; + + Information=['Parallel ' fnameTemp ' Computing ...']; + if isoctave + if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) && (Strategy==0) + printf('\n'); + pause(2); + end + + printf([Information,'\n\n']); + else + fprintf([Information,'\n\n']); + end + end - % Check if the slave(s) has generated some new files remotely. - % 1. The files .log and .txt are not copied. - % 2. The comp_status_*.mat files are managed separately. - if isoctave % to avoid synchronism problems + % Testing Zone + + % Check the new copy file strategy ... + global NuoviFilecopiati + NuoviFilecopiati=zeros(1,totSlaves); + % End + + ForEver=1; + statusString = ''; + flag_CloseAllSlaves=0; + + while (ForEver) + + waitbarString = ''; + statusString0 = repmat('\b',1,length(sprintf(statusString, 100 .* pcerdone))); + statusString = ''; + + pause(1) + try - PRCDirSnapshot=dynareParallelGetNewFiles(PRCDir,Parallel(1:totSlaves),PRCDirSnapshot); + if islocal ==0 + dynareParallelGetFiles(['comp_status_',fname,'*.mat'],PRCDir,Parallel(1:totSlaves)); + end catch end - else - PRCDirSnapshot=dynareParallelGetNewFiles(PRCDir,Parallel(1:totSlaves),PRCDirSnapshot); - end - if isempty(dynareParallelDir(['P_',fname,'_*End.txt'],PRCDir,Parallel(1:totSlaves))) - HoTuttiGliOutput=0; for j=1:totCPU - - % Checking if the remote computation is finished and if we copied all the output here. - if ~isempty(dir([fname,'_output_',int2str(j),'.mat'])) - HoTuttiGliOutput=HoTuttiGliOutput+1; - else - indPC=min(find(nCPU>=j)); - dynareParallelGetFiles([fname,'_output_',int2str(j),'.mat'],PRCDir,Parallel(indPC)); - end - end - - if HoTuttiGliOutput==totCPU - mydelete(['comp_status_',fname,'*.mat']); - if isoctave || options_.console_mode - if isoctave - printf('\n'); - printf(['End Parallel Session ....','\n\n']); - else - fprintf('\n'); - fprintf(['End Parallel Session ....','\n\n']); + try + if ~isempty(['comp_status_',fname,int2str(j),'.mat']) + load(['comp_status_',fname,int2str(j),'.mat']); + % whoCloseAllSlaves = who(['comp_status_',fname,int2str(j),'.mat','CloseAllSlaves']); + if exist('CloseAllSlaves') && flag_CloseAllSlaves==0 + flag_CloseAllSlaves=1; + whoiamCloseAllSlaves=j; + closeSlave(Parallel(1:totSlaves),PRCDir,1); + end end - diary on; + pcerdone(j) = prtfrc; + idCPU(j) = njob; + if isoctave || options_.console_mode + if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) + statusString = [statusString, int2str(j), ' %3.f%% done! ']; + else + statusString = [statusString, int2str(j), ' %3.f%% done! ']; + end + else + status_String{j} = waitbarString; + status_Title{j} = waitbarTitle; + end + catch % ME + % To define! + if isoctave || options_.console_mode + if (~ispc || strcmpi('unix',Parallel(indPC).OperatingSystem)) + statusString = [statusString, int2str(j), ' %3.f%% done! ']; + else + statusString = [statusString, int2str(j), ' %3.f%% done! ']; + end + end + end + end + if isoctave || options_.console_mode + if isoctave + printf([statusString,'\r'], 100 .* pcerdone); else - close(hfigstatus) + if ~isempty(statusString) + fprintf([statusString0,statusString], 100 .* pcerdone); + end + end + else + for j=1:totCPU + try + set(hpat(j),'XData',[0 0 pcerdone(j) pcerdone(j)]); + set(htit(j),'String',[status_Title{j},' - ',status_String{j}]); + catch + + end + end + end + + % Check if the slave(s) has generated some new files remotely. + % 1. The files .log and .txt are not copied. + % 2. The comp_status_*.mat files are managed separately. + + if isoctave % to avoid synchronism problems + try + PRCDirSnapshot=dynareParallelGetNewFiles(PRCDir,Parallel(1:totSlaves),PRCDirSnapshot); + catch + end + else + PRCDirSnapshot=dynareParallelGetNewFiles(PRCDir,Parallel(1:totSlaves),PRCDirSnapshot); + end + + if isempty(dynareParallelDir(['P_',fname,'_*End.txt'],PRCDir,Parallel(1:totSlaves))) + HoTuttiGliOutput=0; + for j=1:totCPU + + % Checking if the remote computation is finished and if we copied all the output here. + if ~isempty(dir([fname,'_output_',int2str(j),'.mat'])) + HoTuttiGliOutput=HoTuttiGliOutput+1; + else + indPC=min(find(nCPU>=j)); + dynareParallelGetFiles([fname,'_output_',int2str(j),'.mat'],PRCDir,Parallel(indPC)); + end end - break - else - disp('Waiting for output files from slaves ...') + if HoTuttiGliOutput==totCPU + mydelete(['comp_status_',fname,'*.mat']); + if isoctave || options_.console_mode + if isoctave + printf('\n'); + printf(['End Parallel Session ....','\n\n']); + else + fprintf('\n'); + fprintf(['End Parallel Session ....','\n\n']); + end + diary on; + else + close(hfigstatus) + end + + break + else + disp('Waiting for output files from slaves ...') + end end + end +else + for j=1:totSlaves + PRCDirSnapshot{j}={}; + end + flag_CloseAllSlaves = 0; end - - % Load and format remote output. iscrash = 0; PRCDirSnapshot=dynareParallelGetNewFiles(PRCDir,Parallel(1:totSlaves),PRCDirSnapshot); @@ -902,4 +914,4 @@ switch Strategy end end end -end \ No newline at end of file +end diff --git a/matlab/partial_information/add_auxiliary_variables_to_steadystate.m b/matlab/partial_information/add_auxiliary_variables_to_steadystate.m index e1ffe4f19..35bd84bb3 100644 --- a/matlab/partial_information/add_auxiliary_variables_to_steadystate.m +++ b/matlab/partial_information/add_auxiliary_variables_to_steadystate.m @@ -2,7 +2,7 @@ function ys1 = add_auxiliary_variables_to_steadystate(ys,aux_vars,fname, ... exo_steady_state, exo_det_steady_state,params, byte_code) % Add auxiliary variables to the steady state vector -% Copyright (C) 2009-2017 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -23,9 +23,9 @@ ys1 = [ys;zeros(n,1)]; for i=1:n+1 if byte_code - [info, res] = bytecode('static','evaluate',ys1,... - [exo_steady_state; ... - exo_det_steady_state],params); + res = bytecode('static','evaluate',ys1,... + [exo_steady_state; ... + exo_det_steady_state],params); else res = feval([fname '.static'],ys1,... [exo_steady_state; ... diff --git a/matlab/partial_information/dr1_PI.m b/matlab/partial_information/dr1_PI.m index 2a6572268..39d57b818 100644 --- a/matlab/partial_information/dr1_PI.m +++ b/matlab/partial_information/dr1_PI.m @@ -176,279 +176,279 @@ if options_.aim_solver error('Anderson and Moore AIM solver is not compatible with Partial Information models'); end % end if useAIM and... - % If required, try PCL86 solver, that is, if not the check being - % performed only and if it is 1st order - % create sparse, extended jacobia AA: - nendo=M_.endo_nbr; % = size(aa,1) +% If required, try PCL86 solver, that is, if not the check being +% performed only and if it is 1st order +% create sparse, extended jacobia AA: +nendo=M_.endo_nbr; % = size(aa,1) - if(options_.ACES_solver) - %if ~isfield(lq_instruments,'names') - if isfield(options_,'instruments') - lq_instruments.names=options_.instruments; +if(options_.ACES_solver) + %if ~isfield(lq_instruments,'names') + if isfield(options_,'instruments') + lq_instruments.names=options_.instruments; + end + %end + if isfield(lq_instruments,'names') + num_inst=size(lq_instruments.names,1); + if ~isfield(lq_instruments,'inst_var_indices') && num_inst>0 + for i=1:num_inst + i_tmp = strmatch(deblank(lq_instruments.names(i,:)), M_.endo_names,'exact'); + if isempty(i_tmp) + error (['One of the specified instrument variables does not exist']) ; + else + i_var(i) = i_tmp; + end + end + lq_instruments.inst_var_indices=i_var; + elseif size(lq_instruments.inst_var_indices)>0 + i_var=lq_instruments.inst_var_indices; + if ~num_inst + num_inst=size(lq_instruments.inst_var_indices); + end + else + i_var=[]; + num_inst=0; end - %end - if isfield(lq_instruments,'names') - num_inst=size(lq_instruments.names,1); - if ~isfield(lq_instruments,'inst_var_indices') && num_inst>0 - for i=1:num_inst - i_tmp = strmatch(deblank(lq_instruments.names(i,:)), M_.endo_names,'exact'); - if isempty(i_tmp) - error (['One of the specified instrument variables does not exist']) ; - else - i_var(i) = i_tmp; - end + if size(i_var,2)>0 && size(i_var,2)==num_inst + m_var=zeros(nendo,1); + for i=1:nendo + if isempty(find(i_var==i)) + m_var(i)=i; end - lq_instruments.inst_var_indices=i_var; - elseif size(lq_instruments.inst_var_indices)>0 - i_var=lq_instruments.inst_var_indices; - if ~num_inst - num_inst=size(lq_instruments.inst_var_indices); - end - else - i_var=[]; - num_inst=0; end - if size(i_var,2)>0 && size(i_var,2)==num_inst - m_var=zeros(nendo,1); - for i=1:nendo - if isempty(find(i_var==i)) - m_var(i)=i; - end - end - m_var=nonzeros(m_var); - lq_instruments.m_var=m_var; - else - error('WARNING: There are no instrumnets for ACES!'); - end - else %if(options_.ACES_solver==1) + m_var=nonzeros(m_var); + lq_instruments.m_var=m_var; + else error('WARNING: There are no instrumnets for ACES!'); end + else %if(options_.ACES_solver==1) + error('WARNING: There are no instrumnets for ACES!'); end +end - % find size xlen of the state vector Y and of A0, A1 and A2 transition matrices: - % it is the sum the all i variables's lag/lead representations, - % for each variable i representation being defined as: - % Max (i_lags-1,0)+ Max (i_leads-1,0)+1 - % so that if variable x appears with 2 lags and 1 lead, and z - % with 2 lags and 3 leads, the size of the state space is: - % 1+0+1 + 1+2+1 =6 - % e.g. E_t Y(t+1)= - % E_t x(t) - % E_t x(t+1) - % E_t z(t) - % E_t z(t+1) - % E_t z(t+2) - % E_t z(t+3) +% find size xlen of the state vector Y and of A0, A1 and A2 transition matrices: +% it is the sum the all i variables's lag/lead representations, +% for each variable i representation being defined as: +% Max (i_lags-1,0)+ Max (i_leads-1,0)+1 +% so that if variable x appears with 2 lags and 1 lead, and z +% with 2 lags and 3 leads, the size of the state space is: +% 1+0+1 + 1+2+1 =6 +% e.g. E_t Y(t+1)= +% E_t x(t) +% E_t x(t+1) +% E_t z(t) +% E_t z(t+1) +% E_t z(t+2) +% E_t z(t+3) - % partition jacobian: - jlen=M_.nspred+M_.nsfwrd+M_.endo_nbr+M_.exo_nbr; % length of jacobian - PSI=-jacobia_(:, jlen-M_.exo_nbr+1:end); % exog - % first transpose M_.lead_lag_incidence'; - lead_lag=M_.lead_lag_incidence'; - max_lead_lag=zeros(nendo,2); % lead/lag representation in Y for each endogenous variable i - if ( M_.maximum_lag <= 1) && (M_.maximum_lead <= 1) - xlen=size(jacobia_,1);%nendo; - AA0=zeros(xlen,xlen); % empty A0 - AA2=AA0; % empty A2 and A3 - AA3=AA0; - if xlen==nendo % && M_.maximum_lag <=1 && M_.maximum_lead <=1 % apply a shortcut - AA1=jacobia_(:,nspred+1:nspred+nendo); - if M_.maximum_lead ==1 - fnd = find(lead_lag(:,M_.maximum_lag+2)); - AA0(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,M_.maximum_lag+2))); %forwd jacobian - end - if nspred>0 && M_.maximum_lag ==1 - fnd = find(lead_lag(:,1)); - AA2(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,1))); %backward - end - elseif options_.ACES_solver % more endo vars than equations in jacobia_ - if nendo-xlen==num_inst - PSI=[PSI;zeros(num_inst, M_.exo_nbr)]; - % AA1 contemporary - AA_all=jacobia_(:,nspred+1:nspred+nendo); - AA1=AA_all(:,lq_instruments.m_var); % endo without instruments - lq_instruments.ij1=AA_all(:,lq_instruments.inst_var_indices); % instruments only - lq_instruments.B1=-[lq_instruments.ij1; eye(num_inst)]; - AA1=[AA1, zeros(xlen,num_inst); zeros(num_inst,xlen), eye(num_inst)]; - %PSI=[PSI; zeros(num_inst,M_.exo_nbr)]; - if M_.maximum_lead ==1 % AA0 forward looking - AA_all(:,:)=0.0; - fnd = find(lead_lag(:,M_.maximum_lag+2)); - AA_all(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,M_.maximum_lag+2))); %forwd jacobian - AA0=AA_all(:,lq_instruments.m_var); - lq_instruments.ij0=AA_all(:,lq_instruments.inst_var_indices); % instruments only - lq_instruments.B0=[lq_instruments.ij0; eye(num_inst)]; - AA0=[AA0, zeros(xlen,num_inst); zeros(num_inst,xlen+num_inst)]; - end - if nspred>0 && M_.maximum_lag ==1 - AA_all(:,:)=0.0; - fnd = find(lead_lag(:,1)); - AA_all(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,1))); %backward - AA2=AA_all(:,lq_instruments.m_var); - lq_instruments.ij2=AA_all(:,lq_instruments.inst_var_indices); % instruments only - lq_instruments.B2=[lq_instruments.ij2; eye(num_inst)]; - AA2=[AA2, lq_instruments.ij2 ; zeros(num_inst,xlen+num_inst)]; - end - else - error('ACES number of instruments does match'); +% partition jacobian: +jlen=M_.nspred+M_.nsfwrd+M_.endo_nbr+M_.exo_nbr; % length of jacobian +PSI=-jacobia_(:, jlen-M_.exo_nbr+1:end); % exog + % first transpose M_.lead_lag_incidence'; +lead_lag=M_.lead_lag_incidence'; +max_lead_lag=zeros(nendo,2); % lead/lag representation in Y for each endogenous variable i +if ( M_.maximum_lag <= 1) && (M_.maximum_lead <= 1) + xlen=size(jacobia_,1);%nendo; + AA0=zeros(xlen,xlen); % empty A0 + AA2=AA0; % empty A2 and A3 + AA3=AA0; + if xlen==nendo % && M_.maximum_lag <=1 && M_.maximum_lead <=1 % apply a shortcut + AA1=jacobia_(:,nspred+1:nspred+nendo); + if M_.maximum_lead ==1 + fnd = find(lead_lag(:,M_.maximum_lag+2)); + AA0(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,M_.maximum_lag+2))); %forwd jacobian end - else - error('More than one lead or lag in the jabian'); + if nspred>0 && M_.maximum_lag ==1 + fnd = find(lead_lag(:,1)); + AA2(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,1))); %backward end - if M_.orig_endo_nbr0 - AA3(:,exp_0)=AA1(:,exp_0); - XX0=zeros(nendo,num_exp_0); - AA1(:,exp_0)=XX0(:,[1:num_exp_0]) - end + elseif options_.ACES_solver % more endo vars than equations in jacobia_ + if nendo-xlen==num_inst + PSI=[PSI;zeros(num_inst, M_.exo_nbr)]; + % AA1 contemporary + AA_all=jacobia_(:,nspred+1:nspred+nendo); + AA1=AA_all(:,lq_instruments.m_var); % endo without instruments + lq_instruments.ij1=AA_all(:,lq_instruments.inst_var_indices); % instruments only + lq_instruments.B1=-[lq_instruments.ij1; eye(num_inst)]; + AA1=[AA1, zeros(xlen,num_inst); zeros(num_inst,xlen), eye(num_inst)]; + %PSI=[PSI; zeros(num_inst,M_.exo_nbr)]; + if M_.maximum_lead ==1 % AA0 forward looking + AA_all(:,:)=0.0; + fnd = find(lead_lag(:,M_.maximum_lag+2)); + AA_all(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,M_.maximum_lag+2))); %forwd jacobian + AA0=AA_all(:,lq_instruments.m_var); + lq_instruments.ij0=AA_all(:,lq_instruments.inst_var_indices); % instruments only + lq_instruments.B0=[lq_instruments.ij0; eye(num_inst)]; + AA0=[AA0, zeros(xlen,num_inst); zeros(num_inst,xlen+num_inst)]; + end + if nspred>0 && M_.maximum_lag ==1 + AA_all(:,:)=0.0; + fnd = find(lead_lag(:,1)); + AA_all(:, fnd)= jacobia_(:,nonzeros(lead_lag(:,1))); %backward + AA2=AA_all(:,lq_instruments.m_var); + lq_instruments.ij2=AA_all(:,lq_instruments.inst_var_indices); % instruments only + lq_instruments.B2=[lq_instruments.ij2; eye(num_inst)]; + AA2=[AA2, lq_instruments.ij2 ; zeros(num_inst,xlen+num_inst)]; + end + else + error('ACES number of instruments does match'); + end + else + error('More than one lead or lag in the jabian'); + end + if M_.orig_endo_nbr0 + AA3(:,exp_0)=AA1(:,exp_0); + XX0=zeros(nendo,num_exp_0); + AA1(:,exp_0)=XX0(:,[1:num_exp_0]) end end - PSI=-[[zeros(xlen-nendo,M_.exo_nbr)];[jacobia_(:, jlen-M_.exo_nbr+1:end)]]; % exog - cc=0; - NX=M_.exo_nbr; % no of exogenous varexo shock variables. - NETA=nfwrd+nboth; % total no of exp. errors set to no of forward looking equations - FL_RANK=rank(AA0); % nfwrd+nboth; % min total no of forward looking equations and vars +end +PSI=-[[zeros(xlen-nendo,M_.exo_nbr)];[jacobia_(:, jlen-M_.exo_nbr+1:end)]]; % exog +cc=0; +NX=M_.exo_nbr; % no of exogenous varexo shock variables. +NETA=nfwrd+nboth; % total no of exp. errors set to no of forward looking equations +FL_RANK=rank(AA0); % nfwrd+nboth; % min total no of forward looking equations and vars - try - % call [G1pi,C,impact,nmat,TT1,TT2,gev,eu]=PI_gensys(a0,a1,a2,c,PSI,NX,NETA,NO_FL_EQS) - % System given as - % a0*E_t[y(t+1])+a1*y(t)=a2*y(t-1)+c+psi*eps(t) - % with eps an exogenous variable process. - % Returned system is - % [s(t)' x(t)' E_t x(t+1)']'=G1pi [s(t-1)' x(t-1)' x(t)]'+C+impact*eps(t), - % and (a) the matrix nmat satisfying nmat*E_t z(t)+ E_t x(t+1)=0 - % (b) matrices TT1, TT2 that relate y(t) to these states: - % y(t)=[TT1 TT2][s(t)' x(t)']'. +try + % call [G1pi,C,impact,nmat,TT1,TT2,gev,eu]=PI_gensys(a0,a1,a2,c,PSI,NX,NETA,NO_FL_EQS) + % System given as + % a0*E_t[y(t+1])+a1*y(t)=a2*y(t-1)+c+psi*eps(t) + % with eps an exogenous variable process. + % Returned system is + % [s(t)' x(t)' E_t x(t+1)']'=G1pi [s(t-1)' x(t-1)' x(t)]'+C+impact*eps(t), + % and (a) the matrix nmat satisfying nmat*E_t z(t)+ E_t x(t+1)=0 + % (b) matrices TT1, TT2 that relate y(t) to these states: + % y(t)=[TT1 TT2][s(t)' x(t)']'. - if(options_.ACES_solver) - if isfield(lq_instruments,'xsopt_SS') - SSbar= diag([lq_instruments.xsopt_SS(m_var)]);% lq_instruments.xsopt_SS(lq_instruments.inst_var_indices)]); - insSSbar=repmat(lq_instruments.xsopt_SS(lq_instruments.inst_var_indices)',nendo-num_inst,1); - else - SSbar= diag([dr.ys(m_var)]);%; dr.ys(lq_instruments.inst_var_indices)]);%(oo_.steady_state); - insSSbar=repmat(dr.ys(lq_instruments.inst_var_indices)',nendo-num_inst,1); - end - SSbar=diag([diag(SSbar);diag(eye(num_inst))]); - insSSbar=[insSSbar;diag(eye(num_inst))]; - - AA0=AA0*SSbar; - AA1=AA1*SSbar; - AA2=AA2*SSbar; - lq_instruments.B1=(lq_instruments.B1).*insSSbar; - end - %% for expectational models when complete - if any(AA3) - AA3=AA3*SSbar; - [G1pi,CC,impact,nmat,TT1,TT2,gev,eu, DD, E2,E5, GAMMA, FL_RANK]=PI_gensysEXP(AA0,AA1,-AA2,AA3,cc,PSI,NX,NETA,FL_RANK, M_, options_); + if(options_.ACES_solver) + if isfield(lq_instruments,'xsopt_SS') + SSbar= diag([lq_instruments.xsopt_SS(m_var)]);% lq_instruments.xsopt_SS(lq_instruments.inst_var_indices)]); + insSSbar=repmat(lq_instruments.xsopt_SS(lq_instruments.inst_var_indices)',nendo-num_inst,1); else - [G1pi,CC,impact,nmat,TT1,TT2,gev,eu, DD, E2,E5, GAMMA, FL_RANK]=PI_gensys(AA0,AA1,-AA2,AA3,cc,PSI,NX,NETA,FL_RANK, M_, options_); + SSbar= diag([dr.ys(m_var)]);%; dr.ys(lq_instruments.inst_var_indices)]);%(oo_.steady_state); + insSSbar=repmat(dr.ys(lq_instruments.inst_var_indices)',nendo-num_inst,1); end + SSbar=diag([diag(SSbar);diag(eye(num_inst))]); + insSSbar=[insSSbar;diag(eye(num_inst))]; - % reuse some of the bypassed code and tests that may be needed - if (eu(1) ~= 1 || eu(2) ~= 1) && ~options_.ACES_solver - info(1) = abs(eu(1)+eu(2)); - info(2) = 1.0e+8; - % return - end - - dr.PI_ghx=G1pi; - dr.PI_ghu=impact; - dr.PI_TT1=TT1; - dr.PI_TT2=TT2; - dr.PI_nmat=nmat; - dr.PI_CC=CC; - dr.PI_gev=gev; - dr.PI_eu=eu; - dr.PI_FL_RANK=FL_RANK; - %dr.ys=zeros(nendo); % zero steady state - dr.ghx=G1pi; - dr.ghu=impact; - dr.eigval = eig(G1pi); - dr.rank=FL_RANK; - - if options_.ACES_solver - betap=options_.planner_discount; - sigma_cov=M_.Sigma_e; - % get W - BY - W=(1-betap)*GAMMA'*DYN_Q*GAMMA; - %W=[0] - ACES.A=G1pi; - ACES.C=impact; % (:,1); - ACES.D=DD; %=impact (:,20); - ACES.E2=E2; - ACES.E5=E5; - ACES.GAMMA=GAMMA; - ACES_M=size(G1pi,2)-FL_RANK; - ACES_NM=FL_RANK; - ACES.M=ACES_M; - ACES.NM=FL_RANK; - % added by BY - ACES.Q=DYN_Q; - ACES.W=W; - NY=nendo-num_inst; - - % save the followings in a subdirectory - BY - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_Matrices'], 'ACES'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_GAMMA'], 'GAMMA'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_A.txt'], 'G1pi', '-ascii', '-double', '-tabs'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_C.txt'], 'impact','-ascii', '-double', '-tabs'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_D.txt'], 'DD', '-ascii', '-double', '-tabs'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_E2.txt'], 'E2', '-ascii', '-double', '-tabs'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_E5.txt'], 'E5', '-ascii', '-double', '-tabs'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_GAMMA.txt'], 'GAMMA', '-ascii', '-double', '-tabs'); - %save ([M_.fname '_ACESLQ_M.txt'], 'ACES_M', '-ascii', '-tabs'); - %save ([M_.fname '_ACESLQ_NM.txt'], 'ACES_NM', '-ascii', '-tabs'); - %save ([M_.fname '_ACESLQ_betap.txt'], 'betap', '-ascii', '-tabs'); - %save ([M_.fname '_ACESLQ_NI.txt'], 'num_inst', '-ascii', '-tabs'); - %save ([M_.fname '_ACESLQ_ND.txt'], 'NX', '-ascii', '-tabs'); - %save ([M_.fname '_ACESLQ_NY.txt'], 'NY', '-ascii', '-tabs'); - ACES_VARS=char(M_.endo_names); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_VARS.txt'], 'ACES_VARS', '-ascii', '-tabs'); - % added by BY - % save the char array ACES_VARS into .txt as it is - fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_VARnames.txt'),'wt'); - ACES_VARS =[ACES_VARS repmat(sprintf('\n'),size(ACES_VARS,1),1)]; - fwrite(fid,ACES_VARS.'); - fclose(fid); - % save as integers - fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_M.txt'),'wt'); - fprintf(fid,'%d\n',ACES_M); - fclose(fid); - fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_NM.txt'),'wt'); - fprintf(fid,'%d\n',ACES_NM); - fclose(fid); - fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_betap.txt'),'wt'); - fprintf(fid,'%d\n',betap); - fclose(fid); - fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_NI.txt'),'wt'); - fprintf(fid,'%d\n',num_inst); - fclose(fid); - fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_ND.txt'),'wt'); - fprintf(fid,'%d\n',NX); - fclose(fid); - fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_NY.txt'),'wt'); - fprintf(fid,'%d\n',NY); - fclose(fid); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_Q.txt'], 'DYN_Q', '-ascii', '-double', '-tabs'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_W.txt'], 'W', '-ascii', '-double', '-tabs'); - save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_SIGMAE.txt'], 'sigma_cov', '-ascii', '-double', '-tabs'); - end - - catch - lerror=lasterror; - if options_.ACES_solver - disp('Problem with using Part Info ACES solver:'); - error(lerror.message); - else - disp('Problem with using Part Info solver'); - error(lerror.message); - end + AA0=AA0*SSbar; + AA1=AA1*SSbar; + AA2=AA2*SSbar; + lq_instruments.B1=(lq_instruments.B1).*insSSbar; + end + %% for expectational models when complete + if any(AA3) + AA3=AA3*SSbar; + [G1pi,CC,impact,nmat,TT1,TT2,gev,eu, DD, E2,E5, GAMMA, FL_RANK]=PI_gensysEXP(AA0,AA1,-AA2,AA3,cc,PSI,NX,NETA,FL_RANK, M_, options_); + else + [G1pi,CC,impact,nmat,TT1,TT2,gev,eu, DD, E2,E5, GAMMA, FL_RANK]=PI_gensys(AA0,AA1,-AA2,AA3,cc,PSI,NX,NETA,FL_RANK, M_, options_); end - % TODO: - % if options_.loglinear == 1 - % if exogenous deterministic variables + % reuse some of the bypassed code and tests that may be needed + if (eu(1) ~= 1 || eu(2) ~= 1) && ~options_.ACES_solver + info(1) = abs(eu(1)+eu(2)); + info(2) = 1.0e+8; + % return + end + + dr.PI_ghx=G1pi; + dr.PI_ghu=impact; + dr.PI_TT1=TT1; + dr.PI_TT2=TT2; + dr.PI_nmat=nmat; + dr.PI_CC=CC; + dr.PI_gev=gev; + dr.PI_eu=eu; + dr.PI_FL_RANK=FL_RANK; + %dr.ys=zeros(nendo); % zero steady state + dr.ghx=G1pi; + dr.ghu=impact; + dr.eigval = eig(G1pi); + dr.rank=FL_RANK; + + if options_.ACES_solver + betap=options_.planner_discount; + sigma_cov=M_.Sigma_e; + % get W - BY + W=(1-betap)*GAMMA'*DYN_Q*GAMMA; + %W=[0] + ACES.A=G1pi; + ACES.C=impact; % (:,1); + ACES.D=DD; %=impact (:,20); + ACES.E2=E2; + ACES.E5=E5; + ACES.GAMMA=GAMMA; + ACES_M=size(G1pi,2)-FL_RANK; + ACES_NM=FL_RANK; + ACES.M=ACES_M; + ACES.NM=FL_RANK; + % added by BY + ACES.Q=DYN_Q; + ACES.W=W; + NY=nendo-num_inst; + + % save the followings in a subdirectory - BY + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_Matrices'], 'ACES'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_GAMMA'], 'GAMMA'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_A.txt'], 'G1pi', '-ascii', '-double', '-tabs'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_C.txt'], 'impact','-ascii', '-double', '-tabs'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_D.txt'], 'DD', '-ascii', '-double', '-tabs'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_E2.txt'], 'E2', '-ascii', '-double', '-tabs'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_E5.txt'], 'E5', '-ascii', '-double', '-tabs'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_GAMMA.txt'], 'GAMMA', '-ascii', '-double', '-tabs'); + %save ([M_.fname '_ACESLQ_M.txt'], 'ACES_M', '-ascii', '-tabs'); + %save ([M_.fname '_ACESLQ_NM.txt'], 'ACES_NM', '-ascii', '-tabs'); + %save ([M_.fname '_ACESLQ_betap.txt'], 'betap', '-ascii', '-tabs'); + %save ([M_.fname '_ACESLQ_NI.txt'], 'num_inst', '-ascii', '-tabs'); + %save ([M_.fname '_ACESLQ_ND.txt'], 'NX', '-ascii', '-tabs'); + %save ([M_.fname '_ACESLQ_NY.txt'], 'NY', '-ascii', '-tabs'); + ACES_VARS=char(M_.endo_names); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_VARS.txt'], 'ACES_VARS', '-ascii', '-tabs'); + % added by BY + % save the char array ACES_VARS into .txt as it is + fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_VARnames.txt'),'wt'); + ACES_VARS =[ACES_VARS repmat(sprintf('\n'),size(ACES_VARS,1),1)]; + fwrite(fid,ACES_VARS.'); + fclose(fid); + % save as integers + fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_M.txt'),'wt'); + fprintf(fid,'%d\n',ACES_M); + fclose(fid); + fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_NM.txt'),'wt'); + fprintf(fid,'%d\n',ACES_NM); + fclose(fid); + fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_betap.txt'),'wt'); + fprintf(fid,'%d\n',betap); + fclose(fid); + fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_NI.txt'),'wt'); + fprintf(fid,'%d\n',num_inst); + fclose(fid); + fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_ND.txt'),'wt'); + fprintf(fid,'%d\n',NX); + fclose(fid); + fid = fopen(strcat(ACES_DirectoryName,'/',M_.fname,'_ACESLQ_NY.txt'),'wt'); + fprintf(fid,'%d\n',NY); + fclose(fid); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_Q.txt'], 'DYN_Q', '-ascii', '-double', '-tabs'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_W.txt'], 'W', '-ascii', '-double', '-tabs'); + save ([ACES_DirectoryName,'/',M_.fname '_ACESLQ_SIGMAE.txt'], 'sigma_cov', '-ascii', '-double', '-tabs'); + end + +catch + lerror=lasterror; + if options_.ACES_solver + disp('Problem with using Part Info ACES solver:'); + error(lerror.message); + else + disp('Problem with using Part Info solver'); + error(lerror.message); + end +end + +% TODO: +% if options_.loglinear == 1 +% if exogenous deterministic variables diff --git a/matlab/particles b/matlab/particles index 66867386e..cef201516 160000 --- a/matlab/particles +++ b/matlab/particles @@ -1 +1 @@ -Subproject commit 66867386ef5c70e8db69293af8a0e051488196f1 +Subproject commit cef20151625a8e353e6d3cd089276ee213fde88e diff --git a/matlab/perfect-foresight-models/det_cond_forecast.m b/matlab/perfect-foresight-models/det_cond_forecast.m index 98875fb91..8c50b1e96 100644 --- a/matlab/perfect-foresight-models/det_cond_forecast.m +++ b/matlab/perfect-foresight-models/det_cond_forecast.m @@ -12,7 +12,7 @@ function data_set = det_cond_forecast(varargin) % dataset [dseries] Returns a dseries containing the forecasted endgenous variables and shocks % -% Copyright (C) 2013-2018 Dynare Team +% Copyright (C) 2013-2020 Dynare Team % % This file is part of Dynare. % @@ -36,6 +36,9 @@ verbosity = options_.verbosity; if options_.periods == 0 options_.periods = 25; end +if isempty(options_.qz_criterium) + options_.qz_criterium = 1+1e-6; +end %We have to get an initial guess for the conditional forecast % and terminal conditions for the non-stationary variables, we % use the first order approximation of the rational expectation solution. @@ -158,13 +161,12 @@ else if options_.bytecode save_options_dynatol_f = options_.dynatol.f; options_.dynatol.f = 1e-7; - [Info, endo, exo] = bytecode('extended_path', plan, oo_.endo_simul, oo_.exo_simul, M_.params, oo_.steady_state, options_.periods); + [endo, exo] = bytecode('extended_path', plan, oo_.endo_simul, oo_.exo_simul, M_.params, oo_.steady_state, options_.periods); options_.dynatol.f = save_options_dynatol_f; - if Info == 0 - oo_.endo_simul = endo; - oo_.exo_simul = exo; - end + oo_.endo_simul = endo; + oo_.exo_simul = exo; + endo = endo'; endo_l = size(endo(1+M_.maximum_lag:end,:),1); jrng = dates(plan.date(1)):dates(plan.date(1)+endo_l); @@ -473,14 +475,12 @@ if pf && ~surprise end data1 = M_; if (options_.bytecode) - [chck, zz, data1]= bytecode('dynamic','evaluate', z, zx, M_.params, oo_.steady_state, k, data1); + [zz, data1]= bytecode('dynamic','evaluate', z, zx, M_.params, oo_.steady_state, k, data1); else [zz, g1b] = feval([M_.fname '.dynamic'], z', zx, M_.params, oo_.steady_state, k); data1.g1_x = g1b(:,end - M_.exo_nbr + 1:end); data1.g1 = g1b(:,1 : end - M_.exo_nbr); - chck = 0; end - mexErrCheck('bytecode', chck); end if k == 1 g1(1:M_.endo_nbr,-M_.endo_nbr + [cur_indx lead_indx]) = data1.g1(:,M_.nspred + 1:end); @@ -745,14 +745,12 @@ else end data1 = M_; if (options_.bytecode) - [chck, zz, data1]= bytecode('dynamic','evaluate', z, zx, M_.params, oo_.steady_state, k, data1); + [zz, data1]= bytecode('dynamic','evaluate', z, zx, M_.params, oo_.steady_state, k, data1); else [zz, g1b] = feval([M_.fname '.dynamic'], z', zx, M_.params, oo_.steady_state, k); data1.g1_x = g1b(:,end - M_.exo_nbr + 1:end); data1.g1 = g1b(:,1 : end - M_.exo_nbr); - chck = 0; end - mexErrCheck('bytecode', chck); end if k == 1 g1(1:M_.endo_nbr,-M_.endo_nbr + [cur_indx lead_indx]) = data1.g1(:,M_.nspred + 1:end); diff --git a/matlab/perfect-foresight-models/perfect_foresight_setup.m b/matlab/perfect-foresight-models/perfect_foresight_setup.m index b379be4f9..45f6f2789 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_setup.m +++ b/matlab/perfect-foresight-models/perfect_foresight_setup.m @@ -65,10 +65,6 @@ if ~isempty(M_.det_shocks) && options_.periods1 maxerror = oo_.deterministic_simulation.error; else if options_.bytecode - [~, residuals]= bytecode('dynamic','evaluate', oo_.endo_simul, oo_.exo_simul, M_.params, oo_.steady_state, 1); + residuals = bytecode('dynamic','evaluate', oo_.endo_simul, oo_.exo_simul, M_.params, oo_.steady_state, 1); else if M_.maximum_lag > 0 y0 = oo_.endo_simul(:, M_.maximum_lag); diff --git a/matlab/perfect-foresight-models/private/initialize_stacked_problem.m b/matlab/perfect-foresight-models/private/initialize_stacked_problem.m index 5677add41..f127858c9 100644 --- a/matlab/perfect-foresight-models/private/initialize_stacked_problem.m +++ b/matlab/perfect-foresight-models/private/initialize_stacked_problem.m @@ -1,5 +1,5 @@ function [options, y0, yT, z, i_cols, i_cols_J1, i_cols_T, i_cols_j, i_cols_1, i_cols_0, i_cols_J0, dynamicmodel] = ... - initialize_stacked_problem(endogenousvariables, options, M, steadystate_y) + initialize_stacked_problem(endogenousvariables, options, M, steadystate_y) % Sets up the stacked perfect foresight problem for use with dynare_solve.m % diff --git a/matlab/perfect-foresight-models/sim1.m b/matlab/perfect-foresight-models/sim1.m index 0db50e2b0..3bd956c91 100644 --- a/matlab/perfect-foresight-models/sim1.m +++ b/matlab/perfect-foresight-models/sim1.m @@ -99,7 +99,7 @@ for iter = 1:options.simul.maxit break end if options.simul.robust_lin_solve - dy = -lin_solve_robust(A, res, verbose); + dy = -lin_solve_robust(A, res, verbose, options); else dy = -lin_solve(A, res, verbose); end @@ -173,7 +173,7 @@ if relres > 1e-6 && verbose fprintf('WARNING : Failed to find a solution to the linear system.\n'); end -function [ x, flag, relres ] = lin_solve_robust(A, b ,verbose) +function [ x, flag, relres ] = lin_solve_robust(A, b ,verbose, options) if norm(b) < sqrt(eps) % then x = 0 is a solution x = 0; flag = 0; diff --git a/matlab/plot_identification.m b/matlab/plot_identification.m index 48fff502e..82c5cea21 100644 --- a/matlab/plot_identification.m +++ b/matlab/plot_identification.m @@ -47,43 +47,43 @@ if nargin <11 end [SampleSize, nparam]=size(params); -si_Jnorm = idemoments.si_Jnorm; -si_dTAUnorm = idemodel.si_dTAUnorm; -si_dLREnorm = idelre.si_dLREnorm; +si_dMOMENTSnorm = idemoments.si_dMOMENTSnorm; +si_dTAUnorm = idemodel.si_dREDUCEDFORMnorm; +si_dLREnorm = idelre.si_dDYNAMICnorm; tittxt1=regexprep(tittxt, ' ', '_'); tittxt1=strrep(tittxt1, '.', ''); if SampleSize == 1 - si_J = idemoments.si_J; + si_dMOMENTS = idemoments.si_dMOMENTS; hh = dyn_figure(options_.nodisplay,'Name',[tittxt, ' - Identification using info from observables']); subplot(211) - mmm = (idehess.ide_strength_J); + mmm = (idehess.ide_strength_dMOMENTS); [ss, is] = sort(mmm); - if ~all(isnan(idehess.ide_strength_J_prior)) - bar(log([idehess.ide_strength_J(:,is)' idehess.ide_strength_J_prior(:,is)'])) + if ~all(isnan(idehess.ide_strength_dMOMENTS_prior)) + bar(1:nparam,log([idehess.ide_strength_dMOMENTS(:,is)' idehess.ide_strength_dMOMENTS_prior(:,is)'])) else - bar(log([idehess.ide_strength_J(:,is)' ])) + bar(1:nparam,log([idehess.ide_strength_dMOMENTS(:,is)' ])) end hold on - plot((1:length(idehess.ide_strength_J(:,is)))-0.15,log([idehess.ide_strength_J(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none') - plot((1:length(idehess.ide_strength_J_prior(:,is)))+0.15,log([idehess.ide_strength_J_prior(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none') - if any(isinf(log(idehess.ide_strength_J(idehess.identified_parameter_indices)))) + plot((1:length(idehess.ide_strength_dMOMENTS(:,is)))-0.15,log([idehess.ide_strength_dMOMENTS(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none') + plot((1:length(idehess.ide_strength_dMOMENTS_prior(:,is)))+0.15,log([idehess.ide_strength_dMOMENTS_prior(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none') + if any(isinf(log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices)))) %-Inf, i.e. 0 strength - inf_indices=find(isinf(log(idehess.ide_strength_J(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J(idehess.identified_parameter_indices))<0); + inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))<0); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); plot(find(inf_pos)-0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 0 0],'MarkerEdgeColor',[0 0 0]) %+Inf, i.e. Inf strength - inf_indices=find(isinf(log(idehess.ide_strength_J(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J(idehess.identified_parameter_indices))>0); + inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))>0); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); plot(find(inf_pos)-0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 1 1],'MarkerEdgeColor',[0 0 0]) end - if any(isinf(log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices)))) + if any(isinf(log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices)))) %-Inf, i.e. 0 strength - inf_indices=find(isinf(log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))<0); + inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))<0); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); plot(find(inf_pos)+0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 0 0],'MarkerEdgeColor',[0 0 0]) %+Inf, i.e. 0 strength - inf_indices=find(isinf(log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))>0); + inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))>0); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); plot(find(inf_pos)+0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 1 1],'MarkerEdgeColor',[0 0 0]) end @@ -93,7 +93,7 @@ if SampleSize == 1 for ip=1:nparam text(ip,dy(1),name{is(ip)},'rotation',90,'HorizontalAlignment','right','interpreter','none') end - if ~all(isnan(idehess.ide_strength_J_prior)) + if ~all(isnan(idehess.ide_strength_dMOMENTS_prior)) legend('relative to param value','relative to prior std','Location','Best') else legend('relative to param value','Location','Best') @@ -106,9 +106,9 @@ if SampleSize == 1 subplot(212) if ~all(isnan(idehess.deltaM_prior)) - bar(log([idehess.deltaM(is) idehess.deltaM_prior(is)])) + bar(1:nparam, log([idehess.deltaM(is) idehess.deltaM_prior(is)])) else - bar(log([idehess.deltaM(is)])) + bar(1:nparam, log([idehess.deltaM(is)])) end hold on plot((1:length(idehess.deltaM(is)))-0.15,log([idehess.deltaM(is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none') @@ -161,12 +161,12 @@ if SampleSize == 1 skipline() disp('Plotting advanced diagnostics') end - if all(isnan([si_Jnorm';si_dTAUnorm';si_dLREnorm'])) + if all(isnan([si_dMOMENTSnorm';si_dTAUnorm';si_dLREnorm'])) fprintf('\nIDENTIFICATION: Skipping sensitivity plot, because standard deviation of parameters is NaN, possibly due to the use of ML.\n') else hh = dyn_figure(options_.nodisplay,'Name',[tittxt, ' - Sensitivity plot']); subplot(211) - mmm = (si_Jnorm)'./max(si_Jnorm); + mmm = (si_dMOMENTSnorm)'./max(si_dMOMENTSnorm); mmm1 = (si_dTAUnorm)'./max(si_dTAUnorm); mmm=[mmm mmm1]; mmm1 = (si_dLREnorm)'./max(si_dLREnorm); @@ -199,7 +199,7 @@ if SampleSize == 1 end end % identificaton patterns - for j=1:size(idemoments.cosnJ,2) + for j=1:size(idemoments.cosndMOMENTS,2) pax=NaN(nparam,nparam); % fprintf('\n') % disp(['Collinearity patterns with ', int2str(j) ,' parameter(s)']) @@ -212,10 +212,10 @@ if SampleSize == 1 namx=[namx ' ' sprintf('%-15s','--')]; else namx=[namx ' ' sprintf('%-15s',name{dumpindx})]; - pax(i,dumpindx)=idemoments.cosnJ(i,j); + pax(i,dumpindx)=idemoments.cosndMOMENTS(i,j); end end - % fprintf('%-15s [%s] %10.3f\n',name{i},namx,idemoments.cosnJ(i,j)) + % fprintf('%-15s [%s] %10.3f\n',name{i},namx,idemoments.cosndMOMENTS(i,j)) end hh = dyn_figure(options_.nodisplay,'Name',[tittxt,' - Collinearity patterns with ', int2str(j) ,' parameter(s)']); imagesc(pax,[0 1]); @@ -337,9 +337,9 @@ if SampleSize == 1 else hh = dyn_figure(options_.nodisplay,'Name',['MC sensitivities']); subplot(211) - mmm = (idehess.ide_strength_J); + mmm = (idehess.ide_strength_dMOMENTS); [ss, is] = sort(mmm); - mmm = mean(si_Jnorm)'; + mmm = mean(si_dMOMENTSnorm)'; mmm = mmm./max(mmm); if advanced mmm1 = mean(si_dTAUnorm)'; diff --git a/matlab/plot_shock_decomposition.m b/matlab/plot_shock_decomposition.m index dbe76f9b9..81df99c09 100644 --- a/matlab/plot_shock_decomposition.m +++ b/matlab/plot_shock_decomposition.m @@ -1,4 +1,4 @@ -function [z, steady_state] = plot_shock_decomposition(M_,oo_,options_,varlist) +function [out, steady_state] = plot_shock_decomposition(M_,oo_,options_,varlist) % function plot_shock_decomposition(M_,oo_,options_,varlist) % Plots the results of shock_decomposition % @@ -31,32 +31,141 @@ function [z, steady_state] = plot_shock_decomposition(M_,oo_,options_,varlist) options_.nodisplay = options_.plot_shock_decomp.nodisplay; options_.graph_format = options_.plot_shock_decomp.graph_format; -% indices of endogenous variables -if isempty(varlist) - varlist = M_.endo_names(1:M_.orig_endo_nbr); +if ~isfield(oo_,'shock_decomposition_info') + oo_.shock_decomposition_info = struct(); +end +if ~isfield(oo_,'plot_shock_decomposition_info') + oo_.plot_shock_decomposition_info = struct(); +end + +out=oo_; +% indices of endogenous variables +exist_varlist = 1; +if size(varlist,1) == 0 + exist_varlist = 0; + if size( M_.endo_names,1) >= M_.orig_endo_nbr + varlist = M_.endo_names(1:M_.orig_endo_nbr); + else + varlist = M_.endo_names; + end +end + +if isfield(options_.plot_shock_decomp,'init2shocks') % private trap for uimenu calls + init2shocks=options_.plot_shock_decomp.init2shocks; +else + init2shocks=[]; +end +if ~isempty(init2shocks) + init2shocks=M_.init2shocks.(init2shocks); +end + + +epilogue_decomp=false; +if exist_varlist && any(ismember(varlist,M_.epilogue_names)) + epilogue_decomp=true; + M_.endo_names = [M_.endo_names;M_.epilogue_names]; + M_.endo_names_tex = [M_.endo_names_tex;M_.epilogue_names]; + M_.endo_nbr = length( M_.endo_names ); +end +if isfield(oo_.shock_decomposition_info,'i_var') && (M_.endo_nbr>=M_.orig_endo_nbr) + if max(oo_.shock_decomposition_info.i_var)>M_.orig_endo_nbr + epilogue_decomp=true; + M_.endo_names = [M_.endo_names;M_.epilogue_names]; + M_.endo_names_tex = [M_.endo_names_tex;M_.epilogue_names]; + M_.endo_nbr = length( M_.endo_names ); + end + M_.endo_names = M_.endo_names(oo_.shock_decomposition_info.i_var,:); + M_.endo_names_tex = M_.endo_names_tex(oo_.shock_decomposition_info.i_var,:); + M_.endo_nbr = length( oo_.shock_decomposition_info.i_var ); +end + +try + [i_var,nvar,index_uniques] = varlist_indices(varlist,M_.endo_names); +catch ME + if isfield(oo_.shock_decomposition_info,'i_var') + warning('shock decomp results for some input variable was not stored: I recompute all decompositions') + M_ = evalin('base','M_'); + bayestopt_ = evalin('base','bayestopt_'); + estim_params_ = evalin('base','estim_params_'); + options_.no_graph.shock_decomposition=1; % force nograph in computing decompositions! + oo_.shock_decomposition_info = rmfield(oo_.shock_decomposition_info,'i_var'); + var_list_ = char(); + disp('recomputing shock decomposition ...') + [oo_,M_]= shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_); + if isfield(oo_,'realtime_shock_decomposition') || options_.plot_shock_decomp.realtime + disp('recomputing realtime shock decomposition ...') + oo_ = realtime_shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_); + end + if isfield(oo_,'initval_decomposition') + disp('recomputing initval shock decomposition ...') + oo_ = initial_condition_decomposition(M_,oo_,options_,0,bayestopt_,estim_params_); + end + [i_var,nvar,index_uniques] = varlist_indices(varlist,M_.endo_names); + out = oo_; + else + rethrow(ME) + end end -[i_var, ~, index_uniques] = varlist_indices(varlist, M_.endo_names); varlist = varlist(index_uniques); -% number of variables -endo_nbr = M_.endo_nbr; +if ~isfield(out.shock_decomposition_info,'i_var') && exist_varlist + if ~isfield(out.plot_shock_decomposition_info,'i_var') + out.plot_shock_decomposition_info.i_var = i_var; + else + out.plot_shock_decomposition_info.i_var = unique([i_var(:); out.plot_shock_decomposition_info.i_var(:)]); + end +end + +type=options_.plot_shock_decomp.type; +if isequal(type, 'aoa') && isfield(options_.plot_shock_decomp,'q2a') && isstruct(options_.plot_shock_decomp.q2a) + q2avec=options_.plot_shock_decomp.q2a; + if nvar>1 + for jv = 1:nvar + my_varlist = varlist(jv); + indv = strcmp(my_varlist,{q2avec.qname}); + options_.plot_shock_decomp.q2a = q2avec(indv); + plot_shock_decomposition(M_,oo_,options_,my_varlist); + end + return + else + indv = strcmp(varlist,{q2avec.qname}); + options_.plot_shock_decomp.q2a = q2avec(indv); + end +end % number of shocks nshocks = M_.exo_nbr; fig_name=''; +if isfield(options_.plot_shock_decomp,'diff') % private trap for uimenu calls + differentiate_decomp=options_.plot_shock_decomp.diff; +else + differentiate_decomp=0; +end +if isfield(options_.plot_shock_decomp,'flip') % private trap for uimenu calls + flip_decomp=options_.plot_shock_decomp.flip; +else + flip_decomp=0; +end if isfield(options_.plot_shock_decomp,'expand') % private trap for uimenu calls expand=options_.plot_shock_decomp.expand; else expand=0; options_.plot_shock_decomp.expand=0; end +if ~isfield(options_.plot_shock_decomp,'init_cond_decomp') + options_.plot_shock_decomp.init_cond_decomp=0; +end +options_.plot_shock_decomp.initval=0; if ~isempty(options_.plot_shock_decomp.fig_name) fig_name=[' ' options_.plot_shock_decomp.fig_name]; + if length(fig_name)>=8 && strcmp(fig_name(end-6:end),'initval') + options_.plot_shock_decomp.initval=1; + end end -type=options_.plot_shock_decomp.type; + detail_plot=options_.plot_shock_decomp.detail_plot; realtime_= options_.plot_shock_decomp.realtime; vintage_ = options_.plot_shock_decomp.vintage; @@ -138,10 +247,32 @@ switch realtime_ end end -if isfield(oo_.dr,'ys') - steady_state = oo_.dr.ys; + +if ~isempty(init2shocks) && ~expand + n=size(init2shocks,1); + M_.exo_names_init=M_.exo_names; + for i=1:n + j=strmatch(init2shocks{i}{1},M_.endo_names,'exact'); + if ~isempty(init2shocks{i}{2}) + jj=strmatch(init2shocks{i}{2},M_.exo_names,'exact'); + M_.exo_names_init{jj}=[M_.exo_names_init{jj} ' + ' M_.endo_names{j}]; + z(:,jj,:)= z(:,jj,:) + oo_.initval_decomposition (:,j,:); + else + z(:,end,:)= z(:,end,:) - oo_.initval_decomposition (:,j,:); + end + z(:,end-1,:)= z(:,end-1,:) - oo_.initval_decomposition (:,j,:); + + end +end + +if ~epilogue_decomp + if isfield(oo_.dr,'ys') + steady_state = oo_.dr.ys; + else + steady_state = oo_.steady_state; + end else - steady_state = oo_.steady_state; + steady_state = oo_.shock_decomposition_info.epilogue_steady_state; end if isequal(type,'aoa') && isstruct(q2a) @@ -159,8 +290,8 @@ if isequal(type,'aoa') && isstruct(q2a) if isempty(t0) error('the realtime decompositions are not stored in Q4! Please check your dates and settings.') end - if ~isfield(q2a,'var_type') % private trap for aoa calls - q2a.var_type=1; + if ~isfield(q2a,'type') % private trap for aoa calls + q2a.type=1; end if ~isfield(q2a,'islog') % private trap for aoa calls q2a.islog=0; @@ -177,7 +308,7 @@ if isequal(type,'aoa') && isstruct(q2a) if ~isfield(q2a,'plot') % private trap for aoa calls q2a.plot=1; % growth rate end - + if ~expand if options_.plot_shock_decomp.interactive && ~isempty(options_.plot_shock_decomp.use_shock_groups) mygroup = options_.plot_shock_decomp.use_shock_groups; @@ -195,6 +326,7 @@ end if ~expand fig_name = fig_name1; end + if options_.plot_shock_decomp.use_shock_groups fig_name=[fig_name ' group ' options_.plot_shock_decomp.use_shock_groups]; if expand @@ -209,16 +341,49 @@ if options_.plot_shock_decomp.use_shock_groups [z, shock_names, M_] = make_the_groups(z,gend,endo_nbr,nshocks,M_,options_); M_.endo_names = endo_names; M_.endo_names_tex = endo_names_tex; + else + % here we know we only have one variable to handle + if isstruct(q2a.aux) && ischar(q2a.aux.y) + steady_state_aux = get_mean(q2a.aux.y); + q2a.aux.y=repmat(steady_state_aux,16,1); + q2a.aux.yss=steady_state_aux; + end + [~, yssa, ~, gyssa] = ... + quarterly2annual(repmat(steady_state,16,1),steady_state,q2a.GYTREND0,q2a.type,q2a.islog,q2a.aux); + if q2a.plot==1 + steady_state = gyssa; + else + steady_state = yssa; + end end else gend = size(z,3); zfull = z; + endo_nbr = size(z,1); [z, shock_names, M_] = make_the_groups(z,gend,endo_nbr,nshocks,M_,options_); end + if ~isempty(init2shocks) && ~expand + M_.exo_names=M_.exo_names_init; + end else + if ~isempty(init2shocks) && ~expand + M_.exo_names=M_.exo_names_init; + end shock_names = M_.exo_names; end +if ~expand + if flip_decomp + fig_name=[fig_name ' flip']; + end + if differentiate_decomp + fig_name=[fig_name ' diff']; + end + if ~isempty(init2shocks) + fig_name=[fig_name ' init2shocks']; + end +end + func = @(x) colorspace('RGB->Lab',x); MAP = distinguishable_colors(size(z,2)-1,'w',func); % MAP = [MAP; MAP(end,:)]; @@ -229,6 +394,12 @@ if isempty(options_.plot_shock_decomp.colormap) options_.plot_shock_decomp.colormap = MAP; end +if differentiate_decomp + z(:,:,2:end) = z(:,:,2:end)-z(:,:,1:end-1); + z(:,:,1) = nan; + steady_state = steady_state*0; +end + switch type case '' % default @@ -261,14 +432,14 @@ switch type end if realtime_ == 0 t0=t0+4-1; % we start in Q4 of the first full year - end + end if isempty(options_.plot_shock_decomp.plot_init_date) && realtime_ == 0 options_.plot_shock_decomp.plot_init_date=initial_date+t0; end if isstruct(q2a) if realtime_ == 0 - if ~isfield(q2a,'var_type') % private trap for aoa calls - q2a.var_type=1; + if ~isfield(q2a,'type') % private trap for aoa calls + q2a.type=1; end if ~isfield(q2a,'islog') % private trap for aoa calls q2a.islog=0; @@ -287,32 +458,34 @@ switch type end if ~expand - if isstruct(q2a.aux) && ischar(q2a.aux.y) - opts=options_; - opts.plot_shock_decomp.type='qoq'; - [y_aux, steady_state_aux] = plot_shock_decomposition(M_,oo_,opts,q2a.aux.y); - q2a.aux.y=y_aux; - q2a.aux.yss=steady_state_aux; - end - [za, endo_names, endo_names_tex, steady_state, i_var, oo_] = ... - annualized_shock_decomposition(z,M_, options_, i_var, t0, options_.nobs, realtime_, vintage_, steady_state,q2a); + if isstruct(q2a.aux) && ischar(q2a.aux.y) + opts=options_; + opts.plot_shock_decomp.type='qoq'; + opts.plot_shock_decomp.use_shock_groups=[]; + [y_aux, steady_state_aux] = plot_shock_decomposition(M_,oo_,opts,q2a.aux.y); + q2a.aux.y=y_aux; + q2a.aux.yss=steady_state_aux; + end + i_var0 = i_var; + [za, endo_names, endo_names_tex, steady_state, i_var, oo_] = ... + annualized_shock_decomposition(z,M_, options_, i_var, t0, options_.nobs, realtime_, vintage_, steady_state,q2a); if options_.plot_shock_decomp.interactive && ~isempty(options_.plot_shock_decomp.use_shock_groups) mygroup = options_.plot_shock_decomp.use_shock_groups; options_.plot_shock_decomp.use_shock_groups=''; zafull = ... - annualized_shock_decomposition(z,M_, options_, i_var, t0, options_.nobs, realtime_, vintage_, steady_state,q2a); + annualized_shock_decomposition(zfull(i_var0,:,:),M_, options_, i_var, t0, options_.nobs, realtime_, vintage_, steady_state,q2a); options_.plot_shock_decomp.use_shock_groups = mygroup; end end end z = za; - if options_.plot_shock_decomp.interactive && ~isempty(options_.plot_shock_decomp.use_shock_groups) - zfull = zafull; - end + if options_.plot_shock_decomp.interactive && ~isempty(options_.plot_shock_decomp.use_shock_groups) + zfull = zafull; + end M_.endo_names = endo_names; M_.endo_names_tex = endo_names_tex; % endo_nbr = size(z,1); - if realtime_<2 + if realtime_<2 || vintage_ == 0 initial_date = initial_date1; else initial_date = initial_date0; @@ -337,12 +510,17 @@ switch type error('plot_shock_decomposition:: Wrong type') end + +if flip_decomp + z = -z; + steady_state = - steady_state; +end if steadystate options_.plot_shock_decomp.steady_state=steady_state; end -if nargout - z=z(i_var,:,:); +if nargout == 2 + out=z(i_var,:,:); steady_state = steady_state(i_var); return end @@ -356,7 +534,11 @@ if ~isempty(options_.plot_shock_decomp.plot_init_date) a = find((initial_date:initial_date+b-1)==options_.plot_shock_decomp.plot_init_date); end if ~isempty(options_.plot_shock_decomp.plot_end_date) - b = find((initial_date:initial_date+b-1)==options_.plot_shock_decomp.plot_end_date); + if options_.plot_shock_decomp.plot_end_date<=(max(initial_date:initial_date+b-1)) + b = find((initial_date:initial_date+b-1)==options_.plot_shock_decomp.plot_end_date); + else + warning('You set plot_end_date larger than smoother size!!'); + end end z = z(:,:,a:b); % end crop data @@ -366,10 +548,13 @@ options_.plot_shock_decomp.orig_varlist = varlist; if options_.plot_shock_decomp.interactive && ~isempty(options_.plot_shock_decomp.use_shock_groups) options_.plot_shock_decomp.zfull = zfull; end -if detail_plot - graph_decomp_detail(z, shock_names, M_.endo_names, i_var, my_initial_date, M_, options_) -else - graph_decomp(z, shock_names, M_.endo_names, i_var, my_initial_date, M_, options_); + +if ~options_.no_graph.plot_shock_decomposition + if detail_plot + graph_decomp_detail(z, shock_names, M_.endo_names, i_var, my_initial_date, M_, options_); + else + graph_decomp(z, shock_names, M_.endo_names, i_var, my_initial_date, M_, options_); + end end if write_xls @@ -384,18 +569,30 @@ shock_groups = M_.shock_groups.(options_.plot_shock_decomp.use_shock_groups); shock_ind = fieldnames(shock_groups); ngroups = length(shock_ind); shock_names = shock_ind; +shock_varexo = shock_ind; for i=1:ngroups shock_names{i} = (shock_groups.(shock_ind{i}).label); + if isfield(M_,'exo_names_init') + shock_varexo{i} = (shock_groups.(shock_ind{i}).shocks); + end end zz = zeros(endo_nbr,ngroups+2,gend); kcum=[]; for i=1:ngroups + indx=0; for j = shock_groups.(shock_ind{i}).shocks k = find(strcmp(j,cellstr(M_.exo_names))); + if isfield(M_,'exo_names_init') + indx=indx+1; + shock_varexo{i}{indx} = M_.exo_names_init{k}; + end zz(:,i,:) = zz(:,i,:) + z(:,k,:); z(:,k,:) = 0; kcum = [kcum k]; end + if isfield(M_,'exo_names_init') + shock_groups.(shock_ind{i}).shocks = shock_varexo{i}; + end end zothers = sum(z(:,1:nshocks,:),2); shock_groups.(['group' int2str(ngroups+1)]).label = 'Others'; diff --git a/matlab/posterior_analysis.m b/matlab/posterior_analysis.m index 0c8da9def..16088823d 100644 --- a/matlab/posterior_analysis.m +++ b/matlab/posterior_analysis.m @@ -72,9 +72,9 @@ switch type [observable_name_requested_vars,index_subset,index_observables]=intersect(vartan,options_.varobs,'stable'); end oo_ = variance_decomposition_ME_mc_analysis(SampleSize,'posterior',M_.dname,M_.fname,... - M_.exo_names,arg2,observable_name_requested_vars,arg1,options_.mh_conf_sig,oo_,options_); + M_.exo_names,arg2,observable_name_requested_vars,arg1,options_.mh_conf_sig,oo_,options_); end - end + end case 'correlation' if nargin==narg1 [nvar,vartan,NumberOfFiles] = ... @@ -92,9 +92,9 @@ switch type if ~all(M_.H==0) if strmatch(arg1,options_.varobs,'exact') oo_ = conditional_variance_decomposition_ME_mc_analysis(SampleSize,'posterior',M_.dname,M_.fname,... - arg3,M_.exo_names,arg2,vartan,arg1,options_.mh_conf_sig,oo_,options_); + arg3,M_.exo_names,arg2,vartan,arg1,options_.mh_conf_sig,oo_,options_); end - end + end otherwise disp('Not yet implemented') end diff --git a/matlab/posterior_sampler.m b/matlab/posterior_sampler.m index 62e8ccfe6..3fa23b3b7 100644 --- a/matlab/posterior_sampler.m +++ b/matlab/posterior_sampler.m @@ -117,7 +117,7 @@ end % User doesn't want to use parallel computing, or wants to compute a % single chain compute sequentially. -if isnumeric(options_.parallel) || (nblck-fblck)==0 +if isnumeric(options_.parallel) || (~isempty(fblck) && (nblck-fblck)==0) fout = posterior_sampler_core(localVars, fblck, nblck, 0); record = fout.record; % Parallel in Local or remote machine. @@ -142,6 +142,11 @@ else end % from where to get back results % NamFileOutput(1,:) = {[M_.dname,'/metropolis/'],'*.*'}; + if options_.mh_recover && isempty(fblck) + % here we just need to retrieve the output of the completed remote jobs + fblck=1; + options_.parallel_info.parallel_recover = 1; + end [fout, nBlockPerCPU, totCPU] = masterParallel(options_.parallel, fblck, nblck,NamFileInput,'posterior_sampler_core', localVars, globalVars, options_.parallel_info); for j=1:totCPU offset = sum(nBlockPerCPU(1:j-1))+fblck-1; @@ -151,7 +156,7 @@ else record.FunctionEvalPerIteration(offset+1:sum(nBlockPerCPU(1:j)))=fout(j).record.FunctionEvalPerIteration(offset+1:sum(nBlockPerCPU(1:j))); record.LastSeeds(offset+1:sum(nBlockPerCPU(1:j)))=fout(j).record.LastSeeds(offset+1:sum(nBlockPerCPU(1:j))); end - + options_.parallel_info.parallel_recover = 0; end irun = fout(1).irun; diff --git a/matlab/posterior_sampler_core.m b/matlab/posterior_sampler_core.m index b753391b4..7504fd132 100644 --- a/matlab/posterior_sampler_core.m +++ b/matlab/posterior_sampler_core.m @@ -86,6 +86,8 @@ oo_ = myinputs.oo_; if whoiam % initialize persistent variables in priordens() priordens(xparam1,bayestopt_.pshape,bayestopt_.p6,bayestopt_.p7, bayestopt_.p3,bayestopt_.p4,1); + % initialize persistent variables in prior_draw() + prior_draw(bayestopt_,options_.prior_trunc); end MetropolisFolder = CheckPath('metropolis',M_.dname); @@ -137,14 +139,37 @@ for curr_block = fblck:nblck % If the state set by master is incompatible with the slave, we only reseed set_dynare_seed(options_.DynareRandomStreams.seed+curr_block); end + mh_recover_flag=0; if (options_.load_mh_file~=0) && (fline(curr_block)>1) && OpenOldFile(curr_block) %load previous draws and likelihood load([BaseName '_mh' int2str(NewFile(curr_block)) '_blck' int2str(curr_block) '.mat']) x2 = [x2;zeros(InitSizeArray(curr_block)-fline(curr_block)+1,npar)]; logpo2 = [logpo2;zeros(InitSizeArray(curr_block)-fline(curr_block)+1,1)]; OpenOldFile(curr_block) = 0; else - x2 = zeros(InitSizeArray(curr_block),npar); - logpo2 = zeros(InitSizeArray(curr_block),1); + if options_.mh_recover && exist([BaseName '_mh_tmp_blck' int2str(curr_block) '.mat'],'file')==2 + load([BaseName '_mh_tmp_blck' int2str(curr_block) '.mat']); + draw_iter = size(neval_this_chain,2)+1; + draw_index_current_file = draw_iter; + feval_this_chain = sum(sum(neval_this_chain)); + feval_this_file = sum(sum(neval_this_chain)); + if feval_this_chain>draw_iter-1 + % non Metropolis type of sampler + accepted_draws_this_chain = draw_iter-1; + accepted_draws_this_file = draw_iter-1; + else + accepted_draws_this_chain = 0; + accepted_draws_this_file = 0; + end + mh_recover_flag=1; + set_dynare_random_generator_state(LastSeeds.(['file' int2str(NewFile(curr_block))]).Unifor, LastSeeds.(['file' int2str(NewFile(curr_block))]).Normal); + last_draw(curr_block,:)=x2(draw_iter-1,:); + last_posterior(curr_block)=logpo2(draw_iter-1); + + else + + x2 = zeros(InitSizeArray(curr_block),npar); + logpo2 = zeros(InitSizeArray(curr_block),1); + end end %Prepare waiting bars if whoiam @@ -158,13 +183,15 @@ for curr_block = fblck:nblck hh = dyn_waitbar(0,[bar_title ' (' int2str(curr_block) '/' int2str(options_.mh_nblck) ')...']); set(hh,'Name',bar_title); end - accepted_draws_this_chain = 0; - accepted_draws_this_file = 0; - feval_this_chain = 0; - feval_this_file = 0; - draw_index_current_file = fline(curr_block); %get location of first draw in current block - draw_iter = 1; - + if mh_recover_flag==0 + accepted_draws_this_chain = 0; + accepted_draws_this_file = 0; + feval_this_chain = 0; + feval_this_file = 0; + draw_iter = 1; + draw_index_current_file = fline(curr_block); %get location of first draw in current block + end + sampler_options.curr_block = curr_block; while draw_iter <= nruns(curr_block) [par, logpost, accepted, neval] = posterior_sampler_iteration(TargetFun, last_draw(curr_block,:), last_posterior(curr_block), sampler_options,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); @@ -173,6 +200,7 @@ for curr_block = fblck:nblck last_draw(curr_block,:) = par; logpo2(draw_index_current_file) = logpost; last_posterior(curr_block) = logpost; + neval_this_chain(:, draw_iter) = neval; feval_this_chain = feval_this_chain + sum(neval); feval_this_file = feval_this_file + sum(neval); accepted_draws_this_chain = accepted_draws_this_chain + accepted; @@ -187,7 +215,7 @@ for curr_block = fblck:nblck end if save_tmp_file [LastSeeds.(['file' int2str(NewFile(curr_block))]).Unifor, LastSeeds.(['file' int2str(NewFile(curr_block))]).Normal] = get_dynare_random_generator_state(); - save([BaseName '_mh_tmp_blck' int2str(curr_block) '.mat'],'x2','logpo2','LastSeeds'); + save([BaseName '_mh_tmp_blck' int2str(curr_block) '.mat'],'x2','logpo2','LastSeeds','neval_this_chain','accepted_draws_this_chain','accepted_draws_this_file','feval_this_chain','feval_this_file'); end end if (draw_index_current_file == InitSizeArray(curr_block)) || (draw_iter == nruns(curr_block)) % Now I save the simulations, either because the current file is full or the chain is done @@ -195,7 +223,7 @@ for curr_block = fblck:nblck if save_tmp_file delete([BaseName '_mh_tmp_blck' int2str(curr_block) '.mat']); end - save([BaseName '_mh' int2str(NewFile(curr_block)) '_blck' int2str(curr_block) '.mat'],'x2','logpo2','LastSeeds'); + save([BaseName '_mh' int2str(NewFile(curr_block)) '_blck' int2str(curr_block) '.mat'],'x2','logpo2','LastSeeds','accepted_draws_this_chain','accepted_draws_this_file','feval_this_chain','feval_this_file'); fidlog = fopen([MetropolisFolder '/metropolis.log'],'a'); fprintf(fidlog,['\n']); fprintf(fidlog,['%% Mh' int2str(NewFile(curr_block)) 'Blck' int2str(curr_block) ' (' datestr(now,0) ')\n']); @@ -238,16 +266,18 @@ for curr_block = fblck:nblck end draw_iter=draw_iter+1; draw_index_current_file = draw_index_current_file + 1; - end% End of the simulations for one mh-block. - record.AcceptanceRatio(curr_block) = accepted_draws_this_chain/(draw_iter-1); - record.FunctionEvalPerIteration(curr_block) = feval_this_chain/(draw_iter-1); + end % End of the simulations for one mh-block. dyn_waitbar_close(hh); - [record.LastSeeds(curr_block).Unifor, record.LastSeeds(curr_block).Normal] = get_dynare_random_generator_state(); + if nruns(curr_block) + record.AcceptanceRatio(curr_block) = accepted_draws_this_chain/(draw_iter-1); + record.FunctionEvalPerIteration(curr_block) = feval_this_chain/(draw_iter-1); + [record.LastSeeds(curr_block).Unifor, record.LastSeeds(curr_block).Normal] = get_dynare_random_generator_state(); + end OutputFileName(block_iter,:) = {[MetropolisFolder,filesep], [ModelName '_mh*_blck' int2str(curr_block) '.mat']}; -end% End of the loop over the mh-blocks. +end % End of the loop over the mh-blocks. myoutput.record = record; myoutput.irun = draw_index_current_file; myoutput.NewFile = NewFile; -myoutput.OutputFileName = OutputFileName; \ No newline at end of file +myoutput.OutputFileName = OutputFileName; diff --git a/matlab/posterior_sampler_initialization.m b/matlab/posterior_sampler_initialization.m index 364bf2b20..069985fa4 100644 --- a/matlab/posterior_sampler_initialization.m +++ b/matlab/posterior_sampler_initialization.m @@ -226,6 +226,7 @@ if ~options_.load_mh_file && ~options_.mh_recover record.LastLineNumber = AnticipatedNumberOfLinesInTheLastFile; record.MCMCConcludedSuccessfully = 0; record.MCMC_sampler=options_.posterior_sampler_options.posterior_sampling_method; + record.ProposalScaleVec=bayestopt_.jscale; fprintf('Ok!\n'); id = write_mh_history_file(MetropolisFolder, ModelName, record); disp(['Estimation::mcmc: Details about the MCMC are available in ' BaseName '_mh_history_' num2str(id) '.mat']) @@ -376,28 +377,30 @@ elseif options_.mh_recover ExpectedNumberOfMhFiles = ExpectedNumberOfMhFilesPerBlock*NumberOfBlocks; % How many mh files do we actually have ? AllMhFiles = dir([BaseName '_mh*_blck*.mat']); - TotalNumberOfMhFiles = length(AllMhFiles); + TotalNumberOfMhFiles = length(AllMhFiles)-length(dir([BaseName '_mh_tmp*_blck*.mat'])); % Quit if no crashed mcmc chain can be found as there are as many files as expected if (TotalNumberOfMhFiles==ExpectedNumberOfMhFiles) - disp('Estimation::mcmc: It appears that you don''t need to use the mh_recover option!') - disp(' You have to edit the mod file and remove the mh_recover option') - disp(' in the estimation command') - error('Estimation::mcmc: mh_recover option not required!') + if isnumeric(options_.parallel) + disp('Estimation::mcmc: It appears that you don''t need to use the mh_recover option!') + disp(' You have to edit the mod file and remove the mh_recover option') + disp(' in the estimation command') + error('Estimation::mcmc: mh_recover option not required!') + end end % 2. Something needs to be done; find out what % Count the number of saved mh files per block. NumberOfMhFilesPerBlock = zeros(NumberOfBlocks,1); for b = 1:NumberOfBlocks BlckMhFiles = dir([BaseName '_mh*_blck' int2str(b) '.mat']); - NumberOfMhFilesPerBlock(b) = length(BlckMhFiles); + NumberOfMhFilesPerBlock(b) = length(BlckMhFiles)-length(dir([BaseName '_mh_tmp*_blck' int2str(b) '.mat'])); end % Find FirstBlock (First block), an integer targeting the crashed mcmc chain. FirstBlock = 1; %initialize + FBlock = zeros(NumberOfBlocks,1); while FirstBlock <= NumberOfBlocks if NumberOfMhFilesPerBlock(FirstBlock) < ExpectedNumberOfMhFilesPerBlock disp(['Estimation::mcmc: Chain ' int2str(FirstBlock) ' is not complete!']) - break - % The mh_recover session will start from chain FirstBlock. + FBlock(FirstBlock)=1; else disp(['Estimation::mcmc: Chain ' int2str(FirstBlock) ' is complete!']) end @@ -406,51 +409,84 @@ elseif options_.mh_recover %% 3. Overwrite default settings for % How many mh-files are saved in this block? - NumberOfSavedMhFilesInTheCrashedBlck = NumberOfMhFilesPerBlock(FirstBlock); - ExistingDrawsInLastMCFile=0; %initialize: no MCMC draws of current MCMC are in file from last run - % Check whether last present file is a file included in the last MCMC run - if ~LastFileFullIndicator - if NumberOfSavedMhFilesInTheCrashedBlck==NewFile(FirstBlock) %only that last file exists, but no files from current MCMC - loaded_results=load([BaseName '_mh' int2str(NewFile(FirstBlock)) '_blck' int2str(FirstBlock) '.mat']); - %check whether that last file was filled - if size(loaded_results.x2,1)==MAX_nruns %file is full - NewFile(FirstBlock)=NewFile(FirstBlock)+1; %set first file to be created to next one - FirstLine(FirstBlock) = 1; %use first line of next file - ExistingDrawsInLastMCFile=MAX_nruns-record.MhDraws(end-1,3); - else - ExistingDrawsInLastMCFile=0; + ExistingDrawsInLastMCFile=zeros(NumberOfBlocks,1); %initialize: no MCMC draws of current MCMC are in file from last run + % Check whether last present file is a file included in the last MCMC run + + update_record=0; + for k=1:NumberOfBlocks + FirstBlock = k; + if FBlock(k) + NumberOfSavedMhFilesInTheCrashedBlck=NumberOfMhFilesPerBlock(k); + if ~LastFileFullIndicator + if NumberOfSavedMhFilesInTheCrashedBlck==NewFile(FirstBlock) %only that last file exists, but no files from current MCMC + loaded_results=load([BaseName '_mh' int2str(NewFile(FirstBlock)) '_blck' int2str(FirstBlock) '.mat']); + %check whether that last file was filled + if size(loaded_results.x2,1)==MAX_nruns %file is full + NewFile(FirstBlock)=NewFile(FirstBlock)+1; %set first file to be created to next one + FirstLine(FirstBlock) = 1; %use first line of next file + ExistingDrawsInLastMCFile(FirstBlock)=MAX_nruns-record.MhDraws(end-1,3); + else + ExistingDrawsInLastMCFile(FirstBlock)=0; + end + end + elseif LastFileFullIndicator + ExistingDrawsInLastMCFile(FirstBlock)=0; + if NumberOfSavedMhFilesInTheCrashedBlck==NewFile(FirstBlock) %only the last file exists, but no files from current MCMC + NewFile(FirstBlock)=NewFile(FirstBlock)+1; %set first file to be created to next one + end end - end - elseif LastFileFullIndicator - ExistingDrawsInLastMCFile=0; - if NumberOfSavedMhFilesInTheCrashedBlck==NewFile(FirstBlock) %only the last file exists, but no files from current MCMC - NewFile(FirstBlock)=NewFile(FirstBlock)+1; %set first file to be created to next one - end - end - % % Correct the number of saved mh files if the crashed Metropolis was not the first session (so - % % that NumberOfSavedMhFilesInTheCrashedBlck is the number of saved mh files in the crashed chain - % % of the current session). - % if OldMhExists - % NumberOfSavedMhFilesInTheCrashedBlck = NumberOfSavedMhFilesInTheCrashedBlck - LastFileNumberInThePreviousMh; - % end - % NumberOfSavedMhFiles = NumberOfSavedMhFilesInTheCrashedBlck+LastFileNumberInThePreviousMh; + % % Correct the number of saved mh files if the crashed Metropolis was not the first session (so + % % that NumberOfSavedMhFilesInTheCrashedBlck is the number of saved mh files in the crashed chain + % % of the current session). + % if OldMhExists + % NumberOfSavedMhFilesInTheCrashedBlck = NumberOfSavedMhFilesInTheCrashedBlck - LastFileNumberInThePreviousMh; + % end + % NumberOfSavedMhFiles = NumberOfSavedMhFilesInTheCrashedBlck+LastFileNumberInThePreviousMh; - % Correct initial conditions. - if NumberOfSavedMhFilesInTheCrashedBlck0 && NumberOfSavedMhFilesInTheCrashedBlck1 only for slice) +% accepted: share of proposed draws that were accepted +% neval: number of evaluations (>1 only for slice) % % SPECIAL REQUIREMENTS % none @@ -134,7 +134,7 @@ switch posterior_sampling_method else logpost = -inf; end - + if (logpost > -inf) %get ratio of proposal densities, required because proposal depends %on current mode via Hessian and is thus not symmetric anymore @@ -151,7 +151,7 @@ switch posterior_sampling_method last_posterior=logpost; accepted_draws_counter =accepted_draws_counter +1; else %no updating - %do nothing, keep old value + %do nothing, keep old value end end end diff --git a/matlab/print_info.m b/matlab/print_info.m index 1c06ed260..7fa109391 100644 --- a/matlab/print_info.m +++ b/matlab/print_info.m @@ -11,7 +11,7 @@ function print_info(info, noprint, DynareOptions) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2005-2019 Dynare Team +% Copyright (C) 2005-2020 Dynare Team % % This file is part of Dynare. % @@ -27,148 +27,7 @@ function print_info(info, noprint, DynareOptions) % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . - if ~noprint - switch info(1) - case 1 - error('The model doesn''t determine the current variables uniquely') - case 2 - error(['The generalized Schur (QZ) decomposition failed. ' ... - 'For more information, see the documentation for Lapack function dgges: info=' ... - int2str(info(2)) ', n=' int2str(info(3)) ... - '. You can also run model_diagnostics to get more information on what may cause this problem.']) - case 3 - error('Blanchard Kahn conditions are not satisfied: no stable equilibrium') - case 4 - error('Blanchard Kahn conditions are not satisfied: indeterminacy') - case 5 - error('Blanchard Kahn conditions are not satisfied: indeterminacy due to rank failure') - case 6 - error('The Jacobian matrix evaluated at the steady state contains elements that are not real or are infinite') - case 7 - error('One of the eigenvalues is close to 0/0 (the absolute value of numerator and denominator is smaller than %s!\n If you believe that the model has a unique solution you can try to reduce the value of qz_zero_threshold.',num2str(DynareOptions.qz_zero_threshold)) - case 8 - if size(info,2)>=2 - global M_; - disp_string = M_.param_names{info(2)}; - for ii=1:length(info)-2 - disp_string = [disp_string, ', ', M_.param_names{info(2+ii)}]; - end - error(['The Jacobian contains NaNs because the following parameters are NaN: ' disp_string]) - else - error('The Jacobian contains NaNs. For more information, use options_.debug.') - end - case 9 - error('k_order_pert was unable to compute the solution') - case 10 - error('The Jacobian of the dynamic model contains Inf. For more information, use options_.debug.') - case 11 - error('The Hessian of the dynamic model used for second order solutions must not contain Inf') - case 12 - error('The Hessian of the dynamic model used for second order solutions must not contain NaN') - case 19 - error('The steadystate file did not compute the steady state') - case 20 - if DynareOptions.linear - error(['Impossible to find the steady state. Either the model' ... - ' doesn''t have a steady state or there are an infinity of steady states.' ... - ' Check whether your model is truly linear or whether there is a mistake in linearization.']) - else - error(['Impossible to find the steady state. Either the model' ... - ' doesn''t have a steady state, there are an infinity of steady states,' ... - ' or the guess values are too far from the solution']) - end - case 21 - error('The steady state is complex') - case 22 - error('The steady state contains NaN or Inf') - case 23 - error('Some updated params are complex') - case 24 - error('Some updated params contain NaN or Inf') - case 25 - error('The solution to the static equations is not a steady state of the dynamic model: verify that the equations tagged by [static] and [dynamic] are consistent') - case 26 - error('The loglinearization of the model cannot be performed, because the steady state is not strictly positive.') - case 30 - error('Variance can''t be computed') - case 41 - error('one (many) parameter(s) do(es) not satisfy the lower bound'); - case 42 - error('one (many) parameter(s) do(es) not satisfy the upper bound'); - case 43 - error('Covariance matrix of structural shocks is not positive definite') - case 44 %DsgeLikelihood_hh / dsge_likelihood - error('The covariance matrix of the measurement errors is not positive definite.'); - case 45 %DsgeLikelihood_hh / dsge_likelihood - error('Likelihood is not a number (NaN) or a complex number'); - case 46 %DsgeLikelihood_hh / dsge_likelihood - error('Likelihood is a complex number'); - case 47 %DsgeLikelihood_hh / dsge_likelihood - error('Prior density is not a number (NaN)'); - case 48 %DsgeLikelihood_hh / dsge_likelihood - error('Prior density is a complex number'); - case 49 - error('The model violates one (many) endogenous prior restriction(s)') - case 50 - error('Likelihood is Inf') - case 51 - fprintf('\n The dsge_prior_weight is dsge_var=%5.4f, but must be at least %5.4f for the prior to be proper.\n',info(2),info(3)); - error('You are estimating a DSGE-VAR model, but the value of the dsge prior weight is too low!') - case 52 %dsge_var_likelihood - error('You are estimating a DSGE-VAR model, but the implied covariance matrix of the VAR''s innovations, based on artificial and actual sample is not positive definite!'); - case 53 %dsge_var_likelihood - error('You are estimating a DSGE-VAR model, but the implied covariance matrix of the VAR''s innovations, based on the artificial sample, is not positive definite!'); - case 55 - error('Fast Kalman filter only works with stationary models [lik_init=1] or stationary observables for non-stationary models [lik_init=3]') - case 61 %Discretionary policy - error('Discretionary policy: maximum number of iterations has been reached. Procedure failed.'); - case 62 - error('Discretionary policy: some eigenvalues greater than options_.qz_criterium. Model potentially unstable.'); - case 63 - error('Discretionary policy: NaN elements are present in the solution. Procedure failed.'); - case 71 - error('Calibrated covariance of the structural errors implies correlation larger than +-1.'); - case 72 - error('Calibrated covariance of the measurement errors implies correlation larger than +-1.'); - % Aim Code Conversions by convertAimCodeToInfo.m - case 81 - error(['Ramsey: The solution to the static first order conditions for optimal policy could not be found. Either the model' ... - ' doesn''t have a steady state, there are an infinity of steady states, ' ... - ' or the guess values are too far from the solution']); - case 82 - error('Ramsey: The steady state computation resulted in NaN in the static first order conditions for optimal policy'); - case 83 - error('Ramsey: The steady state computation resulted in NaN in the auxiliary equations for optimal policy'); - case 84 - error('Ramsey: The steady state file computation for the Ramsey problem resulted in NaNs at the initial values of the instruments'); - case 85 - error('Ramsey: The steady state file does not solve the static first order conditions conditional on the instruments.'); - case 86 - error('Ramsey: The steady state file provides complex numbers conditional on the instruments.'); - case 87 - error('Ramsey: The maximum number of iterations has been reached. Try increasing maxit.'); - case 102 - error('Aim: roots not correctly computed by real_schur'); - case 103 - error('Aim: too many explosive roots: no stable equilibrium'); - case 135 - error('Aim: too many explosive roots, and q(:,right) is singular'); - case 104 - error('Aim: too few explosive roots: indeterminacy'); - case 145 - error('Aim: too few explosive roots, and q(:,right) is singular'); - case 105 - error('Aim: q(:,right) is singular'); - case 161 - error('Aim: too many exact shiftrights'); - case 162 - error('Aim: too many numeric shiftrights'); - case 163 - error('Aim: A is NAN or INF.') - case 164 - error('Aim: Problem in SPEIG.') - otherwise - error('This case shouldn''t happen. Contact the authors of Dynare') - end -end + message = get_error_message(info, DynareOptions); + error(message); +end \ No newline at end of file diff --git a/matlab/print_moments_implied_prior.m b/matlab/print_moments_implied_prior.m index ebce7c15a..21a6d6a81 100644 --- a/matlab/print_moments_implied_prior.m +++ b/matlab/print_moments_implied_prior.m @@ -2,7 +2,7 @@ function print_moments_implied_prior(ModelInfo, mm, vm, mv, vv) %function print_moments_implied_prior(ModelInfo, mm, vm, mv, vv) % This routine prints in the command window some descriptive statistics % about the endogenous variables implied prior moments. -% Inputs: +% Inputs: % - ModelInfo [structure] Dynare's model structure % - mm [endo_nbr*1] mean first moments of the endogenous % variables diff --git a/matlab/prior_analysis.m b/matlab/prior_analysis.m index 564b8f4d1..0c945c3eb 100644 --- a/matlab/prior_analysis.m +++ b/matlab/prior_analysis.m @@ -81,9 +81,9 @@ switch type if ~all(M_.H==0) if strmatch(vartan(arg1,:),options_.varobs,'exact') oo_ = conditional_variance_decomposition_ME_mc_analysis(SampleSize,'prior',M_.dname,M_.fname,... - arg3,M_.exo_names,arg2,vartan,arg1,options_.mh_conf_sig,oo_,options_); + arg3,M_.exo_names,arg2,vartan,arg1,options_.mh_conf_sig,oo_,options_); end - end + end otherwise disp('Not yet implemented') end \ No newline at end of file diff --git a/matlab/prior_draw.m b/matlab/prior_draw.m index c97eaeefd..326029778 100644 --- a/matlab/prior_draw.m +++ b/matlab/prior_draw.m @@ -268,7 +268,7 @@ end %$ %$ if t(1) %$ t(2) = all(abs(m0-BayesInfo.p1)<3e-3); -%$ t(3) = all(all(abs(v0-diag(BayesInfo.p2.^2))<2e-3)); +%$ t(3) = all(all(abs(v0-diag(BayesInfo.p2.^2))<3e-3)); %$ end %$ T = all(t); -%@eof:1 \ No newline at end of file +%@eof:1 diff --git a/matlab/prior_posterior_statistics.m b/matlab/prior_posterior_statistics.m index 2c5bd93a5..3a638882d 100644 --- a/matlab/prior_posterior_statistics.m +++ b/matlab/prior_posterior_statistics.m @@ -19,7 +19,7 @@ function prior_posterior_statistics(type,dataset,dataset_info) % See the comments in the posterior_sampler.m funtion. -% Copyright (C) 2005-2018 Dynare Team +% Copyright (C) 2005-2020 Dynare Team % % This file is part of Dynare. % @@ -241,7 +241,7 @@ if isnumeric(options_.parallel) [fout] = prior_posterior_statistics_core(localVars,1,B,0); % Parallel execution! else - [nCPU, totCPU, nBlockPerCPU] = distributeJobs(options_.parallel, 1, B); + [~, totCPU, nBlockPerCPU] = distributeJobs(options_.parallel, 1, B); ifil=zeros(n_variables_to_fill,totCPU); for j=1:totCPU-1 if run_smoother @@ -294,7 +294,7 @@ else % which files have to be copied to run remotely NamFileInput(1,:) = {'',[M_.fname '.static.m']}; NamFileInput(2,:) = {'',[M_.fname '.dynamic.m']}; - if M.set_auxiliary_variables + if M_.set_auxiliary_variables NamFileInput(3,:) = {'',[M_.fname '.set_auxiliary_variables.m']}; end if options_.steadystate_flag diff --git a/matlab/prior_posterior_statistics_core.m b/matlab/prior_posterior_statistics_core.m index 7559b7c3c..5d74f2baa 100644 --- a/matlab/prior_posterior_statistics_core.m +++ b/matlab/prior_posterior_statistics_core.m @@ -30,7 +30,7 @@ function myoutput=prior_posterior_statistics_core(myinputs,fpar,B,whoiam, ThisMa % SPECIAL REQUIREMENTS. % None. -% Copyright (C) 2005-2017 Dynare Team +% Copyright (C) 2005-2020 Dynare Team % % This file is part of Dynare. % @@ -203,7 +203,7 @@ for b=fpar:B M_ = set_all_parameters(deep,estim_params_,M_); if run_smoother - [dr,info,M_,options_,oo_] = resol(0,M_,options_,oo_); + [dr,info,M_,options_,oo_] =compute_decision_rules(M_,options_,oo_); [alphahat,etahat,epsilonhat,alphatilde,SteadyState,trend_coeff,aK,~,~,P,~,~,trend_addition,state_uncertainty,M_,oo_,options_,bayestopt_] = ... DsgeSmoother(deep,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_); diff --git a/matlab/prodmom.m b/matlab/prodmom.m new file mode 100644 index 000000000..a6e28d667 --- /dev/null +++ b/matlab/prodmom.m @@ -0,0 +1,103 @@ +% +% prodmom.m Date: 4/29/2006 +% This Matlab program computes the product moment of X_{i_1}^{nu_1}X_{i_2}^{nu_2}...X_{i_m}^{nu_m}, +% where X_{i_j} are elements from X ~ N(0_n,V). +% V only needs to be positive semidefinite. +% V: variance-covariance matrix of X +% ii: vector of i_j +% nu: power of X_{i_j} +% Reference: Triantafyllopoulos (2003) On the Central Moments of the Multidimensional +% Gaussian Distribution, Mathematical Scientist +% Kotz, Balakrishnan, and Johnson (2000), Continuous Multivariate +% Distributions, Vol. 1, p.261 +% Note that there is a typo in Eq.(46.25), there should be an extra rho in front +% of the equation. +% Usage: prodmom(V,[i1 i2 ... ir],[nu1 nu2 ... nur]) +% Example: To get E[X_2X_4^3X_7^2], use prodmom(V,[2 4 7],[1 3 2]) +% +% Retrieved from http://www-2.rotman.utoronto.ca/~kan/papers/prodmom.zip +% This function is part of replication codes of the following paper: +% Kan, R.: "From moments of sum to moments of product." Journal of +% Multivariate Analysis, 2008, vol. 99, issue 3, pages 542-554. +% ========================================================================= +% Copyright (C) 2008-2015 Raymond Kan +% Copyright (C) 2019-2020 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 . +% ========================================================================= +function y = prodmom(V,ii,nu); +if nargin<3 + nu = ones(size(ii)); +end +s = sum(nu); +if s==0 + y = 1; + return +end +if rem(s,2)==1 + y = 0; + return +end +nuz = nu==0; +nu(nuz) = []; +ii(nuz) = []; +m = length(ii); +V = V(ii,ii); +s2 = s/2; +% +% Use univariate normal results +% +if m==1 + y = V^s2*prod([1:2:s-1]); + return +end +% +% Use bivariate normal results when there are only two distinct indices +% +if m==2 + rho = V(1,2)/sqrt(V(1,1)*V(2,2)); + y = V(1,1)^(nu(1)/2)*V(2,2)^(nu(2)/2)*bivmom(nu,rho); + return +end +% +% Regular case +% +[nu,inu] = sort(nu,2,'descend'); +V = V(inu,inu); % Extract only the relevant part of V +x = zeros(1,m); +V = V./2; +nu2 = nu./2; +p = 2; +q = nu2*V*nu2'; +y = 0; +for i=1:fix(prod(nu+1)/2) + y = y+p*q^s2; + for j=1:m + if x(j) +% Copyright (C) 2019-2020 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 . +% ========================================================================= +if nargin<3 + nu = ones(size(ii)); +end +s = sum(nu); +if s==0 + y = 1; + if nargout > 1 + dy = zeros(1,1,size(dV,3)); + end + return +end +if rem(s,2)==1 + y = 0; + if nargout > 1 + dy = zeros(1,1,size(dV,3)); + end + return +end +nuz = nu==0; +nu(nuz) = []; +ii(nuz) = []; +m = length(ii); +V = V(ii,ii); +if nargout > 1 + dV = dV(ii,ii,:); +end +s2 = s/2; +% +% Use univariate normal results +% +if m==1 + y = V^s2*prod([1:2:s-1]); + if nargout > 1 + dy = s2*V^(s2-1)*dV*prod([1:2:s-1]); + dy = reshape(dy,1,size(dV,3)); + end + return +end +% +% Use bivariate normal results when there are only two distinct indices +% +if m==2 + rho = V(1,2)/sqrt(V(1,1)*V(2,2)); + if nargout > 1 + drho = dC(ii(1),ii(2),:); + [tmp,dtmp] = bivmom(nu,rho); + dy = (nu(1)/2)*V(1,1)^(nu(1)/2-1)*dV(1,1,:) * V(2,2)^(nu(2)/2) * tmp... + + V(1,1)^(nu(1)/2) * (nu(2)/2)*V(2,2)^(nu(2)/2-1)*dV(2,2,:) * tmp... + + V(1,1)^(nu(1)/2) * V(2,2)^(nu(2)/2) * dtmp * drho; + dy = reshape(dy,1,size(dV,3)); + else + tmp = bivmom(nu,rho); + end + y = V(1,1)^(nu(1)/2)*V(2,2)^(nu(2)/2)*tmp; + return +end +% +% Regular case +% +[nu,inu] = sort(nu,2,'descend'); +V = V(inu,inu); % Extract only the relevant part of V +x = zeros(1,m); +V = V./2; +nu2 = nu./2; +p = 2; +q = nu2*V*nu2'; +y = 0; +if nargout > 1 + dV = dV(inu,inu,:); % Extract only the relevant part of dV + dV = dV./2; + %dq = nu2*dV*nu2'; + %dq = multiprod(multiprod(nu2,dV),nu2'); + dq = NaN(size(q,1), size(q,2), size(dV,3)); + for jp = 1:size(dV,3) + dq(:,:,jp) = nu2*dV(:,:,jp)*nu2'; + end + dy = 0; +end +for i=1:fix(prod(nu+1)/2) + y = y+p*q^s2; + if nargout > 1 + dy = dy+p*s2*q^(s2-1)*dq; + end + for j=1:m + if x(j) 1 + %dq = dq-2*(nu2-x)*dV(:,j,:)-dV(j,j,:); + %dq = dq-2*multiprod((nu2-x),dV(:,j,:))-dV(j,j,:); + for jp=1:size(dV,3) + dq(:,:,jp) = dq(:,:,jp)-2*(nu2-x)*dV(:,j,jp)-dV(j,j,jp); + end + end + break + else + x(j) = 0; + if rem(nu(j),2)==1 + p = -p; + end + if nargout > 1 + %dq = dq+2*nu(j)*multiprod((nu2-x),dV(:,j,:))-nu(j)^2*dV(j,j,:); + for jp=1:size(dV,3) + dq(:,:,jp) = dq(:,:,jp)+2*nu(j)*(nu2-x)*dV(:,j,jp)-nu(j)^2*dV(j,j,jp); + end + end + q = q+2*nu(j)*(nu2-x)*V(:,j)-nu(j)^2*V(j,j); + end + end +end +y = y/prod([1:s2]); +if nargout > 1 + dy = dy/prod([1:s2]); + dy = reshape(dy,1,size(dV,3)); +end \ No newline at end of file diff --git a/matlab/pruned_state_space_system.m b/matlab/pruned_state_space_system.m new file mode 100644 index 000000000..df5cf5ab4 --- /dev/null +++ b/matlab/pruned_state_space_system.m @@ -0,0 +1,1219 @@ +function pruned_state_space = pruned_state_space_system(M, options, dr, indy, nlags, useautocorr, compute_derivs) +% Set up the pruned state space ABCD representation: +% z = c + A*z(-1) + B*inov +% y = ys + d + C*z(-1) + D*inov +% References: +% - Andreasen, Martin M., Jesús Fernández-Villaverde and Juan F. Rubio-Ramírez (2018): +% "The Pruned State-Space System for Non-Linear DSGE Models: Theory and Empirical Applications", +% Review of Economic Studies, Volume 85, Issue 1, Pages 1–49. +% - Mutschler, Willi (2018): "Higher-order statistics for DSGE models", +% Econometrics and Statistics, Volume 6, Pages 44-56. +% ========================================================================= +% INPUTS +% M: [structure] storing the model information +% options: [structure] storing the options +% dr: [structure] storing the results from perturbation approximation +% indy: [vector] index of control variables in DR order +% nlags: [integer] number of lags in autocovariances and autocorrelations +% useautocorr: [boolean] true: compute autocorrelations +% ------------------------------------------------------------------------- +% OUTPUTS +% pruned_state_space: [structure] with the following fields: +% indx: [x_nbr by 1] +% index of state variables +% indy: [y_nbr by 1] +% index of control variables +% A: [z_nbr by z_nbr] +% state space transition matrix A mapping previous states to current states +% B: [z_nbr by inov_nbr] +% state space transition matrix B mapping current inovations to current states +% c: [z_nbr by 1] +% state space transition matrix c mapping constants to current states +% C: [y_nbr by z_nbr] +% state space measurement matrix C mapping previous states to current controls +% D: [y_nbr by inov_nbr] +% state space measurement matrix D mapping current inovations to current controls +% d: [y_nbr by 1] +% state space measurement matrix d mapping constants to current controls +% Var_inov [inov_nbr by inov_nbr] +% contemporenous covariance matrix of innovations, i.e. E[inov*inov'] +% Var_z [z_nbr by z_nbr] +% contemporenous covariance matrix of states z +% Var_y [y_nbr by y_nbr] +% contemporenous covariance matrix of controls y +% Var_yi [y_nbr by y_nbr by nlags] +% autocovariance matrix of controls y +% Corr_y [y_nbr by y_nbr] +% contemporenous correlation matrix of controls y +% Corr_yi [y_nbr by y_nbr by nlags] +% autocorrelation matrix of controls y +% E_y [y_nbr by 1] +% unconditional theoretical mean of control variables y +% +% if compute_derivs == 1, then the following additional fields are outputed: +% dA: [z_nbr by z_nbr by totparam_nbr] +% parameter Jacobian of A +% dB: [z_nbr by inov_nbr by totparam_nbr] +% parameter Jacobian of B +% dc: [z_nbr by totparam_nbr] +% parameter Jacobian of c +% dC: [y_nbr by z_nbr by totparam_nbr] +% parameter Jacobian of C +% dD: [y_nbr by inov_nbr by totparam_nbr] +% parameter Jacobian of D +% dd: [y_nbr by totparam_nbr] +% parameter Jacobian of d +% dVar_inov [inov_nbr by inov_nbr by totparam_nbr] +% parameter Jacobian of Var_inov +% dVar_z [z_nbr by z_nbr by totparam_nbr] +% parameter Jacobian of Var_z +% dVar_y [y_nbr by y_nbr by totparam_nbr] +% parameter Jacobian of Var_y +% dVar_yi [y_nbr by y_nbr by nlags by totparam_nbr] +% parameter Jacobian of Var_yi +% dCorr_y [y_nbr by y_nbr by totparam_nbr] +% parameter Jacobian of Corr_y +% dCorr_yi [y_nbr by y_nbr by nlags by totparam_nbr] +% parameter Jacobian of Corr_yi +% dE_y [y_nbr by totparam_nbr] +% parameter Jacobian of E_y +% ------------------------------------------------------------------------- +% This function is called by +% * get_identification_jacobians.m +% * identification_numerical_objective.m +% ------------------------------------------------------------------------- +% This function calls +% * allVL1.m +% * commutation.m +% * disclyap_fast.m +% * duplication.m +% * lyapunov_symm.m +% * prodmom +% * prodmom_deriv +% * Q6_plication +% * quadruplication.m +% * vec.m +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= + +%% MAIN IDEA: +% Decompose the state vector x into first-order effects xf, second-order +% effects xs, and third-order effects xrd, i.e. x=xf+xs+xrd. Then, Dynare's +% perturbation approximation for the state vector up to third order +% (with Gaussian innovations u, i.e. no odd moments, hxxs=huus=hxus=hsss=0) is: +% x = hx*( xf(-1)+xs(-1)+xrd(-1) ) +% + hu*u +% + 1/2*hxx*kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) +% + hxu*kron( xf(-1)+xs(-1)+xrd(-1) , u ) +% + 1/2*huu*kron( u , u ) +% + 1/2*hss*sig^2 +% + 1/6*hxxx*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , xf(-1)+xs(-1)+xrd(-1) ) +% + 1/6*huuu*kron( kron( u , u ) , u ) +% + 3/6*hxxu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , u ) +% + 3/6*hxuu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , u ) , u) +% + 3/6*hxss*( xf(-1)+xs(-1)+xrd(-1) )*sig^2 +% + 3/6*huss*u*sig^2 +% where: +% hx = dr.ghx(indx,:); hu = dr.ghu(indx,:); +% hxx = dr.ghxx(indx,:); hxu = dr.ghxu(indx,:); huu = dr.ghuu(indx,:); hss = dr.ghs2(indx,:); +% hxxx = dr.ghxxx(indx,:); huuu = dr.ghuuu(indx,:); hxxu = dr.ghxxu(indx,:); hxuu = dr.ghxxu(indx,:); hxss = dr.ghxss(indx,:); huss = dr.ghuss(indx,:); +% and similarly for control variables: +% y = gx*( xf(-1)+xs(-1)+xrd(-1) ) +% + gu*u +% + 1/2*gxx*kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) +% + gxu*kron( xf(-1)+xs(-1)+xrd(-1) , u ) +% + 1/2*guu*kron( u , u ) +% + 1/2*gss*sig^2 +% + 1/6*gxxx*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , xf(-1)+xs(-1)+xrd(-1) ) +% + 1/6*guuu*kron( kron( u , u ) , u ) +% + 3/6*gxxu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , u ) +% + 3/6*gxuu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , u ) , u) +% + 3/6*gxss*( xf(-1)+xs(-1)+xrd(-1) )*sig^2 +% + 3/6*guss*u*sig^2 +% where: +% gx = dr.ghx(indy,:); gu = dr.ghu(indy,:); +% gxx = dr.ghxx(indy,:); gxu = dr.ghxu(indy,:); guu = dr.ghuu(indy,:); gss = dr.ghs2(indy,:); +% gxxx = dr.ghxxx(indy,:); guuu = dr.ghuuu(indy,:); gxxu = dr.ghxxu(indy,:); gxuu = dr.ghxxu(indy,:); gxss = dr.ghxss(indy,:); guss = dr.ghuss(indy,:); +% +% PRUNING means getting rid of terms higher than the approximation order, i.e. +% - involving fourth-order effects: kron(xf,xrd), kron(xs,xs), kron(xrd,xf), kron(xrd,u), +% kron(kron(xf,xf),xs), kron(kron(xf,xs),xf), kron(kron(xs,xf),xf) +% kron(kron(xf,xs),u), kron(kron(xs,xf),u) +% kron(kron(xs,u),u) +% xs*sig^2 +% - involving fifth-order effects: kron(xs,xrd), kron(xrd,xs), +% kron(kron(xf,xf),xrd), kron(kron(xf,xs),xs), kron(kron(xf,xrd),xf), kron(kron(xs,xf),xs), kron(kron(xs,xs),xf), kron(kron(xrd,xf),xf) +% kron(kron(xf,xrd),u), kron(kron(xs,xs),u), kron(kron(xrd,xf),u) +% kron(kron(xrd,u),u) +% xrd*sig^2 +% - involving sixth-order effects: kron(xrd,xrd), +% kron(kron(xf,xs),xrd), kron(kron(xf,xrd),xs), kron(kron(xs,xrd),xrd), kron(kron(xs,xs),xs), kron(kron(xs,xrd),xf), kron(kron(xf,xf),xs), kron(kron(xrd,xs),xf) +% kron(kron(xs,xrd),u), kron(kron(xrd,xs),u) +% - involving seventh-order effects: kron(kron(xf,xrd),xrd), kron(kron(xs,xs),xrd), kron(kron(xs,xrd),xs), kron(kron(xrd,xf),xrd), kron(kron(xrd,xs),xs), kron(kron(xrd,xrd),xf) +% kron(kron(xrd,xrd),u) +% - involving eighth-order effects: kron(kron(xs,xrd),xrd), kron(kron(xrd,xs),xrd), kron(kron(xrd,xrd),xs) +% - involving ninth-order effects: kron(kron(xrd,xrd),xrd) +% Note that u is treated as a first-order effect and the perturbation parameter sig as a variable. +% +% SUMMARY OF LAW OF MOTIONS: Set up the law of motions for the individual effects, but keep only effects of same order +% Notation: I_n=eye(n) and K_m_n=commutation(m,n) +% +% First-order effects: keep xf and u +% xf = hx*xf(-1) + hu*u +% Note that we +% +% Second-order effects: keep xs, kron(xf,xf), kron(u,u), kron(xf,u), and sig^2 +% xs = hx*xs(-1) + 1/2*hxx*kron(xf(-1),xf(-1)) + 1/2*huu*(kron(u,u)-Sigma_e(:)+Sigma_e(:)) + hxu*kron(xf(-1),u) + 1/2*hss*sig^2% +% +% Third-order effects: keep xrd, kron(xf,xs), kron(xs,xf), kron(xs,u), kron(kron(xf,xf),xf), kron(kron(u,u),u), kron(kron(xf,xf),u), kron(kron(xf,u),u), xf*sig^2, u*sig^2 +% xrd = hx*xrd(-1) + 1/2*hxx*(kron(xf(-1),xs(-1))+kron(xs(-1),xf(-1))) + hxu*kron(xs(-1),u) + 1/6*hxxx*kron(xf(-1),kron(xf(-1),xf(-1))) + 1/6*huuu*kron(u,kron(u,u)) + 3/6*hxxu*kron(xf(-1),kron(xf(-1),u)) + 3/6*hxuu*kron(xf(-1),kron(u,u)) + 3/6*hxss*xf(-1)*sig^2 + 3/6*huss*u*sig^2 +% Simplified (due to symmetry in hxx): +% xrd = hx*xrd(-1) + hxx*(kron(xf(-1),xs(-1)) + hxu*kron(xs(-1),u) + 1/6*hxxx*kron(xf(-1),kron(xf(-1),xf(-1))) + 1/6*huuu*kron(u,kron(u,u)) + 3/6*hxxu*kron(xf(-1),kron(xf(-1),u)) + 3/6*hxuu*kron(xf(-1),kron(u,u)) + 3/6*hxss*xf(-1)*sig^2 + 3/6*huss*u*sig^2% +% +% Auxiliary equation kron(xf,xf) to set up the VAR(1) pruned state space system +% kron(xf,xf) = kron(hx,hx)*kron(xf(-1),xf(-1)) + kron(hu,hu)*(kron(u,u)-Sigma_e(:)+Sigma_e(:)) + kron(hx,u)*kron(xf(-1),u) + kron(u,hx)*kron(u,xf(-1)) +% Simplified using commutation matrix: +% kron(xf,xf) = kron(hx,hx)*kron(xf(-1),xf(-1)) + (I_xx+K_x_x)*kron(hx,hu)*kron(xf(-1),u) + kron(hu,hu)*kron(u,u) +% +% Auxiliary equation kron(xf,xs) to set up the VAR(1) pruned state space system +% kron(xf,xs) = kron(hx,hx)*kron(xf(-1),xs(-1)) + kron(hu,hx)*kron(u,xs(-1)) +% + kron(hx,1/2*hxx)*kron(kron(xf(-1),xf(-1)),xf(-1)) + kron(hu,1/2*hxx)*kron(kron(u,xf(-1)),xf(-1)) +% + kron(hx,1/2*huu)*kron(kron(xf(-1),u),u) + kron(hu,1/2*huu)*kron(kron(u,u),u) +% + kron(hx,hxu)*kron(kron(xf(-1),xf(-1)),u) + kron(hu,hxu)*kron(kron(u,xf(-1)),u) +% + kron(hx,1/2*hss)*xf(-1)*sig^2 + kron(hu,1/2*hss)*u*sig^2 +% Simplified using commutation matrix: +% kron(xf,xs) = kron(hx,hx)*kron(xf(-1),xs(-1)) +% + K_x_x*kron(hx,hu)*kron(xs(-1),u) +% + kron(hx,1/2*hxx)*kron(kron(xf(-1),xf(-1)),xf(-1)) +% + ( kron(hx,hxu) + K_x_x*kron(1/2*hxx,hu) )*kron(kron(xf(-1),xf(-1)),u) +% + ( kron(hx,1/2*huu) + K_x_x*kron(hxu,hu) )*kron(kron(xf(-1),u),u) +% + kron(hu,1/2*huu)*kron(kron(u,u),u) +% + kron(hx,1/2*hss)*xf(-1)*sig^2 +% + kron(hu,1/2*hss)*u*sig^2 +% +% Auxiliary equation kron(kron(xf,xf),xf) to set up the VAR(1) pruned state space system +% kron(kron(xf,xf),xf) = kron(kron(hx,hx),hx)*kron(kron(xf(-1),xf(-1)),xf(-1)) +% + kron(kron(hx,hu),hx)*kron(kron(xf(-1),u),xf(-1)) +% + kron(kron(hx,hx),hu)*kron(kron(xf(-1),xf(-1)),u) +% + kron(kron(hx,hu),hu)*kron(kron(xf(-1),u),u) +% + kron(kron(hu,hx),hx)*kron(kron(u,xf(-1)),xf(-1)) +% + kron(kron(hu,hu),hx)*kron(kron(u,u),xf(-1)) +% + kron(kron(hu,hx),hu)*kron(kron(u,xf(-1)),u) +% + kron(kron(hu,hu),hu)*kron(kron(u,u),u) +% Simplified using commutation matrix: +% kron(kron(xf,xf),xf) = kron(kron(hx,hx),hx)*kron(kron(xf(-1),xf(-1)),xf(-1)) +% + ( kron(kron(hx,hx),hu) + K_xx_x*kron(hx,(I_xx+K_x_x)*kron(hx,hu)) )*kron(kron(xf(-1),xf(-1)),u) +% + ( kron((I_xx+K_x_x)*kron(hx,hu),hu) + K_xx_x*kron(kron(hx,hu),hu) )*kron(kron(xf(-1),u),u) +% + kron(kron(hu,hu),hu)*kron(kron(u,u),u) +% +% Law of motion for control variables y (either VAROBS variables or if no VAROBS statement is given then for all endogenous variables) +% y = steady_state(y) +% + gx*( xf(-1)+xs(-1)+xrd(-1) ) +% + gu*u +% + 1/2*gxx*kron(xf(-1),xf(-1)) + gxx*kron(xf(-1),xs(-1)) +% + gxu*kron(xf(-1),u) + gxu*kron(xs(-1),u) +% + 1/2*guu*(kron(u,u)-Sigma_e+Sigma_e) +% + 1/2*gss*sig^2 +% + 1/6*gxxx*kron(kron(xf(-1),xf(-1)),xf(-1)) +% + 1/6*guuu*kron(kron(u,u),u) +% + 3/6*gxxu*kron(kron(xf(-1),xf(-1),u) +% + 3/6*gxuu*kron(kron(xf(-1),u),u) +% + 3/6*gxss*xf(-1)*sig^2 +% + 3/6*guss*u*sig^2 +% +% See code below how z and inov are defined at first, second, and third order, +% and how to set up A, B, C, D and compute unconditional first and second moments of inov, z and y + + +%% Auxiliary indices and objects +order = options.order; +if isempty(options.qz_criterium) + % set default value for qz_criterium: if there are no unit roots one can use 1.0 + % If they are possible, you may have have multiple unit roots and the accuracy + % decreases when computing the eigenvalues in lyapunov_symm. Hence, we normally use 1+1e-6 + % Note that unit roots are only possible at first-order, at higher order we set it to 1 + options.qz_criterium = 1+1e-6; +end +indx = [M.nstatic+(1:M.nspred) M.endo_nbr+(1:size(dr.ghx,2)-M.nspred)]'; +if isempty(indy) + indy = (1:M.endo_nbr)'; %by default select all variables in DR order +end +u_nbr = M.exo_nbr; +x_nbr = length(indx); +y_nbr = length(indy); +Yss = dr.ys(dr.order_var); +hx = dr.ghx(indx,:); +gx = dr.ghx(indy,:); +hu = dr.ghu(indx,:); +gu = dr.ghu(indy,:); +E_uu = M.Sigma_e; %this is E[u*u'] + +if compute_derivs + stderrparam_nbr = length(dr.derivs.indpstderr); + corrparam_nbr = size(dr.derivs.indpcorr,1); + modparam_nbr = length(dr.derivs.indpmodel); + totparam_nbr = stderrparam_nbr+corrparam_nbr+modparam_nbr; + dYss = dr.derivs.dYss; + dhx = dr.derivs.dghx(indx,:,:); + dgx = dr.derivs.dghx(indy,:,:); + dhu = dr.derivs.dghu(indx,:,:); + dgu = dr.derivs.dghu(indy,:,:); + dE_uu = dr.derivs.dSigma_e; +end + +% first-order approximation indices for extended state vector z and extended innovations vector inov +id_z1_xf = (1:x_nbr); +id_inov1_u = (1:u_nbr); +if order > 1 + % second-order approximation indices for extended state vector z and extended innovations vector inov + id_z2_xs = id_z1_xf(end) + (1:x_nbr); + id_z3_xf_xf = id_z2_xs(end) + (1:x_nbr*x_nbr); + id_inov2_u_u = id_inov1_u(end) + (1:u_nbr*u_nbr); + id_inov3_xf_u = id_inov2_u_u(end) + (1:x_nbr*u_nbr); + + hxx = dr.ghxx(indx,:); + gxx = dr.ghxx(indy,:); + hxu = dr.ghxu(indx,:); + gxu = dr.ghxu(indy,:); + huu = dr.ghuu(indx,:); + guu = dr.ghuu(indy,:); + hss = dr.ghs2(indx,:); + gss = dr.ghs2(indy,:); + if compute_derivs + dhxx = dr.derivs.dghxx(indx,:,:); + dgxx = dr.derivs.dghxx(indy,:,:); + dhxu = dr.derivs.dghxu(indx,:,:); + dgxu = dr.derivs.dghxu(indy,:,:); + dhuu = dr.derivs.dghuu(indx,:,:); + dguu = dr.derivs.dghuu(indy,:,:); + dhss = dr.derivs.dghs2(indx,:); + dgss = dr.derivs.dghs2(indy,:); + end +end +if order > 2 + % third-order approximation indices for extended state vector z and extended innovations vector inov + id_z4_xrd = id_z3_xf_xf(end) + (1:x_nbr); + id_z5_xf_xs = id_z4_xrd(end) + (1:x_nbr*x_nbr); + id_z6_xf_xf_xf = id_z5_xf_xs(end) + (1:x_nbr*x_nbr*x_nbr); + id_inov4_xs_u = id_inov3_xf_u(end) + (1:x_nbr*u_nbr); + id_inov5_xf_xf_u = id_inov4_xs_u(end) + (1:x_nbr*x_nbr*u_nbr); + id_inov6_xf_u_u = id_inov5_xf_xf_u(end) + (1:x_nbr*u_nbr*u_nbr); + id_inov7_u_u_u = id_inov6_xf_u_u(end) + (1:u_nbr*u_nbr*u_nbr); + + hxxx = dr.ghxxx(indx,:); + gxxx = dr.ghxxx(indy,:); + hxxu = dr.ghxxu(indx,:); + gxxu = dr.ghxxu(indy,:); + hxuu = dr.ghxuu(indx,:); + gxuu = dr.ghxuu(indy,:); + huuu = dr.ghuuu(indx,:); + guuu = dr.ghuuu(indy,:); + hxss = dr.ghxss(indx,:); + gxss = dr.ghxss(indy,:); + huss = dr.ghuss(indx,:); + guss = dr.ghuss(indy,:); + if compute_derivs + dhxxx = dr.derivs.dghxxx(indx,:,:); + dgxxx = dr.derivs.dghxxx(indy,:,:); + dhxxu = dr.derivs.dghxxu(indx,:,:); + dgxxu = dr.derivs.dghxxu(indy,:,:); + dhxuu = dr.derivs.dghxuu(indx,:,:); + dgxuu = dr.derivs.dghxuu(indy,:,:); + dhuuu = dr.derivs.dghuuu(indx,:,:); + dguuu = dr.derivs.dghuuu(indy,:,:); + dhxss = dr.derivs.dghxss(indx,:,:); + dgxss = dr.derivs.dghxss(indy,:,:); + dhuss = dr.derivs.dghuss(indx,:,:); + dguss = dr.derivs.dghuss(indy,:,:); + end +end + +%% First-order state space system +% Auxiliary state vector z is defined by: z = [xf] +% Auxiliary innovations vector inov is defined by: inov = [u] +z_nbr = x_nbr; +inov_nbr = M.exo_nbr; +A = hx; +B = hu; +c = zeros(x_nbr,1); +C = gx; +D = gu; +d = zeros(y_nbr,1); +Varinov = E_uu; +E_inovzlag1 = zeros(inov_nbr,z_nbr); %at first-order E[inov*z(-1)'] = 0 +Om_z = B*Varinov*B'; +E_xf = zeros(x_nbr,1); + +lyapunov_symm_method = 1; %method=1 to initialize persistent variables +[Var_z,Schur_u] = lyapunov_symm(A, Om_z,... %at first-order this algorithm is well established and also used in th_autocovariances.m + options.lyapunov_fixed_point_tol, options.qz_criterium, options.lyapunov_complex_threshold,... + lyapunov_symm_method,... + options.debug); %we use Schur_u to take care of (possible) nonstationary VAROBS variables in moment computations +%find stationary vars +stationary_vars = (1:y_nbr)'; +if ~isempty(Schur_u) + %base this only on first order, because if first-order is stable so are the higher-order pruned systems + x = abs(gx*Schur_u); + stationary_vars = find(all(x < options.Schur_vec_tol,2)); +end + +if compute_derivs == 1 + dA = dhx; + dB = dhu; + dc = zeros(x_nbr,totparam_nbr); + dC = dgx; + dD = dgu; + dd = zeros(y_nbr,totparam_nbr); + dVarinov = dE_uu; + dE_xf = zeros(x_nbr,totparam_nbr); + dE_inovzlag1 = zeros(z_nbr,inov_nbr,totparam_nbr); + dVar_z = zeros(z_nbr,z_nbr,totparam_nbr); + lyapunov_symm_method = 2;%to spare a lot of computing time while not repeating Schur every time + for jp1 = 1:totparam_nbr + if jp1 <= stderrparam_nbr+corrparam_nbr + dOm_z_jp1 = B*dVarinov(:,:,jp1)*B'; + dVar_z(:,:,jp1) = lyapunov_symm(A, dOm_z_jp1,... + options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,... + lyapunov_symm_method,... + options.debug); + else + dOm_z_jp1 = dB(:,:,jp1)*Varinov*B' + B*Varinov*dB(:,:,jp1)'; + dVar_z(:,:,jp1) = lyapunov_symm(A, dA(:,:,jp1)*Var_z*A' + A*Var_z*dA(:,:,jp1)' + dOm_z_jp1,... + options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,... + lyapunov_symm_method,... + options.debug); + end + end +end + +if order > 1 + options.qz_criterium = 1; %pruned state space has no unit roots + % Some common and useful objects for order > 1 + E_xfxf = Var_z; + if compute_derivs + dE_xfxf = dVar_z; + end + hx_hx = kron(hx,hx); + hx_hu = kron(hx,hu); + hu_hu = kron(hu,hu); + I_xx = eye(x_nbr^2); + K_x_x = commutation(x_nbr,x_nbr,1); + invIx_hx = (eye(x_nbr)-hx)\eye(x_nbr); + + %Compute unique fourth order product moments of u, i.e. unique(E[kron(kron(kron(u,u),u),u)],'stable') + u_nbr4 = u_nbr*(u_nbr+1)/2*(u_nbr+2)/3*(u_nbr+3)/4; + QPu = quadruplication(u_nbr); + COMBOS4 = flipud(allVL1(u_nbr, 4)); %all possible (unique) combinations of powers that sum up to four + E_u_u_u_u = zeros(u_nbr4,1); %only unique entries + if compute_derivs && (stderrparam_nbr+corrparam_nbr>0) + dE_u_u_u_u = zeros(u_nbr4,stderrparam_nbr+corrparam_nbr); + end + for j4 = 1:size(COMBOS4,1) + if compute_derivs && (stderrparam_nbr+corrparam_nbr>0) + [E_u_u_u_u(j4), dE_u_u_u_u(j4,:)] = prodmom_deriv(E_uu, 1:u_nbr, COMBOS4(j4,:), dE_uu(:,:,1:(stderrparam_nbr+corrparam_nbr)), dr.derivs.dCorrelation_matrix(:,:,1:(stderrparam_nbr+corrparam_nbr))); + else + E_u_u_u_u(j4) = prodmom(E_uu, 1:u_nbr, COMBOS4(j4,:)); + end + end + E_xfxf_uu = kron(E_xfxf,E_uu'); + +%% Second-order pruned state space system +% Auxiliary state vector z is defined by: z = [xf;xs;kron(xf,xf)] +% Auxiliary innovations vector inov is defined by: inov = [u;kron(u,u)-E_uu(:);kron(xf,u)] + z_nbr = x_nbr + x_nbr + x_nbr^2; + inov_nbr = u_nbr + u_nbr^2 + x_nbr*u_nbr; + + A = zeros(z_nbr, z_nbr); + A(id_z1_xf , id_z1_xf ) = hx; + A(id_z2_xs , id_z2_xs ) = hx; + A(id_z2_xs , id_z3_xf_xf) = 1/2*hxx; + A(id_z3_xf_xf , id_z3_xf_xf) = hx_hx; + + B = zeros(z_nbr, inov_nbr); + B(id_z1_xf , id_inov1_u ) = hu; + B(id_z2_xs , id_inov2_u_u ) = 1/2*huu; + B(id_z2_xs , id_inov3_xf_u) = hxu; + B(id_z3_xf_xf , id_inov2_u_u ) = hu_hu; + B(id_z3_xf_xf , id_inov3_xf_u) = (I_xx+K_x_x)*hx_hu; + + c = zeros(z_nbr, 1); + c(id_z2_xs , 1) = 1/2*hss + 1/2*huu*E_uu(:); + c(id_z3_xf_xf , 1) = hu_hu*E_uu(:); + + C = zeros(y_nbr, z_nbr); + C(: , id_z1_xf ) = gx; + C(: , id_z2_xs ) = gx; + C(: , id_z3_xf_xf) = 1/2*gxx; + + D = zeros(y_nbr, inov_nbr); + D(: , id_inov1_u ) = gu; + D(: , id_inov2_u_u ) = 1/2*guu; + D(: , id_inov3_xf_u) = gxu; + + d = 1/2*gss + 1/2*guu*E_uu(:); + + Varinov = zeros(inov_nbr,inov_nbr); + Varinov(id_inov1_u , id_inov1_u) = E_uu; + %Varinov(id_inov1_u , id_inov2_u_u ) = zeros(u_nbr,u_nbr^2); + %Varinov(id_inov1_u , id_inov3_xf_u) = zeros(u_nbr,x_nbr*u_nbr); + %Varinov(id_inov2_u_u , id_inov1_u ) = zeros(u_nbr^2,u_nbr); + Varinov(id_inov2_u_u , id_inov2_u_u ) = reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2)-E_uu(:)*E_uu(:)'; + %Varinov(id_inov2_u_u , id_inov3_xf_u) = zeros(u_nbr^2,x_nbr*u_nbr); + %Varinov(id_inov3_xf_u , id_inov1_u ) = zeros(x_nbr*u_nbr,u_nbr); + %Varinov(id_inov3_xf_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr,u_nbr^2); + Varinov(id_inov3_xf_u , id_inov3_xf_u) = E_xfxf_uu; + + E_xs = invIx_hx*(1/2*hxx*E_xfxf(:) + c(id_z2_xs,1)); + E_inovzlag1 = zeros(inov_nbr,z_nbr); %at second-order E[z(-1)*inov'] = 0 + Om_z = B*Varinov*transpose(B); + + lyapunov_symm_method = 1; %method=1 to initialize persistent variables (if errorflag) + [Var_z, errorflag] = disclyap_fast(A,Om_z,options.lyapunov_doubling_tol); + if errorflag %use Schur-based method + fprintf('PRUNED_STATE_SPACE_SYSTEM: error flag in disclyap_fast at order=2, use lyapunov_symm\n'); + Var_z = lyapunov_symm(A,Om_z,... + options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,... + lyapunov_symm_method,... + options.debug); + lyapunov_symm_method = 2; %in the following we can reuse persistent variables + end + % Make sure some stuff is zero due to Gaussianity + Var_z(id_z1_xf , id_z2_xs ) = zeros(x_nbr,x_nbr); + Var_z(id_z1_xf , id_z3_xf_xf) = zeros(x_nbr,x_nbr^2); + Var_z(id_z2_xs , id_z1_xf ) = zeros(x_nbr,x_nbr); + Var_z(id_z3_xf_xf , id_z1_xf ) = zeros(x_nbr^2,x_nbr); + + if compute_derivs + dA = zeros(z_nbr,z_nbr,totparam_nbr); + dB = zeros(z_nbr,inov_nbr,totparam_nbr); + dc = zeros(z_nbr,totparam_nbr); + dC = zeros(y_nbr,z_nbr,totparam_nbr); + dD = zeros(y_nbr,inov_nbr,totparam_nbr); + dd = zeros(y_nbr,totparam_nbr); + dVarinov = zeros(inov_nbr,inov_nbr,totparam_nbr); + dE_xs = zeros(x_nbr,totparam_nbr); + dE_inovzlag1 = zeros(inov_nbr,z_nbr,totparam_nbr); + dVar_z = zeros(z_nbr,z_nbr,totparam_nbr); + + for jp2 = 1:totparam_nbr + if jp2 <= (stderrparam_nbr+corrparam_nbr) + dE_uu_jp2 = dE_uu(:,:,jp2); + dE_u_u_u_u_jp2 = QPu*dE_u_u_u_u(:,jp2); + else + dE_uu_jp2 = zeros(u_nbr,u_nbr); + dE_u_u_u_u_jp2 = zeros(u_nbr^4,1); + end + dhx_jp2 = dhx(:,:,jp2); + dhu_jp2 = dhu(:,:,jp2); + dhxx_jp2 = dhxx(:,:,jp2); + dhxu_jp2 = dhxu(:,:,jp2); + dhuu_jp2 = dhuu(:,:,jp2); + dhss_jp2 = dhss(:,jp2); + dgx_jp2 = dgx(:,:,jp2); + dgu_jp2 = dgu(:,:,jp2); + dgxx_jp2 = dgxx(:,:,jp2); + dgxu_jp2 = dgxu(:,:,jp2); + dguu_jp2 = dguu(:,:,jp2); + dgss_jp2 = dgss(:,jp2); + dhx_hx_jp2 = kron(dhx_jp2,hx) + kron(hx,dhx_jp2); + dhu_hu_jp2 = kron(dhu_jp2,hu) + kron(hu,dhu_jp2); + dhx_hu_jp2 = kron(dhx_jp2,hu) + kron(hx,dhu_jp2); + dE_xfxf_jp2 = dE_xfxf(:,:,jp2); + dE_xfxf_uu_jp2 = kron(dE_xfxf_jp2,E_uu) + kron(E_xfxf,dE_uu_jp2); + + dA(id_z1_xf , id_z1_xf , jp2) = dhx_jp2; + dA(id_z2_xs , id_z2_xs , jp2) = dhx_jp2; + dA(id_z2_xs , id_z3_xf_xf , jp2) = 1/2*dhxx_jp2; + dA(id_z3_xf_xf , id_z3_xf_xf , jp2) = dhx_hx_jp2; + + dB(id_z1_xf , id_inov1_u , jp2) = dhu_jp2; + dB(id_z2_xs , id_inov2_u_u , jp2) = 1/2*dhuu_jp2; + dB(id_z2_xs , id_inov3_xf_u , jp2) = dhxu_jp2; + dB(id_z3_xf_xf , id_inov2_u_u , jp2) = dhu_hu_jp2; + dB(id_z3_xf_xf , id_inov3_xf_u , jp2) = (I_xx+K_x_x)*dhx_hu_jp2; + + dc(id_z2_xs , jp2) = 1/2*dhss_jp2 + 1/2*dhuu_jp2*E_uu(:) + 1/2*huu*dE_uu_jp2(:); + dc(id_z3_xf_xf , jp2) = dhu_hu_jp2*E_uu(:) + hu_hu*dE_uu_jp2(:); + + dC(: , id_z1_xf , jp2) = dgx_jp2; + dC(: , id_z2_xs , jp2) = dgx_jp2; + dC(: , id_z3_xf_xf , jp2) = 1/2*dgxx_jp2; + + dD(: , id_inov1_u , jp2) = dgu_jp2; + dD(: , id_inov2_u_u , jp2) = 1/2*dguu_jp2; + dD(: , id_inov3_xf_u , jp2) = dgxu_jp2; + + dd(:,jp2) = 1/2*dgss_jp2 + 1/2*guu*dE_uu_jp2(:) + 1/2*dguu_jp2*E_uu(:); + + dVarinov(id_inov1_u , id_inov1_u , jp2) = dE_uu_jp2; + dVarinov(id_inov2_u_u , id_inov2_u_u , jp2) = reshape(dE_u_u_u_u_jp2,u_nbr^2,u_nbr^2) - dE_uu_jp2(:)*E_uu(:)' - E_uu(:)*dE_uu_jp2(:)'; + dVarinov(id_inov3_xf_u , id_inov3_xf_u , jp2) = dE_xfxf_uu_jp2; + + dE_xs(:,jp2) = invIx_hx*( dhx_jp2*E_xs + 1/2*dhxx_jp2*E_xfxf(:) + 1/2*hxx*dE_xfxf_jp2(:) + dc(id_z2_xs,jp2) ); + dOm_z_jp2 = dB(:,:,jp2)*Varinov*B' + B*dVarinov(:,:,jp2)*B' + B*Varinov*dB(:,:,jp2)'; + + [dVar_z(:,:,jp2), errorflag] = disclyap_fast(A, dA(:,:,jp2)*Var_z*A' + A*Var_z*dA(:,:,jp2)' + dOm_z_jp2, options.lyapunov_doubling_tol); + if errorflag + dVar_z(:,:,jp2) = lyapunov_symm(A, dA(:,:,jp2)*Var_z*A' + A*Var_z*dA(:,:,jp2)' + dOm_z_jp2,... + options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,... + lyapunov_symm_method,... + options.debug); + if lyapunov_symm_method == 1 + lyapunov_symm_method = 2; %now we can reuse persistent schur + end + end + % Make sure some stuff is zero due to Gaussianity + dVar_z(id_z1_xf , id_z2_xs , jp2) = zeros(x_nbr,x_nbr); + dVar_z(id_z1_xf , id_z3_xf_xf , jp2) = zeros(x_nbr,x_nbr^2); + dVar_z(id_z2_xs , id_z1_xf , jp2) = zeros(x_nbr,x_nbr); + dVar_z(id_z3_xf_xf , id_z1_xf , jp2) = zeros(x_nbr^2,x_nbr); + end + end + + if order > 2 + % Some common and useful objects for order > 2 + K_u_xx = commutation(u_nbr,x_nbr^2,1); + K_u_ux = commutation(u_nbr,u_nbr*x_nbr,1); + hx_hss2 = kron(hx,1/2*hss); + hu_hss2 = kron(hu,1/2*hss); + hx_hxx2 = kron(hx,1/2*hxx); + hxx2_hu = kron(1/2*hxx,hu); + hx_hxu = kron(hx,hxu); + hxu_hu = kron(hxu,hu); + hx_huu2 = kron(hx,1/2*huu); + hu_huu2 = kron(hu,1/2*huu); + hx_hx_hx = kron(hx,hx_hx); + hx_hx_hu = kron(hx_hx,hu); + hu_hx_hx = kron(hu,hx_hx); + hu_hu_hu = kron(hu_hu,hu); + hx_hu_hu = kron(hx,hu_hu); + hu_hx_hu = kron(hu,hx_hu); + invIxx_hx_hx = (eye(x_nbr^2)-hx_hx)\eye(x_nbr^2); + + % Reuse second-order results + %E_xfxf = Var_z(id_z1_xf, id_z1_xf ); %this is E[xf*xf'], we already have that + %E_xfxs = Var_z(id_z1_xf, id_z2_xs ); %this is E[xf*xs']=0 due to gaussianity + %E_xfxf_xf = Var_z(id_z1_xf, id_z3_xf_xf ); %this is E[xf*kron(xf_xf)']=0 due to gaussianity + %E_xsxf = Var_z(id_z2_xs, id_z1_xf ); %this is E[xs*xf']=0 due to gaussianity + E_xsxs = Var_z(id_z2_xs, id_z2_xs ) + E_xs*transpose(E_xs); %this is E[xs*xs'] + E_xsxf_xf = Var_z(id_z2_xs, id_z3_xf_xf ) + E_xs*E_xfxf(:)'; %this is E[xs*kron(xf,xf)'] + %E_xf_xfxf = Var_z(id_z3_xf_xf, id_z1_xf ); %this is E[kron(xf,xf)*xf']=0 due to gaussianity + E_xf_xfxs = Var_z(id_z3_xf_xf, id_z2_xs ) + E_xfxf(:)*E_xs'; %this is E[kron(xf,xf)*xs'] + E_xf_xfxf_xf = Var_z(id_z3_xf_xf, id_z3_xf_xf) + E_xfxf(:)*E_xfxf(:)'; %this is E[kron(xf,xf)*kron(xf,xf)'] + E_xrdxf = reshape(invIxx_hx_hx*vec(... + hxx*reshape( commutation(x_nbr^2,x_nbr,1)*E_xf_xfxs(:), x_nbr^2,x_nbr)*hx'... + + hxu*kron(E_xs,E_uu)*hu'... + + 1/6*hxxx*reshape(E_xf_xfxf_xf,x_nbr^3,x_nbr)*hx'... + + 1/6*huuu*reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)*hu'... + + 3/6*hxxu*kron(E_xfxf(:),E_uu)*hu'... + + 3/6*hxuu*kron(E_xfxf,E_uu(:))*hx'... + + 3/6*hxss*E_xfxf*hx'... + + 3/6*huss*E_uu*hu'... + ),... + x_nbr,x_nbr); %this is E[xrd*xf'] + if compute_derivs + dE_xsxs = zeros(x_nbr,x_nbr,totparam_nbr); + dE_xsxf_xf = zeros(x_nbr,x_nbr^2,totparam_nbr); + dE_xf_xfxs = zeros(x_nbr^2,x_nbr,totparam_nbr); + dE_xf_xfxf_xf = zeros(x_nbr^2,x_nbr^2,totparam_nbr); + dE_xrdxf = zeros(x_nbr,x_nbr,totparam_nbr); + for jp2 = 1:totparam_nbr + if jp2 < (stderrparam_nbr+corrparam_nbr) + dE_u_u_u_u_jp2 = QPu*dE_u_u_u_u(:,jp2); + else + dE_u_u_u_u_jp2 = zeros(u_nbr^4,1); + end + dE_xsxs(:,:,jp2) = dVar_z(id_z2_xs , id_z2_xs , jp2) + dE_xs(:,jp2)*transpose(E_xs) + E_xs*transpose(dE_xs(:,jp2)); + dE_xsxf_xf(:,:,jp2) = dVar_z(id_z2_xs , id_z3_xf_xf , jp2) + dE_xs(:,jp2)*E_xfxf(:)' + E_xs*vec(dE_xfxf(:,:,jp2))'; + dE_xf_xfxs(:,:,jp2) = dVar_z(id_z3_xf_xf , id_z2_xs , jp2) + vec(dE_xfxf(:,:,jp2))*E_xs' + E_xfxf(:)*dE_xs(:,jp2)'; + dE_xf_xfxf_xf(:,:,jp2) = dVar_z(id_z3_xf_xf , id_z3_xf_xf , jp2) + vec(dE_xfxf(:,:,jp2))*E_xfxf(:)' + E_xfxf(:)*vec(dE_xfxf(:,:,jp2))'; + dE_xrdxf(:,:,jp2) = reshape(invIxx_hx_hx*vec(... + dhx(:,:,jp2)*E_xrdxf*hx' + hx*E_xrdxf*dhx(:,:,jp2)'... + + dhxx(:,:,jp2)*reshape( commutation(x_nbr^2,x_nbr,1)*E_xf_xfxs(:), x_nbr^2,x_nbr)*hx' + hxx*reshape( commutation(x_nbr^2,x_nbr,1)*vec(dE_xf_xfxs(:,:,jp2)), x_nbr^2,x_nbr)*hx' + hxx*reshape( commutation(x_nbr^2,x_nbr,1)*E_xf_xfxs(:), x_nbr^2,x_nbr)*dhx(:,:,jp2)'... + + dhxu(:,:,jp2)*kron(E_xs,E_uu)*hu' + hxu*kron(dE_xs(:,jp2),E_uu)*hu' + hxu*kron(E_xs,dE_uu(:,:,jp2))*hu' + hxu*kron(E_xs,E_uu)*dhu(:,:,jp2)'... + + 1/6*dhxxx(:,:,jp2)*reshape(E_xf_xfxf_xf,x_nbr^3,x_nbr)*hx' + 1/6*hxxx*reshape(dE_xf_xfxf_xf(:,:,jp2),x_nbr^3,x_nbr)*hx' + 1/6*hxxx*reshape(E_xf_xfxf_xf,x_nbr^3,x_nbr)*dhx(:,:,jp2)'... + + 1/6*dhuuu(:,:,jp2)*reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)*hu' + 1/6*huuu*reshape(dE_u_u_u_u_jp2,u_nbr^3,u_nbr)*hu' + 1/6*huuu*reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)*dhu(:,:,jp2)'... + + 3/6*dhxxu(:,:,jp2)*kron(E_xfxf(:),E_uu)*hu' + 3/6*hxxu*kron(vec(dE_xfxf(:,:,jp2)),E_uu)*hu' + 3/6*hxxu*kron(E_xfxf(:),dE_uu(:,:,jp2))*hu' + 3/6*hxxu*kron(E_xfxf(:),E_uu)*dhu(:,:,jp2)'... + + 3/6*dhxuu(:,:,jp2)*kron(E_xfxf,E_uu(:))*hx' + 3/6*hxuu*kron(dE_xfxf(:,:,jp2),E_uu(:))*hx' + 3/6*hxuu*kron(E_xfxf,vec(dE_uu(:,:,jp2)))*hx' + 3/6*hxuu*kron(E_xfxf,E_uu(:))*dhx(:,:,jp2)'... + + 3/6*dhxss(:,:,jp2)*E_xfxf*hx' + 3/6*hxss*dE_xfxf(:,:,jp2)*hx' + 3/6*hxss*E_xfxf*dhx(:,:,jp2)'... + + 3/6*dhuss(:,:,jp2)*E_uu*hu' + 3/6*huss*dE_uu(:,:,jp2)*hu' + 3/6*huss*E_uu*dhu(:,:,jp2)'... + ), x_nbr, x_nbr); + end + end + + % Compute unique sixth-order product moments of u, i.e. unique(E[kron(kron(kron(kron(kron(u,u),u),u),u),u)],'stable') + u_nbr6 = u_nbr*(u_nbr+1)/2*(u_nbr+2)/3*(u_nbr+3)/4*(u_nbr+4)/5*(u_nbr+5)/6; + Q6Pu = Q6_plication(u_nbr); + COMBOS6 = flipud(allVL1(u_nbr, 6)); %all possible (unique) combinations of powers that sum up to six + E_u_u_u_u_u_u = zeros(u_nbr6,1); %only unique entries + if compute_derivs && (stderrparam_nbr+corrparam_nbr>0) + dE_u_u_u_u_u_u = zeros(u_nbr6,stderrparam_nbr+corrparam_nbr); + end + for j6 = 1:size(COMBOS6,1) + if compute_derivs && (stderrparam_nbr+corrparam_nbr>0) + [E_u_u_u_u_u_u(j6), dE_u_u_u_u_u_u(j6,:)] = prodmom_deriv(E_uu, 1:u_nbr, COMBOS6(j6,:), dE_uu(:,:,1:(stderrparam_nbr+corrparam_nbr)), dr.derivs.dCorrelation_matrix(:,:,1:(stderrparam_nbr+corrparam_nbr))); + else + E_u_u_u_u_u_u(j6) = prodmom(E_uu, 1:u_nbr, COMBOS6(j6,:)); + end + end + +%% Third-order pruned state space system +% Auxiliary state vector z is defined by: z = [xf; xs; kron(xf,xf); xrd; kron(xf,xs); kron(kron(xf,xf),xf)] +% Auxiliary innovations vector inov is defined by: inov = [u; kron(u,u)-E_uu(:); kron(xf,u); kron(xs,u); kron(kron(xf,xf),u); kron(kron(xf,u),u); kron(kron(u,u),u))] + z_nbr = x_nbr + x_nbr + x_nbr^2 + x_nbr + x_nbr^2 + x_nbr^3; + inov_nbr = u_nbr + u_nbr^2 + x_nbr*u_nbr + x_nbr*u_nbr + x_nbr^2*u_nbr + x_nbr*u_nbr^2 + u_nbr^3; + + A = zeros(z_nbr,z_nbr); + A(id_z1_xf , id_z1_xf ) = hx; + A(id_z2_xs , id_z2_xs ) = hx; + A(id_z2_xs , id_z3_xf_xf ) = 1/2*hxx; + A(id_z3_xf_xf , id_z3_xf_xf ) = hx_hx; + A(id_z4_xrd , id_z1_xf ) = 3/6*hxss; + A(id_z4_xrd , id_z4_xrd ) = hx; + A(id_z4_xrd , id_z5_xf_xs ) = hxx; + A(id_z4_xrd , id_z6_xf_xf_xf) = 1/6*hxxx; + A(id_z5_xf_xs , id_z1_xf ) = hx_hss2; + A(id_z5_xf_xs , id_z5_xf_xs ) = hx_hx; + A(id_z5_xf_xs , id_z6_xf_xf_xf) = hx_hxx2; + A(id_z6_xf_xf_xf , id_z6_xf_xf_xf) = hx_hx_hx; + + B = zeros(z_nbr,inov_nbr); + B(id_z1_xf , id_inov1_u ) = hu; + B(id_z2_xs , id_inov2_u_u ) = 1/2*huu; + B(id_z2_xs , id_inov3_xf_u ) = hxu; + B(id_z3_xf_xf , id_inov2_u_u ) = hu_hu; + B(id_z3_xf_xf , id_inov3_xf_u ) = (I_xx+K_x_x)*hx_hu; + B(id_z4_xrd , id_inov1_u ) = 3/6*huss; + B(id_z4_xrd , id_inov4_xs_u ) = hxu; + B(id_z4_xrd , id_inov5_xf_xf_u) = 3/6*hxxu; + B(id_z4_xrd , id_inov6_xf_u_u ) = 3/6*hxuu; + B(id_z4_xrd , id_inov7_u_u_u ) = 1/6*huuu; + B(id_z5_xf_xs , id_inov1_u ) = hu_hss2; + B(id_z5_xf_xs , id_inov4_xs_u ) = K_x_x*hx_hu; + B(id_z5_xf_xs , id_inov5_xf_xf_u) = hx_hxu + K_x_x*hxx2_hu; + B(id_z5_xf_xs , id_inov6_xf_u_u ) = hx_huu2 + K_x_x*hxu_hu; + B(id_z5_xf_xs , id_inov7_u_u_u ) = hu_huu2; + B(id_z6_xf_xf_xf , id_inov5_xf_xf_u) = hx_hx_hu + kron(hx,K_x_x*hx_hu) + hu_hx_hx*K_u_xx; + B(id_z6_xf_xf_xf , id_inov6_xf_u_u ) = hx_hu_hu + hu_hx_hu*K_u_ux + kron(hu,K_x_x*hx_hu)*K_u_ux; + B(id_z6_xf_xf_xf , id_inov7_u_u_u ) = hu_hu_hu; + + c = zeros(z_nbr, 1); + c(id_z2_xs , 1) = 1/2*hss + 1/2*huu*E_uu(:); + c(id_z3_xf_xf , 1) = hu_hu*E_uu(:); + + C = zeros(y_nbr,z_nbr); + C(: , id_z1_xf ) = gx + 3/6*gxss; + C(: , id_z2_xs ) = gx; + C(: , id_z3_xf_xf ) = 1/2*gxx; + C(: , id_z4_xrd ) = gx; + C(: , id_z5_xf_xs ) = gxx; + C(: , id_z6_xf_xf_xf) = 1/6*gxxx; + + D = zeros(y_nbr,inov_nbr); + D(: , id_inov1_u ) = gu + 3/6*guss; + D(: , id_inov2_u_u ) = 1/2*guu; + D(: , id_inov3_xf_u ) = gxu; + D(: , id_inov4_xs_u ) = gxu; + D(: , id_inov5_xf_xf_u) = 3/6*gxxu; + D(: , id_inov6_xf_u_u) = 3/6*gxuu; + D(: , id_inov7_u_u_u ) = 1/6*guuu; + + d = 1/2*gss + 1/2*guu*E_uu(:); + + Varinov = zeros(inov_nbr,inov_nbr); + Varinov(id_inov1_u , id_inov1_u ) = E_uu; + %Varinov(id_inov1_u , id_inov2_u_u ) = zeros(u_nbr,u_nbr^2); + %Varinov(id_inov1_u , id_inov3_xf_u ) = zeros(u_nbr,x_nbr*u_nbr); + Varinov(id_inov1_u , id_inov4_xs_u ) = kron(E_xs',E_uu); + Varinov(id_inov1_u , id_inov5_xf_xf_u) = kron(E_xfxf(:)',E_uu); + %Varinov(id_inov1_u , id_inov6_xf_u_u ) = zeros(u_nbr,x_nbr*u_nbr^2); + Varinov(id_inov1_u , id_inov7_u_u_u ) = reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3); + + %Varinov(id_inov2_u_u , id_inov1_u ) = zeros(u_nbr^2,u_nbr); + Varinov(id_inov2_u_u , id_inov2_u_u ) = reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2)-E_uu(:)*E_uu(:)'; + %Varinov(id_inov2_u_u , id_inov3_xf_u ) = zeros(u_nbr^2,x_nbr*u_nbr); + %Varinov(id_inov2_u_u , id_inov4_xs_u ) = zeros(u_nbr^2,x_nbr*u_nbr); + %Varinov(id_inov2_u_u , id_inov5_xf_xf_u) = zeros(u_nbr^2,x_nbr^2,u_nbr); + %Varinov(id_inov2_u_u , id_inov6_xf_u_u ) = zeros(u_nbr^2,x_nbr*u_nbr^2); + %Varinov(id_inov2_u_u , id_inov7_u_u_u ) = zeros(u_nbr^2,u_nbr^3); + + %Varinov(id_inov3_xf_u , id_inov1_u ) = zeros(x_nbr*u_nbr,u_nbr); + %Varinov(id_inov3_xf_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr,u_nbr^2); + Varinov(id_inov3_xf_u , id_inov3_xf_u ) = E_xfxf_uu; + %Varinov(id_inov3_xf_u , id_inov4_xs_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr); + %Varinov(id_inov3_xf_u , id_inov5_xf_xf_u) = zeros(x_nbr*u_nbr,x_nbr^2*u_nbr); + %Varinov(id_inov3_xf_u , id_inov6_xf_u_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr^2); + %Varinov(id_inov3_xf_u , id_inov7_u_u_u ) = zeros(x_nbr*u_nbr,u_nbr^3); + + Varinov(id_inov4_xs_u , id_inov1_u ) = kron(E_xs,E_uu); + %Varinov(id_inov4_xs_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr,u_nbr^2); + %Varinov(id_inov4_xs_u , id_inov3_xf_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr); + Varinov(id_inov4_xs_u , id_inov4_xs_u ) = kron(E_xsxs,E_uu); + Varinov(id_inov4_xs_u , id_inov5_xf_xf_u) = kron(E_xsxf_xf, E_uu); + %Varinov(id_inov4_xs_u , id_inov6_xf_u_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr^2); + Varinov(id_inov4_xs_u , id_inov7_u_u_u ) = kron(E_xs,reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3)); + + Varinov(id_inov5_xf_xf_u , id_inov1_u ) = kron(E_xfxf(:),E_uu); + %Varinov(id_inov5_xf_xf_u , id_inov2_u_u ) = zeros(x_nbr^2*u_nbr,u_nbr^2); + %Varinov(id_inov5_xf_xf_u , id_inov3_xf_u ) = zeros(x_nbr^2*u_nbr,x_nbr*u_nbr); + Varinov(id_inov5_xf_xf_u , id_inov4_xs_u ) = kron(E_xf_xfxs,E_uu); + Varinov(id_inov5_xf_xf_u , id_inov5_xf_xf_u) = kron(E_xf_xfxf_xf,E_uu); + %Varinov(id_inov5_xf_xf_u , id_inov6_xf_u_u ) = zeros(x_nbr^2*u_nbr,x_nbr*u_nbr^2); + Varinov(id_inov5_xf_xf_u , id_inov7_u_u_u ) = kron(E_xfxf(:),reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3)); + + %Varinov(id_inov6_xf_u_u , id_inov1_u ) = zeros(x_nbr*u_nbr^2,u_nbr); + %Varinov(id_inov6_xf_u_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr^2,u_nbr^2); + %Varinov(id_inov6_xf_u_u , id_inov3_xf_u ) = zeros(x_nbr*u_nbr^2,x_nbr*u_nbr); + %Varinov(id_inov6_xf_u_u , id_inov4_xs_u ) = zeros(x_nbr*u_nbr^2,x_nbr*u_nbr); + %Varinov(id_inov6_xf_u_u , id_inov5_xf_xf_u) = zeros(x_nbr*u_nbr^2,x_nbr^2*u_nbr); + Varinov(id_inov6_xf_u_u , id_inov6_xf_u_u ) = kron(E_xfxf,reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2)); + %Varinov(id_inov6_xf_u_u , id_inov7_u_u_u ) = zeros(x_nbr*u_nbr^2,u_nbr^3); + + Varinov(id_inov7_u_u_u , id_inov1_u ) = reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr); + %Varinov(id_inov7_u_u_u , id_inov2_u_u ) = zeros(u_nbr^3,u_nbr^2); + %Varinov(id_inov7_u_u_u , id_inov3_xf_u ) = zeros(u_nbr^3,x_nbr*u_nbr); + Varinov(id_inov7_u_u_u , id_inov4_xs_u ) = kron(E_xs',reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)); + Varinov(id_inov7_u_u_u , id_inov5_xf_xf_u) = kron(transpose(E_xfxf(:)),reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)); + %Varinov(id_inov7_u_u_u , id_inov6_xf_u_u ) = zeros(u_nbr^3,x_nbr*u_nbr^2); + Varinov(id_inov7_u_u_u , id_inov7_u_u_u ) = reshape(Q6Pu*E_u_u_u_u_u_u,u_nbr^3,u_nbr^3); + + E_xrd = zeros(x_nbr,1);%due to gaussianity + + E_inovzlag1 = zeros(inov_nbr,z_nbr); % Attention: E[inov*z(-1)'] is not equal to zero for a third-order approximation due to kron(kron(xf(-1),u),u) + E_inovzlag1(id_inov6_xf_u_u , id_z1_xf ) = kron(E_xfxf,E_uu(:)); + E_inovzlag1(id_inov6_xf_u_u , id_z4_xrd ) = kron(E_xrdxf',E_uu(:)); + E_inovzlag1(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(reshape(commutation(x_nbr^2,x_nbr)*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu)) ; + E_inovzlag1(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:)); + + Binovzlag1A= B*E_inovzlag1*transpose(A); + Om_z = B*Varinov*transpose(B) + Binovzlag1A + transpose(Binovzlag1A); + + lyapunov_symm_method = 1; %method=1 to initialize persistent variables + [Var_z, errorflag] = disclyap_fast(A,Om_z,options.lyapunov_doubling_tol); + if errorflag %use Schur-based method + fprintf('PRUNED_STATE_SPACE_SYSTEM: error flag in disclyap_fast at order=3, use lyapunov_symm\n'); + Var_z = lyapunov_symm(A,Om_z,... + options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,... + lyapunov_symm_method,... + options.debug); + lyapunov_symm_method = 2; %we can now make use of persistent variables from shur + end + %make sure some stuff is zero due to Gaussianity + Var_z(id_z1_xf , id_z2_xs) = zeros(x_nbr,x_nbr); + Var_z(id_z1_xf , id_z3_xf_xf) = zeros(x_nbr,x_nbr^2); + Var_z(id_z2_xs , id_z1_xf) = zeros(x_nbr,x_nbr); + Var_z(id_z2_xs , id_z4_xrd) = zeros(x_nbr,x_nbr); + Var_z(id_z2_xs , id_z5_xf_xs) = zeros(x_nbr,x_nbr^2); + Var_z(id_z2_xs , id_z6_xf_xf_xf) = zeros(x_nbr,x_nbr^3); + Var_z(id_z3_xf_xf , id_z1_xf) = zeros(x_nbr^2,x_nbr); + Var_z(id_z3_xf_xf , id_z4_xrd) = zeros(x_nbr^2,x_nbr); + Var_z(id_z3_xf_xf , id_z5_xf_xs) = zeros(x_nbr^2,x_nbr^2); + Var_z(id_z3_xf_xf , id_z6_xf_xf_xf) = zeros(x_nbr^2,x_nbr^3); + Var_z(id_z4_xrd , id_z2_xs) = zeros(x_nbr,x_nbr); + Var_z(id_z4_xrd , id_z3_xf_xf) = zeros(x_nbr,x_nbr^2); + Var_z(id_z5_xf_xs , id_z2_xs) = zeros(x_nbr^2,x_nbr); + Var_z(id_z5_xf_xs , id_z3_xf_xf) = zeros(x_nbr^2,x_nbr^2); + Var_z(id_z6_xf_xf_xf , id_z2_xs) = zeros(x_nbr^3,x_nbr); + Var_z(id_z6_xf_xf_xf , id_z3_xf_xf) = zeros(x_nbr^3,x_nbr^2); + + if compute_derivs + dA = zeros(z_nbr,z_nbr,totparam_nbr); + dB = zeros(z_nbr,inov_nbr,totparam_nbr); + dc = zeros(z_nbr,totparam_nbr); + dC = zeros(y_nbr,z_nbr,totparam_nbr); + dD = zeros(y_nbr,inov_nbr,totparam_nbr); + dd = zeros(y_nbr,totparam_nbr); + dVarinov = zeros(inov_nbr,inov_nbr,totparam_nbr); + dE_xrd = zeros(x_nbr,totparam_nbr); + dE_inovzlag1 = zeros(inov_nbr,z_nbr,totparam_nbr); + dVar_z = zeros(z_nbr,z_nbr,totparam_nbr); + + for jp3 = 1:totparam_nbr + if jp3 <= (stderrparam_nbr+corrparam_nbr) + dE_uu_jp3 = dE_uu(:,:,jp3); + dE_u_u_u_u_jp3 = QPu*dE_u_u_u_u(:,jp3); + dE_u_u_u_u_u_u_jp3 = Q6Pu*dE_u_u_u_u_u_u(:,jp3); + else + dE_uu_jp3 = zeros(u_nbr,u_nbr); + dE_u_u_u_u_jp3 = zeros(u_nbr^4,1); + dE_u_u_u_u_u_u_jp3 = zeros(u_nbr^6,1); + end + dhx_jp3 = dhx(:,:,jp3); + dhu_jp3 = dhu(:,:,jp3); + dhxx_jp3 = dhxx(:,:,jp3); + dhxu_jp3 = dhxu(:,:,jp3); + dhuu_jp3 = dhuu(:,:,jp3); + dhss_jp3 = dhss(:,jp3); + dhxxx_jp3 = dhxxx(:,:,jp3); + dhxxu_jp3 = dhxxu(:,:,jp3); + dhxuu_jp3 = dhxuu(:,:,jp3); + dhuuu_jp3 = dhuuu(:,:,jp3); + dhxss_jp3 = dhxss(:,:,jp3); + dhuss_jp3 = dhuss(:,:,jp3); + dgx_jp3 = dgx(:,:,jp3); + dgu_jp3 = dgu(:,:,jp3); + dgxx_jp3 = dgxx(:,:,jp3); + dgxu_jp3 = dgxu(:,:,jp3); + dguu_jp3 = dguu(:,:,jp3); + dgss_jp3 = dgss(:,jp3); + dgxxx_jp3 = dgxxx(:,:,jp3); + dgxxu_jp3 = dgxxu(:,:,jp3); + dgxuu_jp3 = dgxuu(:,:,jp3); + dguuu_jp3 = dguuu(:,:,jp3); + dgxss_jp3 = dgxss(:,:,jp3); + dguss_jp3 = dguss(:,:,jp3); + + dhx_hx_jp3 = kron(dhx_jp3,hx) + kron(hx,dhx_jp3); + dhx_hu_jp3 = kron(dhx_jp3,hu) + kron(hx,dhu_jp3); + dhu_hu_jp3 = kron(dhu_jp3,hu) + kron(hu,dhu_jp3); + dhx_hss2_jp3 = kron(dhx_jp3,1/2*hss) + kron(hx,1/2*dhss_jp3); + dhu_hss2_jp3 = kron(dhu_jp3,1/2*hss) + kron(hu,1/2*dhss_jp3); + dhx_hxx2_jp3 = kron(dhx_jp3,1/2*hxx) + kron(hx,1/2*dhxx_jp3); + dhxx2_hu_jp3 = kron(1/2*dhxx_jp3,hu) + kron(1/2*hxx,dhu_jp3); + dhx_hxu_jp3 = kron(dhx_jp3,hxu) + kron(hx,dhxu_jp3); + dhxu_hu_jp3 = kron(dhxu_jp3,hu) + kron(hxu,dhu_jp3); + dhx_huu2_jp3 = kron(dhx_jp3,1/2*huu) + kron(hx,1/2*dhuu_jp3); + dhu_huu2_jp3 = kron(dhu_jp3,1/2*huu) + kron(hu,1/2*dhuu_jp3); + dhx_hx_hx_jp3 = kron(dhx_jp3,hx_hx) + kron(hx,dhx_hx_jp3); + dhx_hx_hu_jp3 = kron(dhx_hx_jp3,hu) + kron(hx_hx,dhu_jp3); + dhu_hx_hx_jp3 = kron(dhu_jp3,hx_hx) + kron(hu,dhx_hx_jp3); + dhu_hu_hu_jp3 = kron(dhu_hu_jp3,hu) + kron(hu_hu,dhu_jp3); + dhx_hu_hu_jp3 = kron(dhx_jp3,hu_hu) + kron(hx,dhu_hu_jp3); + dhu_hx_hu_jp3 = kron(dhu_jp3,hx_hu) + kron(hu,dhx_hu_jp3); + + dE_xs_jp3 = dE_xs(:,jp3); + dE_xfxf_jp3 = dE_xfxf(:,:,jp3); + dE_xsxs_jp3 = dE_xsxs(:,:,jp3); + dE_xsxf_xf_jp3 = dE_xsxf_xf(:,:,jp3); + dE_xfxf_uu_jp3 = kron(dE_xfxf_jp3,E_uu) + kron(E_xfxf,dE_uu_jp3); + dE_xf_xfxs_jp3 = dE_xf_xfxs(:,:,jp3); + dE_xf_xfxf_xf_jp3 = dE_xf_xfxf_xf(:,:,jp3); + dE_xrdxf_jp3 = dE_xrdxf(:,:,jp3); + + dA(id_z1_xf , id_z1_xf , jp3) = dhx_jp3; + dA(id_z2_xs , id_z2_xs , jp3) = dhx_jp3; + dA(id_z2_xs , id_z3_xf_xf , jp3) = 1/2*dhxx_jp3; + dA(id_z3_xf_xf , id_z3_xf_xf , jp3) = dhx_hx_jp3; + dA(id_z4_xrd , id_z1_xf , jp3) = 3/6*dhxss_jp3; + dA(id_z4_xrd , id_z4_xrd , jp3) = dhx_jp3; + dA(id_z4_xrd , id_z5_xf_xs , jp3) = dhxx_jp3; + dA(id_z4_xrd , id_z6_xf_xf_xf , jp3) = 1/6*dhxxx_jp3; + dA(id_z5_xf_xs , id_z1_xf , jp3) = dhx_hss2_jp3; + dA(id_z5_xf_xs , id_z5_xf_xs , jp3) = dhx_hx_jp3; + dA(id_z5_xf_xs , id_z6_xf_xf_xf , jp3) = dhx_hxx2_jp3; + dA(id_z6_xf_xf_xf , id_z6_xf_xf_xf , jp3) = dhx_hx_hx_jp3; + + dB(id_z1_xf , id_inov1_u , jp3) = dhu_jp3; + dB(id_z2_xs , id_inov2_u_u , jp3) = 1/2*dhuu_jp3; + dB(id_z2_xs , id_inov3_xf_u , jp3) = dhxu_jp3; + dB(id_z3_xf_xf , id_inov2_u_u , jp3) = dhu_hu_jp3; + dB(id_z3_xf_xf , id_inov3_xf_u , jp3) = (I_xx+K_x_x)*dhx_hu_jp3; + dB(id_z4_xrd , id_inov1_u , jp3) = 3/6*dhuss_jp3; + dB(id_z4_xrd , id_inov4_xs_u , jp3) = dhxu_jp3; + dB(id_z4_xrd , id_inov5_xf_xf_u , jp3) = 3/6*dhxxu_jp3; + dB(id_z4_xrd , id_inov6_xf_u_u , jp3) = 3/6*dhxuu_jp3; + dB(id_z4_xrd , id_inov7_u_u_u , jp3) = 1/6*dhuuu_jp3; + dB(id_z5_xf_xs , id_inov1_u , jp3) = dhu_hss2_jp3; + dB(id_z5_xf_xs , id_inov4_xs_u , jp3) = K_x_x*dhx_hu_jp3; + dB(id_z5_xf_xs , id_inov5_xf_xf_u , jp3) = dhx_hxu_jp3 + K_x_x*dhxx2_hu_jp3; + dB(id_z5_xf_xs , id_inov6_xf_u_u , jp3) = dhx_huu2_jp3 + K_x_x*dhxu_hu_jp3; + dB(id_z5_xf_xs , id_inov7_u_u_u , jp3) = dhu_huu2_jp3; + dB(id_z6_xf_xf_xf , id_inov5_xf_xf_u , jp3) = dhx_hx_hu_jp3 + kron(dhx_jp3,K_x_x*hx_hu) + kron(hx,K_x_x*dhx_hu_jp3) + dhu_hx_hx_jp3*K_u_xx; + dB(id_z6_xf_xf_xf , id_inov6_xf_u_u , jp3) = dhx_hu_hu_jp3 + dhu_hx_hu_jp3*K_u_ux + kron(dhu_jp3,K_x_x*hx_hu)*K_u_ux + kron(hu,K_x_x*dhx_hu_jp3)*K_u_ux; + dB(id_z6_xf_xf_xf , id_inov7_u_u_u , jp3) = dhu_hu_hu_jp3; + + dc(id_z2_xs , jp3) = 1/2*dhss_jp3 + 1/2*dhuu_jp3*E_uu(:) + 1/2*huu*dE_uu_jp3(:); + dc(id_z3_xf_xf , jp3) = dhu_hu_jp3*E_uu(:) + hu_hu*dE_uu_jp3(:); + + dC(: , id_z1_xf , jp3) = dgx_jp3 + 3/6*dgxss_jp3; + dC(: , id_z2_xs , jp3) = dgx_jp3; + dC(: , id_z3_xf_xf , jp3) = 1/2*dgxx_jp3; + dC(: , id_z4_xrd , jp3) = dgx_jp3; + dC(: , id_z5_xf_xs , jp3) = dgxx_jp3; + dC(: , id_z6_xf_xf_xf , jp3) = 1/6*dgxxx_jp3; + + dD(: , id_inov1_u , jp3) = dgu_jp3 + 3/6*dguss_jp3; + dD(: , id_inov2_u_u , jp3) = 1/2*dguu_jp3; + dD(: , id_inov3_xf_u , jp3) = dgxu_jp3; + dD(: , id_inov4_xs_u , jp3) = dgxu_jp3; + dD(: , id_inov5_xf_xf_u , jp3) = 3/6*dgxxu_jp3; + dD(: , id_inov6_xf_u_u , jp3) = 3/6*dgxuu_jp3; + dD(: , id_inov7_u_u_u , jp3) = 1/6*dguuu_jp3; + + dd(:,jp3) = 1/2*dgss_jp3 + 1/2*dguu_jp3*E_uu(:) + 1/2*guu*dE_uu_jp3(:); + + dVarinov(id_inov1_u , id_inov1_u , jp3) = dE_uu_jp3; + dVarinov(id_inov1_u , id_inov4_xs_u , jp3) = kron(dE_xs_jp3',E_uu) + kron(E_xs',dE_uu_jp3); + dVarinov(id_inov1_u , id_inov5_xf_xf_u , jp3) = kron(dE_xfxf_jp3(:)',E_uu) + kron(E_xfxf(:)',dE_uu_jp3); + dVarinov(id_inov1_u , id_inov7_u_u_u , jp3) = reshape(dE_u_u_u_u_jp3,u_nbr,u_nbr^3); + dVarinov(id_inov2_u_u , id_inov2_u_u , jp3) = reshape(dE_u_u_u_u_jp3,u_nbr^2,u_nbr^2) - dE_uu_jp3(:)*E_uu(:)' - E_uu(:)*dE_uu_jp3(:)'; + dVarinov(id_inov3_xf_u , id_inov3_xf_u , jp3) = dE_xfxf_uu_jp3; + dVarinov(id_inov4_xs_u , id_inov1_u , jp3) = kron(dE_xs_jp3,E_uu) + kron(E_xs,dE_uu_jp3); + dVarinov(id_inov4_xs_u , id_inov4_xs_u , jp3) = kron(dE_xsxs_jp3,E_uu) + kron(E_xsxs,dE_uu_jp3); + dVarinov(id_inov4_xs_u , id_inov5_xf_xf_u , jp3) = kron(dE_xsxf_xf_jp3, E_uu) + kron(E_xsxf_xf, dE_uu_jp3); + dVarinov(id_inov4_xs_u , id_inov7_u_u_u , jp3) = kron(dE_xs_jp3,reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3)) + kron(E_xs,reshape(dE_u_u_u_u_jp3,u_nbr,u_nbr^3)); + dVarinov(id_inov5_xf_xf_u , id_inov1_u , jp3) = kron(dE_xfxf_jp3(:),E_uu) + kron(E_xfxf(:),dE_uu_jp3); + dVarinov(id_inov5_xf_xf_u , id_inov4_xs_u , jp3) = kron(dE_xf_xfxs_jp3,E_uu) + kron(E_xf_xfxs,dE_uu_jp3); + dVarinov(id_inov5_xf_xf_u , id_inov5_xf_xf_u , jp3) = kron(dE_xf_xfxf_xf_jp3,E_uu) + kron(E_xf_xfxf_xf,dE_uu_jp3); + dVarinov(id_inov5_xf_xf_u , id_inov7_u_u_u , jp3) = kron(dE_xfxf_jp3(:),reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3)) + kron(E_xfxf(:),reshape(dE_u_u_u_u_jp3,u_nbr,u_nbr^3)); + dVarinov(id_inov6_xf_u_u , id_inov6_xf_u_u , jp3) = kron(dE_xfxf_jp3,reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(dE_u_u_u_u_jp3,u_nbr^2,u_nbr^2)); + dVarinov(id_inov7_u_u_u , id_inov1_u , jp3) = reshape(dE_u_u_u_u_jp3,u_nbr^3,u_nbr); + dVarinov(id_inov7_u_u_u , id_inov4_xs_u , jp3) = kron(dE_xs_jp3',reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)) + kron(E_xs',reshape(dE_u_u_u_u_jp3,u_nbr^3,u_nbr)); + dVarinov(id_inov7_u_u_u , id_inov5_xf_xf_u , jp3) = kron(transpose(dE_xfxf_jp3(:)),reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)) + kron(transpose(E_xfxf(:)),reshape(dE_u_u_u_u_jp3,u_nbr^3,u_nbr)); + dVarinov(id_inov7_u_u_u , id_inov7_u_u_u , jp3) = reshape(dE_u_u_u_u_u_u_jp3,u_nbr^3,u_nbr^3); + + dE_inovzlag1(id_inov6_xf_u_u , id_z1_xf , jp3) = kron(dE_xfxf_jp3,E_uu(:)) + kron(E_xfxf,dE_uu_jp3(:)); + dE_inovzlag1(id_inov6_xf_u_u , id_z4_xrd , jp3) = kron(dE_xrdxf_jp3',E_uu(:)) + kron(E_xrdxf',dE_uu_jp3(:)); + dE_inovzlag1(id_inov6_xf_u_u , id_z5_xf_xs , jp3) = kron(reshape(commutation(x_nbr^2,x_nbr)*vec(dE_xsxf_xf_jp3),x_nbr,x_nbr^2),vec(E_uu)) + kron(reshape(commutation(x_nbr^2,x_nbr)*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(dE_uu_jp3)) ; + dE_inovzlag1(id_inov6_xf_u_u , id_z6_xf_xf_xf , jp3) = kron(reshape(dE_xf_xfxf_xf_jp3,x_nbr,x_nbr^3),E_uu(:)) + kron(reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),dE_uu_jp3(:)); + + dBinovzlag1A_jp3 = dB(:,:,jp3)*E_inovzlag1*transpose(A) + B*dE_inovzlag1(:,:,jp3)*transpose(A) + B*E_inovzlag1*transpose(dA(:,:,jp3)); + dOm_z_jp3 = dB(:,:,jp3)*Varinov*transpose(B) + B*dVarinov(:,:,jp3)*transpose(B) + B*Varinov*transpose(dB(:,:,jp3)) + dBinovzlag1A_jp3 + transpose(dBinovzlag1A_jp3); + + [dVar_z(:,:,jp3), errorflag] = disclyap_fast(A, dA(:,:,jp3)*Var_z*A' + A*Var_z*dA(:,:,jp3)' + dOm_z_jp3, options.lyapunov_doubling_tol); + if errorflag + dVar_z(:,:,jp3) = lyapunov_symm(A, dA(:,:,jp3)*Var_z*A' + A*Var_z*dA(:,:,jp3)' + dOm_z_jp3,... + options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,... + lyapunov_symm_method,... + options.debug); + if lyapunov_symm_method == 1 + lyapunov_symm_method = 2; %now we can reuse persistent schur + end + end + %make sure some stuff is zero due to Gaussianity + dVar_z(id_z1_xf , id_z2_xs , jp3) = zeros(x_nbr,x_nbr); + dVar_z(id_z1_xf , id_z3_xf_xf , jp3) = zeros(x_nbr,x_nbr^2); + dVar_z(id_z2_xs , id_z1_xf , jp3) = zeros(x_nbr,x_nbr); + dVar_z(id_z2_xs , id_z4_xrd , jp3) = zeros(x_nbr,x_nbr); + dVar_z(id_z2_xs , id_z5_xf_xs , jp3) = zeros(x_nbr,x_nbr^2); + dVar_z(id_z2_xs , id_z6_xf_xf_xf , jp3) = zeros(x_nbr,x_nbr^3); + dVar_z(id_z3_xf_xf , id_z1_xf , jp3) = zeros(x_nbr^2,x_nbr); + dVar_z(id_z3_xf_xf , id_z4_xrd , jp3) = zeros(x_nbr^2,x_nbr); + dVar_z(id_z3_xf_xf , id_z5_xf_xs , jp3) = zeros(x_nbr^2,x_nbr^2); + dVar_z(id_z3_xf_xf , id_z6_xf_xf_xf , jp3) = zeros(x_nbr^2,x_nbr^3); + dVar_z(id_z4_xrd , id_z2_xs , jp3) = zeros(x_nbr,x_nbr); + dVar_z(id_z4_xrd , id_z3_xf_xf , jp3) = zeros(x_nbr,x_nbr^2); + dVar_z(id_z5_xf_xs , id_z2_xs , jp3) = zeros(x_nbr^2,x_nbr); + dVar_z(id_z5_xf_xs , id_z3_xf_xf , jp3) = zeros(x_nbr^2,x_nbr^2); + dVar_z(id_z6_xf_xf_xf , id_z2_xs , jp3) = zeros(x_nbr^3,x_nbr); + dVar_z(id_z6_xf_xf_xf , id_z3_xf_xf , jp3) = zeros(x_nbr^3,x_nbr^2); + end + end + end +end + +%% Covariance/Correlation of control variables +Var_y = NaN*ones(y_nbr,y_nbr); +if order < 3 + Var_y(stationary_vars,stationary_vars) = C(stationary_vars,:)*Var_z*C(stationary_vars,:)'... + + D(stationary_vars,:)*Varinov*D(stationary_vars,:)'; +else + Var_y(stationary_vars,stationary_vars) = C(stationary_vars,:)*Var_z*C(stationary_vars,:)'... + + D(stationary_vars,:)*E_inovzlag1*C(stationary_vars,:)'... + + C(stationary_vars,:)*transpose(E_inovzlag1)*D(stationary_vars,:)'... + + D(stationary_vars,:)*Varinov*D(stationary_vars,:)'; +end +indzeros = find(abs(Var_y) < 1e-12); %find values that are numerical zero +Var_y(indzeros) = 0; +if useautocorr + sy = sqrt(diag(Var_y)); %theoretical standard deviation + sy = sy(stationary_vars); + sy = sy*sy'; %cross products of standard deviations + Corr_y = NaN*ones(y_nbr,y_nbr); + Corr_y(stationary_vars,stationary_vars) = Var_y(stationary_vars,stationary_vars)./sy; + Corr_yi = NaN*ones(y_nbr,y_nbr,nlags); +end + +if compute_derivs + dVar_y = NaN*ones(y_nbr,y_nbr,totparam_nbr); + if useautocorr + dCorr_y = NaN*ones(y_nbr,y_nbr,totparam_nbr); + dCorr_yi = NaN*ones(y_nbr,y_nbr,nlags,totparam_nbr); + end + for jpV=1:totparam_nbr + if order < 3 + dVar_y(stationary_vars,stationary_vars,jpV) = dC(stationary_vars,:,jpV)*Var_z*C(stationary_vars,:)' + C(stationary_vars,:)*dVar_z(:,:,jpV)*C(stationary_vars,:)' + C(stationary_vars,:)*Var_z*dC(stationary_vars,:,jpV)'... + + dD(stationary_vars,:,jpV)*Varinov*D(stationary_vars,:)' + D(stationary_vars,:)*dVarinov(:,:,jpV)*D(stationary_vars,:)' + D(stationary_vars,:)*Varinov*dD(stationary_vars,:,jpV)'; + else + dVar_y(stationary_vars,stationary_vars,jpV) = dC(stationary_vars,:,jpV)*Var_z*C(stationary_vars,:)' + C(stationary_vars,:)*dVar_z(:,:,jpV)*C(stationary_vars,:)' + C(stationary_vars,:)*Var_z*dC(stationary_vars,:,jpV)'... + + dD(stationary_vars,:,jpV)*E_inovzlag1*C(stationary_vars,:)' + D(stationary_vars,:)*dE_inovzlag1(:,:,jpV)*C(stationary_vars,:)' + D(stationary_vars,:)*E_inovzlag1*dC(stationary_vars,:,jpV)'... + + dC(stationary_vars,:,jpV)*transpose(E_inovzlag1)*D(stationary_vars,:)' + C(stationary_vars,:)*transpose(dE_inovzlag1(:,:,jpV))*D(stationary_vars,:)' + C(stationary_vars,:)*transpose(E_inovzlag1)*dD(stationary_vars,:,jpV)'... + + dD(stationary_vars,:,jpV)*Varinov*D(stationary_vars,:)' + D(stationary_vars,:)*dVarinov(:,:,jpV)*D(stationary_vars,:)' + D(stationary_vars,:)*Varinov*dD(stationary_vars,:,jpV)'; + end + [indzerosrow,indzeroscol] = find(abs(dVar_y(:,:,jpV)) < 1e-12); %find values that are numerical zero + dVar_y(indzerosrow,indzeroscol,jpV) = 0; + if useautocorr + %is this correct?[@wmutschl] + dsy = 1/2./sy.*diag(dVar_y(:,:,jpV)); + dsy = dsy(stationary_vars); + dsy = dsy*sy'+sy*dsy'; + dCorr_y(stationary_vars,stationary_vars,jpV) = (dVar_y(stationary_vars,stationary_vars,jpV).*sy-dsy.*Var_y(stationary_vars,stationary_vars))./(sy.*sy); + dCorr_y(stationary_vars,stationary_vars,jpV) = dCorr_y(stationary_vars,stationary_vars,jpV)-diag(diag(dCorr_y(stationary_vars,stationary_vars,jpV)))+diag(diag(dVar_y(stationary_vars,stationary_vars,jpV))); + end + end +end + +%% Autocovariances/autocorrelations of lagged control variables +Var_yi = NaN*ones(y_nbr,y_nbr,nlags); +Ai = eye(z_nbr); %this is A^0 +hxi = eye(x_nbr); +E_inovzlagi = E_inovzlag1; +Var_zi = Var_z; +if order <= 2 + tmp = A*Var_z*C(stationary_vars,:)' + B*Varinov*D(stationary_vars,:)'; +else + tmp = A*E_inovzlag1'*D(stationary_vars,:)' + B*Varinov*D(stationary_vars,:)'; +end +for i = 1:nlags + if order <= 2 + Var_yi(stationary_vars,stationary_vars,i) = C(stationary_vars,:)*Ai*tmp; + else + Var_zi = A*Var_zi + B*E_inovzlagi; + hxi = hx*hxi; + E_inovzlagi = zeros(inov_nbr,z_nbr); + E_inovzlagi(id_inov6_xf_u_u , id_z1_xf ) = kron(hxi*E_xfxf,E_uu(:)); + E_inovzlagi(id_inov6_xf_u_u , id_z4_xrd ) = kron(hxi*E_xrdxf',E_uu(:)); + E_inovzlagi(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(hxi*reshape(commutation(x_nbr^2,x_nbr)*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu)); + E_inovzlagi(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(hxi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:)); + Var_yi(stationary_vars,stationary_vars,i) = C(stationary_vars,:)*Var_zi*C(stationary_vars,:)' + C(stationary_vars,:)*Ai*tmp + D(stationary_vars,:)*E_inovzlagi*C(stationary_vars,:)'; + end + if useautocorr + Corr_yi(stationary_vars,stationary_vars,i) = Var_yi(stationary_vars,stationary_vars,i)./sy; + end + Ai = Ai*A; %note that this is A^(i-1) +end + +if compute_derivs + dVar_yi = NaN*ones(y_nbr,y_nbr,nlags,totparam_nbr); + for jpVi=1:totparam_nbr + Ai = eye(z_nbr); dAi_jpVi = zeros(z_nbr,z_nbr); + hxi = eye(x_nbr); dhxi_jpVi = zeros(x_nbr,x_nbr); + E_inovzlagi = E_inovzlag1; dE_inovzlagi_jpVi = dE_inovzlag1(:,:,jpVi); + Var_zi = Var_z; dVar_zi_jpVi = dVar_z(:,:,jpVi); + if order <= 2 + dtmp_jpVi = dA(:,:,jpVi)*Var_z*C(stationary_vars,:)' + A*dVar_z(:,:,jpVi)*C(stationary_vars,:)' + A*Var_z*dC(stationary_vars,:,jpVi)'... + + dB(:,:,jpVi)*Varinov*D(stationary_vars,:)' + B*dVarinov(:,:,jpVi)*D(stationary_vars,:)' + B*Varinov*dD(stationary_vars,:,jpVi)'; + else + dtmp_jpVi = dA(:,:,jpVi)*E_inovzlag1'*D(stationary_vars,:)' + A*dE_inovzlag1(:,:,jpVi)'*D(stationary_vars,:)' + A*E_inovzlag1'*dD(stationary_vars,:,jpVi)'... + + dB(:,:,jpVi)*Varinov*D(stationary_vars,:)' + B*dVarinov(:,:,jpVi)*D(stationary_vars,:)' + B*Varinov*dD(stationary_vars,:,jpVi)'; + end + + for i = 1:nlags + if order <= 2 + dVar_yi(stationary_vars,stationary_vars,i,jpVi) = dC(stationary_vars,:,jpVi)*Ai*tmp + C(stationary_vars,:)*dAi_jpVi*tmp + C(stationary_vars,:)*Ai*dtmp_jpVi; + else + Var_zi = A*Var_zi + B*E_inovzlagi; + dVar_zi_jpVi = dA(:,:,jpVi)*Var_zi + A*dVar_zi_jpVi + dB(:,:,jpVi)*E_inovzlagi + + B*dE_inovzlagi_jpVi; + dhxi_jpVi = dhx(:,:,jpVi)*hxi + hx*dhxi_jpVi; + hxi = hx*hxi; + E_inovzlagi = zeros(inov_nbr,z_nbr); + E_inovzlagi(id_inov6_xf_u_u , id_z1_xf ) = kron(hxi*E_xfxf,E_uu(:)); + E_inovzlagi(id_inov6_xf_u_u , id_z4_xrd ) = kron(hxi*E_xrdxf',E_uu(:)); + E_inovzlagi(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(hxi*reshape(commutation(x_nbr^2,x_nbr)*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu)); + E_inovzlagi(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(hxi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:)); + dE_inovzlagi_jpVi = zeros(inov_nbr,z_nbr); + dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z1_xf ) = kron(dhxi_jpVi*E_xfxf,E_uu(:)) + kron(hxi*dE_xfxf(:,:,jpVi),E_uu(:)) + kron(hxi*E_xfxf,vec(dE_uu(:,:,jpVi))); + dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z4_xrd ) = kron(dhxi_jpVi*E_xrdxf',E_uu(:)) + kron(hxi*dE_xrdxf(:,:,jpVi)',E_uu(:)) + kron(hxi*E_xrdxf',vec(dE_uu(:,:,jpVi))); + dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(dhxi_jpVi*reshape(commutation(x_nbr^2,x_nbr)*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu)) + kron(hxi*reshape(commutation(x_nbr^2,x_nbr)*vec(dE_xsxf_xf(:,:,jpVi)),x_nbr,x_nbr^2),vec(E_uu)) + kron(hxi*reshape(commutation(x_nbr^2,x_nbr)*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(dE_uu(:,:,jpVi))); + dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(dhxi_jpVi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:)) + kron(hxi*reshape(dE_xf_xfxf_xf(:,:,jpVi),x_nbr,x_nbr^3),E_uu(:)) + kron(hxi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),vec(dE_uu(:,:,jpVi))); + dVar_yi(stationary_vars,stationary_vars,i,jpVi) = dC(stationary_vars,:,jpVi)*Var_zi*C(stationary_vars,:)' + C(stationary_vars,:)*dVar_zi_jpVi*C(stationary_vars,:)' + C(stationary_vars,:)*Var_zi*dC(stationary_vars,:,jpVi)'... + + dC(stationary_vars,:,jpVi)*Ai*tmp + C(stationary_vars,:)*dAi_jpVi*tmp + C(stationary_vars,:)*Ai*dtmp_jpVi... + + dD(stationary_vars,:,jpVi)*E_inovzlagi*C(stationary_vars,:)' + D(stationary_vars,:)*dE_inovzlagi_jpVi*C(stationary_vars,:)' + D(stationary_vars,:)*E_inovzlagi*dC(stationary_vars,:,jpVi)'; + end + if useautocorr + dCorr_yi(stationary_vars,stationary_vars,i,jpVi) = (dVar_yi(stationary_vars,stationary_vars,i,jpVi).*sy-dsy.*Var_yi(stationary_vars,stationary_vars,i))./(sy.*sy); + end + dAi_jpVi = dAi_jpVi*A + Ai*dA(:,:,jpVi); + Ai = Ai*A; + end + end +end + + +%% Mean of control variables +E_z = E_xf; +if order > 1 + E_z = [E_xf;E_xs;E_xfxf(:)]; +end +if order > 2 + E_xf_xs = zeros(x_nbr^2,1); + E_xf_xf_xf = zeros(x_nbr^3,1); + E_z = [E_xf;E_xs;E_xfxf(:);E_xrd;E_xf_xs;E_xf_xf_xf]; +end +E_y = Yss(indy,:) + C*E_z + d; + +if compute_derivs + dE_y = zeros(y_nbr,totparam_nbr); + for jpE = 1:totparam_nbr + if order == 1 + dE_z_jpE = dE_xf(:,jpE); + elseif order == 2 + dE_z_jpE = [dE_xf(:,jpE);dE_xs(:,jpE);vec(dE_xfxf(:,:,jpE))]; + elseif order == 3 + dE_xf_xs_jpE = zeros(x_nbr^2,1); + dE_xf_xf_xf_jpE = zeros(x_nbr^3,1); + dE_z_jpE = [dE_xf(:,jpE);dE_xs(:,jpE);vec(dE_xfxf(:,:,jpE)); dE_xrd(:,jpE); dE_xf_xs_jpE; dE_xf_xf_xf_jpE]; + end + dE_y(:,jpE) = dC(:,:,jpE)*E_z + C*dE_z_jpE + dd(:,jpE); + if jpE > (stderrparam_nbr+corrparam_nbr) + dE_y(:,jpE) = dE_y(:,jpE) + dYss(indy,jpE-stderrparam_nbr-corrparam_nbr); %add steady state + end + end +end +non_stationary_vars = setdiff(1:y_nbr,stationary_vars); +E_y(non_stationary_vars) = NaN; +if compute_derivs + dE_y(non_stationary_vars,:) = NaN; +end + +%% Store into output structure +pruned_state_space.indx = indx; +pruned_state_space.indy = indy; +pruned_state_space.A = A; +pruned_state_space.B = B; +pruned_state_space.C = C; +pruned_state_space.D = D; +pruned_state_space.c = c; +pruned_state_space.d = d; +pruned_state_space.Varinov = Varinov; +pruned_state_space.Var_z = Var_z; %remove in future [@wmutschl] +pruned_state_space.Var_y = Var_y; +pruned_state_space.Var_yi = Var_yi; +if useautocorr + pruned_state_space.Corr_y = Corr_y; + pruned_state_space.Corr_yi = Corr_yi; +end +pruned_state_space.E_y = E_y; + +if compute_derivs == 1 + pruned_state_space.dA = dA; + pruned_state_space.dB = dB; + pruned_state_space.dC = dC; + pruned_state_space.dD = dD; + pruned_state_space.dc = dc; + pruned_state_space.dd = dd; + pruned_state_space.dVarinov = dVarinov; + pruned_state_space.dVar_y = dVar_y; + pruned_state_space.dVar_yi = dVar_yi; + if useautocorr + pruned_state_space.dCorr_y = dCorr_y; + pruned_state_space.dCorr_yi = dCorr_yi; + end + pruned_state_space.dE_y = dE_y; +end diff --git a/matlab/quadruplication.m b/matlab/quadruplication.m new file mode 100644 index 000000000..2d47fe740 --- /dev/null +++ b/matlab/quadruplication.m @@ -0,0 +1,92 @@ +function [QP,QPinv] = quadruplication(p) +% Computes the Quadruplication Matrix QP (and its Moore-Penrose inverse) +% such that for any p-dimensional vector x: +% y=kron(kron(kron(x,x),x),x)=QP*z +% where z is of dimension np=p*(p+1)*(p+2)*(p+3)/2 and is obtained from y +% by removing each second and later occurence of the same element. +% This is a generalization of the Duplication matrix. +% Reference: Meijer (2005) - Matrix algebra for higher order moments. +% Linear Algebra and its Applications, 410,pp. 112-134 +% ========================================================================= +% INPUTS +% * p [integer] size of vector +% ------------------------------------------------------------------------- +% OUTPUTS +% * QP [p^4 by np] Quadruplication matrix +% * QPinv [np by np] Moore-Penrose inverse of QP +% ------------------------------------------------------------------------- +% This function is called by +% * pruned_state_space_system.m +% ------------------------------------------------------------------------- +% This function calls +% * mue (embedded) +% * uperm +% ========================================================================= +% Copyright (C) 2020 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 . +% ========================================================================= +np = p*(p+1)*(p+2)*(p+3)/24; +QP = spalloc(p^4,np,p^4); +if nargout > 1 + QPinv = spalloc(np,np,p^4); +end +counti = 1; +for l=1:p + for k=l:p + for j=k:p + for i=j:p + idx = uperm([i j k l]); + for r = 1:size(idx,1) + ii = idx(r,1); jj= idx(r,2); kk=idx(r,3); ll=idx(r,4); + n = ii + (jj-1)*p + (kk-1)*p^2 + (ll-1)*p^3; + m = mue(p,i,j,k,l); + QP(n,m)=1; + if nargout > 1 + if i==j && j==k && k==l + QPinv(m,n)=1; + elseif i==j && j==k && k>l + QPinv(m,n)=1/4; + elseif i>j && j==k && k==l + QPinv(m,n)=1/4; + elseif i==j && j>k && k==l + QPinv(m,n) = 1/6; + elseif i>j && j>k && k==l + QPinv(m,n) = 1/12; + elseif i>j && j==k && k>l + QPinv(m,n) = 1/12; + elseif i==j && j>k && k>l + QPinv(m,n) = 1/12; + elseif i>j && j>k && k>l + QPinv(m,n) = 1/24; + end + end + end + counti = counti+1; + end + end + end +end +%QPinv = (transpose(QP)*QP)\transpose(QP); + +function m = mue(p,i,j,k,l) + % Auxiliary expression, see page 118 of Meijer (2005) + m = i + (j-1)*p + 1/2*(k-1)*p^2 + 1/6*(l-1)*p^3 - 1/2*j*(j-1) + 1/6*k*(k-1)*(k-2) - 1/24*l*(l-1)*(l-2)*(l-3) - 1/2*(k-1)^2*p + 1/6*(l-1)^3*p - 1/4*(l-1)*(l-2)*p^2 - 1/4*l*(l-1)*p + 1/6*(l-1)*p; + m = round(m); +end + + +end \ No newline at end of file diff --git a/matlab/ramsey_policy.m b/matlab/ramsey_policy.m index 0ce386c8a..46acdb854 100644 --- a/matlab/ramsey_policy.m +++ b/matlab/ramsey_policy.m @@ -39,7 +39,7 @@ else end end -[info, oo_, options_] = stoch_simul(M_, options_, oo_, var_list); +[info, oo_, options_, M_] = stoch_simul(M_, options_, oo_, var_list); oo_.steady_state = oo_.dr.ys; diff --git a/matlab/read_data_.m b/matlab/read_data_.m deleted file mode 100644 index d42174115..000000000 --- a/matlab/read_data_.m +++ /dev/null @@ -1,75 +0,0 @@ -function read_data_() -% function read_data_ -% reads endogenous and exogenous variables from a text file -% Used by datafile option in simulate -% -% INPUT -% none -% -% OUTPUT -% none -% -% SPECIAL REQUIREMENT -% none - -% Copyright (C) 2007-2018 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 . - -global options_ M_ oo_; -dname= options_.datafile; - -if size(oo_.endo_simul,2) < M_.maximum_lag+M_.maximum_lead+options_.periods - fid = fopen([dname '_endo.dat'],'r'); - names_line = fgetl(fid); - allVariables = ''; - positions = ones(0); - while (any(names_line)) - [chopped,names_line] = strtok(names_line); - if isempty(allVariables) - allVariables = chopped; - else - allVariables = char(allVariables, chopped); - end - positions = [positions ; strmatch(chopped,M_.endo_names,'exact')]; - end - Values=fscanf(fid,'%f',inf); - Values=reshape(Values,M_.orig_endo_nbr,size(Values,1)/M_.orig_endo_nbr); - oo_.endo_simul=[Values(positions,:); kron(oo_.steady_state((M_.orig_endo_nbr+1) : M_.endo_nbr , 1) , ones(1 , size(Values, 2)))]; - fclose(fid); -end - -if size(oo_.exo_simul,1) < M_.maximum_lag+M_.maximum_lead+options_.periods - fid = fopen([dname '_exo.dat'],'r'); - names_line = fgetl(fid); - allVariables = ''; - positions = ones(0); - while (any(names_line)) - [chopped,names_line] = strtok(names_line); - if isempty(allVariables) - allVariables = chopped; - else - allVariables = char(allVariables, chopped); - end - positions = [positions ; strmatch(chopped,M_.exo_names,'exact')]; - end - Values=fscanf(fid,'%f',inf); - Values=reshape(Values,M_.exo_nbr,size(Values,1)/M_.exo_nbr); - oo_.exo_simul=(Values(positions,:))'; - fclose(fid); -end - -end \ No newline at end of file diff --git a/matlab/realtime_shock_decomposition.m b/matlab/realtime_shock_decomposition.m index 4160c10fc..6686d5c8e 100644 --- a/matlab/realtime_shock_decomposition.m +++ b/matlab/realtime_shock_decomposition.m @@ -22,7 +22,7 @@ function oo_ = realtime_shock_decomposition(M_,oo_,options_,varlist,bayestopt_,e % SPECIAL REQUIREMENTS % none -% Copyright (C) 2009-2019 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -39,6 +39,20 @@ function oo_ = realtime_shock_decomposition(M_,oo_,options_,varlist,bayestopt_,e % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . + +if isfield(oo_,'shock_decomposition_info') && isfield(oo_.shock_decomposition_info,'i_var') + if isfield (oo_,'realtime_conditional_shock_decomposition') ... + || isfield (oo_,'realtime_forecast_shock_decomposition') ... + || isfield (oo_,'realtime_shock_decomposition') ... + || isfield (oo_,'shock_decomposition') ... + || isfield (oo_,'conditional_shock_decomposition') ... + || isfield (oo_,'initval_decomposition') + error('realtime_shock_decomposition::squeezed shock decompositions are already stored in oo_') + end +end + +with_epilogue = options_.shock_decomp.with_epilogue; + % indices of endogenous variables if isempty(varlist) varlist = M_.endo_names(1:M_.orig_endo_nbr); @@ -68,9 +82,10 @@ if isempty(parameter_set) end end -presample = max(1,options_.presample); +presample = max(1,options_.presample-1); if isfield(options_.shock_decomp,'presample') - presample = max(presample,options_.shock_decomp.presample); + my_presample = max(1,options_.shock_decomp.presample); + presample = min(presample,my_presample); end % forecast_=0; forecast_ = options_.shock_decomp.forecast; @@ -87,8 +102,8 @@ end save_realtime = options_.shock_decomp.save_realtime; % array of time points in the range options_.presample+1:options_.nobs -zreal = zeros(endo_nbr,nshocks+2,options_.nobs+forecast_); -zcond = zeros(endo_nbr,nshocks+2,options_.nobs); +zreal = zeros(endo_nbr+length(M_.epilogue_names)*with_epilogue,nshocks+2,options_.nobs+forecast_); +zcond = zeros(endo_nbr+length(M_.epilogue_names)*with_epilogue,nshocks+2,options_.nobs); options_.selected_variables_only = 0; %make sure all variables are stored options_.plot_priors=0; @@ -213,6 +228,12 @@ for j=presample+1:nobs z(:,nshocks+1,i) = z(:,nshocks+2,i) - sum(z(:,1:nshocks,i),2); end + if with_epilogue + [z, epilogue_steady_state] = epilogue_shock_decomposition(z, M_, oo_); + if ~isfield(oo_,'shock_decomposition_info') || ~isfield(oo_.shock_decomposition_info,'epilogue_steady_state') + oo_.shock_decomposition_info.epilogue_steady_state = epilogue_steady_state; + end + end %% conditional shock decomp 1 step ahead z1 = zeros(endo_nbr,nshocks+2); z1(:,end) = Smoothed_Variables_deviation_from_mean(:,gend); @@ -221,6 +242,15 @@ for j=presample+1:nobs z1(:,1:nshocks) = z1(:,1:nshocks) + B(inv_order_var,:).*repmat(epsilon(:,i)',endo_nbr,1); z1(:,nshocks+1) = z1(:,nshocks+2) - sum(z1(:,1:nshocks),2); end + if with_epilogue + clear ztmp0 + ztmp0(:,1,:) = Smoothed_Variables_deviation_from_mean(:,1:gend-1); + ztmp0(:,2,:) = Smoothed_Variables_deviation_from_mean(:,1:gend-1); + ztmp = cat(3,cat(2,zeros(endo_nbr,nshocks,gend-1),ztmp0),z1); +% ztmp = cat(3,zeros(endo_nbr,nshocks+2,40),ztmp); % pad with zeros in presample + z1 = epilogue_shock_decomposition(ztmp, M_, oo_); + z1=squeeze(z1(:,:,end)); + end %% %% conditional shock decomp k step ahead @@ -244,14 +274,27 @@ for j=presample+1:nobs % zn(:,1:nshocks,i) = zn(:,1:nshocks,i) + B(inv_order_var,:).*repmat(epsilon(:,i+gend-forecast_-1)',endo_nbr,1); zn(:,nshocks+1,i) = zn(:,nshocks+2,i) - sum(zn(:,1:nshocks,i),2); end - oo_.conditional_shock_decomposition.(['time_' int2str(j-forecast_)])=zn; + if with_epilogue + clear ztmp0 + ztmp0(:,1,:) = Smoothed_Variables_deviation_from_mean(:,1:gend-forecast_-1); + ztmp0(:,2,:) = Smoothed_Variables_deviation_from_mean(:,1:gend-forecast_-1); + ztmp = cat(3,cat(2,zeros(endo_nbr,nshocks,gend-forecast_-1),ztmp0),zn); +% ztmp = cat(3,zeros(endo_nbr,nshocks+2,40),ztmp); % pad with zeros (st state) in presample + zn = epilogue_shock_decomposition(ztmp, M_, oo_); + zn=squeeze(zn(:,:,end-forecast_:end)); + end + if ismember(j-forecast_,save_realtime) + oo_.conditional_shock_decomposition.(['time_' int2str(j-forecast_)])=zn; + end end %% if init zreal(:,:,1:j) = z(:,:,1:j); - else + elseif jforecast_+presample %% realtime conditional shock decomp k step ahead - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)]) = ... + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)]) = ... zreal(:,:,j-forecast_:j) - ... - oo_.realtime_forecast_shock_decomposition.(['time_' int2str(j-forecast_)]); - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end-1,:) = ... - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end-1,:) + ... - oo_.realtime_forecast_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end,:); - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end,:) = ... + ootmp.realtime_forecast_shock_decomposition.(['time_' int2str(j-forecast_)]); + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end-1,:) = ... + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end-1,:) + ... + ootmp.realtime_forecast_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end,:); + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)])(:,end,:) = ... zreal(:,end,j-forecast_:j); - + if ismember(j-forecast_,save_realtime) + oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)]) = ... + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-forecast_)]); + end if j==nobs for my_forecast_=(forecast_-1):-1:1 - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)]) = ... + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)]) = ... zreal(:,:,j-my_forecast_:j) - ... - oo_.realtime_forecast_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,:,1:my_forecast_+1); - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end-1,:) = ... - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end-1,:) + ... - oo_.realtime_forecast_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end,1:my_forecast_+1); - oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end,:) = ... + ootmp.realtime_forecast_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,:,1:my_forecast_+1); + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end-1,:) = ... + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end-1,:) + ... + ootmp.realtime_forecast_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end,1:my_forecast_+1); + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)])(:,end,:) = ... zreal(:,end,j-my_forecast_:j); + if ismember(j-my_forecast_,save_realtime) + oo_.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)]) = ... + ootmp.realtime_conditional_shock_decomposition.(['time_' int2str(j-my_forecast_)]); + end end end @@ -303,5 +357,6 @@ oo_.conditional_shock_decomposition.pool = zcond; if forecast_ oo_.realtime_forecast_shock_decomposition.pool = zfrcst; end +oo_.gui.ran_realtime_shock_decomposition = true; skipline() diff --git a/matlab/resid.m b/matlab/resid.m index 716c9c5b3..1f3743a07 100644 --- a/matlab/resid.m +++ b/matlab/resid.m @@ -12,7 +12,7 @@ function z = resid(junk) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2018 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -79,8 +79,7 @@ if options_.block && ~options_.bytecode z(idx) = r; end elseif options_.bytecode - [check, z] = bytecode('evaluate','static'); - mexErrCheck('bytecode', check); + z = bytecode('evaluate','static'); else z = feval([M_.fname '.static'],... oo_.steady_state,... diff --git a/matlab/selec_posterior_draws.m b/matlab/selec_posterior_draws.m index 95407609e..11d9a4dad 100644 --- a/matlab/selec_posterior_draws.m +++ b/matlab/selec_posterior_draws.m @@ -115,7 +115,7 @@ if info pdraws(i,1) = {x2(SampleAddress(i,4),:)}; if info-1 set_parameters(pdraws{i,1}); - [dr,info,M_,options_,oo_] = resol(0,M_,options_,oo_); + [dr,info,M_,options_,oo_] =compute_decision_rules(M_,options_,oo_); pdraws(i,2) = { dr }; end old_mhfile = mhfile; diff --git a/matlab/set_default_initial_condition_decomposition_options.m b/matlab/set_default_initial_condition_decomposition_options.m index b0591443c..f354db07d 100644 --- a/matlab/set_default_initial_condition_decomposition_options.m +++ b/matlab/set_default_initial_condition_decomposition_options.m @@ -28,12 +28,19 @@ function options = set_default_initial_condition_decomposition_options(options) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -options.initial_condition_decomp.detail_plot = 0; -options.initial_condition_decomp.steadystate = 0; -options.initial_condition_decomp.write_xls = 0; +options.initial_condition_decomp.colormap = ''; +options.initial_condition_decomp.nodisplay = false; +options.initial_condition_decomp.graph_format = 'eps'; +options.initial_condition_decomp.fig_name = ''; +options.initial_condition_decomp.detail_plot = false; +options.initial_condition_decomp.init2shocks = []; +options.initial_condition_decomp.steadystate = false; +options.initial_condition_decomp.with_epilogue = options.shock_decomp.with_epilogue; +options.initial_condition_decomp.write_xls = false; options.initial_condition_decomp.type = ''; options.initial_condition_decomp.plot_init_date = []; options.initial_condition_decomp.plot_end_date = []; options.initial_condition_decomp.diff = false; options.initial_condition_decomp.flip = false; +options.initial_condition_decomp.max_nrows = 6; end diff --git a/matlab/set_default_option.m b/matlab/set_default_option.m index 43910ba29..a388ca94e 100644 --- a/matlab/set_default_option.m +++ b/matlab/set_default_option.m @@ -41,7 +41,7 @@ if isempty(options.(field)) return end -if ~iscell(options.(field)) && ~isdates(options.(field)) +if ~iscell(options.(field)) && ~isdates(options.(field)) && ~isstruct(options.(field)) if isnan(options.(field)) options.(field) = default; return diff --git a/matlab/set_default_plot_shock_decomposition_options.m b/matlab/set_default_plot_shock_decomposition_options.m index 5ffd23cb5..385884e97 100644 --- a/matlab/set_default_plot_shock_decomposition_options.m +++ b/matlab/set_default_plot_shock_decomposition_options.m @@ -33,6 +33,7 @@ options.plot_shock_decomp.colormap = ''; options.plot_shock_decomp.nodisplay = false; options.plot_shock_decomp.graph_format = 'eps'; options.plot_shock_decomp.detail_plot = false; +options.plot_shock_decomp.init2shocks = []; options.plot_shock_decomp.interactive = false; options.plot_shock_decomp.screen_shocks = false; options.plot_shock_decomp.steadystate = false; @@ -50,4 +51,5 @@ options.plot_shock_decomp.plot_init_date = []; options.plot_shock_decomp.plot_end_date = []; options.plot_shock_decomp.diff = false; options.plot_shock_decomp.flip = false; +options.plot_shock_decomp.max_nrows = 6; end diff --git a/matlab/set_dynare_threads.m b/matlab/set_dynare_threads.m index 300b00c97..753a2b271 100644 --- a/matlab/set_dynare_threads.m +++ b/matlab/set_dynare_threads.m @@ -40,6 +40,8 @@ switch mexname options_.threads.kronecker.sparse_hessian_times_B_kronecker_C = n; case 'local_state_space_iteration_2' options_.threads.local_state_space_iteration_2 = n; + case 'local_state_space_iteration_k' + options_.threads.local_state_space_iteration_2 = n; case 'perfect_foresight_problem' options_.threads.perfect_foresight_problem = n; case 'k_order_perturbation' diff --git a/matlab/set_parameters_locally.m b/matlab/set_parameters_locally.m index 84da8152f..492024daa 100644 --- a/matlab/set_parameters_locally.m +++ b/matlab/set_parameters_locally.m @@ -3,7 +3,7 @@ function M_=set_parameters_locally(M_,xparam1) % function M_out=set_parameters(M_,xparam1) % Sets parameters value (except measurement errors) % This is called for computations such as IRF and forecast -% when measurement errors aren't taken into account; in contrast to +% when measurement errors aren't taken into account; in contrast to % set_parameters.m, the global M_-structure is not altered % % INPUTS diff --git a/matlab/set_prior.m b/matlab/set_prior.m index 5fc1eb374..a8a5c9e7e 100644 --- a/matlab/set_prior.m +++ b/matlab/set_prior.m @@ -112,8 +112,8 @@ if ncx bayestopt_.name = [bayestopt_.name; cell(ncx, 1)]; for i = 1:ncx bayestopt_.name(baseid+i) = {sprintf('corr %s, %s', ... - M_.exo_names{estim_params_.corrx(i,1)}, ... - M_.exo_names{estim_params_.corrx(i,2)})}; + M_.exo_names{estim_params_.corrx(i,1)}, ... + M_.exo_names{estim_params_.corrx(i,2)})}; end end if ncn @@ -236,7 +236,7 @@ for i=1:length(k) else problem_parameters=[problem_parameters ', ' bayestopt_.name{k(i)}]; end - end + end bayestopt_.p3(k(i)) = bayestopt_.p6(k(i)) ; bayestopt_.p4(k(i)) = bayestopt_.p7(k(i)) ; bayestopt_.p5(k(i)) = NaN ; diff --git a/matlab/shock_decomposition.m b/matlab/shock_decomposition.m index 2793b1a9e..3ecd08531 100644 --- a/matlab/shock_decomposition.m +++ b/matlab/shock_decomposition.m @@ -23,7 +23,7 @@ function [oo_,M_] = shock_decomposition(M_,oo_,options_,varlist,bayestopt_,estim % SPECIAL REQUIREMENTS % none -% Copyright (C) 2009-2019 Dynare Team +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -41,6 +41,18 @@ function [oo_,M_] = shock_decomposition(M_,oo_,options_,varlist,bayestopt_,estim % along with Dynare. If not, see . % indices of endogenous variables + +if isfield(oo_,'shock_decomposition_info') && isfield(oo_.shock_decomposition_info,'i_var') + if isfield (oo_,'realtime_conditional_shock_decomposition') ... + || isfield (oo_,'realtime_forecast_shock_decomposition') ... + || isfield (oo_,'realtime_shock_decomposition') ... + || isfield (oo_,'conditional_shock_decomposition') ... + || isfield (oo_,'initval_decomposition') + error('shock_decomposition::squeezed shock decompositions are already stored in oo_') + end +end +with_epilogue = options_.shock_decomp.with_epilogue; + if isempty(varlist) varlist = M_.endo_names(1:M_.orig_endo_nbr); end @@ -120,8 +132,14 @@ for i=1:gend z(:,nshocks+1,i) = z(:,nshocks+2,i) - sum(z(:,1:nshocks,i),2); end +if with_epilogue + [z, oo_.shock_decomposition_info.epilogue_steady_state] = epilogue_shock_decomposition(z, M_, oo_); +end + oo_.shock_decomposition = z; if ~options_.no_graph.shock_decomposition - plot_shock_decomposition(M_,oo_,options_,varlist); -end \ No newline at end of file + oo_ = plot_shock_decomposition(M_,oo_,options_,varlist); +end + +oo_.gui.ran_shock_decomposition = true; diff --git a/matlab/simult_.m b/matlab/simult_.m index e3ec1ec31..508af26e4 100644 --- a/matlab/simult_.m +++ b/matlab/simult_.m @@ -17,7 +17,7 @@ function y_=simult_(M_,options_,y0,dr,ex_,iorder) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2001-2019 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -53,10 +53,9 @@ end if options_.k_order_solver && ~options_.pruning % Call dynare++ routines. ex_ = [zeros(M_.maximum_lag,M_.exo_nbr); ex_]; - [err, y_] = dynare_simul_(options_.order,M_.nstatic,M_.npred,M_.nboth,M_.nfwrd,exo_nbr, ... - y_(dr.order_var,1),ex_',M_.Sigma_e,options_.DynareRandomStreams.seed, ... - dr.ys(dr.order_var),dr); - mexErrCheck('dynare_simul_', err); + y_ = dynare_simul_(options_.order,M_.nstatic,M_.npred,M_.nboth,M_.nfwrd,exo_nbr, ... + y_(dr.order_var,1),ex_',M_.Sigma_e,options_.DynareRandomStreams.seed, ... + dr.ys(dr.order_var),dr); y_(dr.order_var,:) = y_; else if options_.block @@ -98,12 +97,9 @@ else yhat1 = y__(order_var(k2))-dr.ys(order_var(k2)); yhat2 = y_(order_var(k2),i-1)-dr.ys(order_var(k2)); epsilon = ex_(i-1,:)'; - [abcOut1, err] = A_times_B_kronecker_C(.5*dr.ghxx,yhat1); - mexErrCheck('A_times_B_kronecker_C', err); - [abcOut2, err] = A_times_B_kronecker_C(.5*dr.ghuu,epsilon); - mexErrCheck('A_times_B_kronecker_C', err); - [abcOut3, err] = A_times_B_kronecker_C(dr.ghxu,yhat1,epsilon); - mexErrCheck('A_times_B_kronecker_C', err); + abcOut1 = A_times_B_kronecker_C(.5*dr.ghxx,yhat1); + abcOut2 = A_times_B_kronecker_C(.5*dr.ghuu,epsilon); + abcOut3 = A_times_B_kronecker_C(dr.ghxu,yhat1,epsilon); y_(order_var,i) = constant + dr.ghx*yhat2 + dr.ghu*epsilon ... + abcOut1 + abcOut2 + abcOut3; y__(order_var) = dr.ys(order_var) + dr.ghx*yhat1 + dr.ghu*epsilon; @@ -112,12 +108,9 @@ else for i = 2:iter+M_.maximum_lag yhat = y_(order_var(k2),i-1)-dr.ys(order_var(k2)); epsilon = ex_(i-1,:)'; - [abcOut1, err] = A_times_B_kronecker_C(.5*dr.ghxx,yhat); - mexErrCheck('A_times_B_kronecker_C', err); - [abcOut2, err] = A_times_B_kronecker_C(.5*dr.ghuu,epsilon); - mexErrCheck('A_times_B_kronecker_C', err); - [abcOut3, err] = A_times_B_kronecker_C(dr.ghxu,yhat,epsilon); - mexErrCheck('A_times_B_kronecker_C', err); + abcOut1 = A_times_B_kronecker_C(.5*dr.ghxx,yhat); + abcOut2 = A_times_B_kronecker_C(.5*dr.ghuu,epsilon); + abcOut3 = A_times_B_kronecker_C(dr.ghxu,yhat,epsilon); y_(dr.order_var,i) = constant + dr.ghx*yhat + dr.ghu*epsilon ... + abcOut1 + abcOut2 + abcOut3; end @@ -150,30 +143,21 @@ else u = ex_(i-1,:)'; %construct terms of order 2 from second order part, based %on linear component yhat1 - [gyy, err] = A_times_B_kronecker_C(ghxx,yhat1); - mexErrCheck('A_times_B_kronecker_C', err); - [guu, err] = A_times_B_kronecker_C(ghuu,u); - mexErrCheck('A_times_B_kronecker_C', err); - [gyu, err] = A_times_B_kronecker_C(ghxu,yhat1,u); - mexErrCheck('A_times_B_kronecker_C', err); + gyy = A_times_B_kronecker_C(ghxx,yhat1); + guu = A_times_B_kronecker_C(ghuu,u); + gyu = A_times_B_kronecker_C(ghxu,yhat1,u); %construct terms of order 3 from second order part, based %on order 2 component yhat2 - [gyy12, err] = A_times_B_kronecker_C(ghxx,yhat1,yhat2); - mexErrCheck('A_times_B_kronecker_C', err); - [gy2u, err] = A_times_B_kronecker_C(ghxu,yhat2,u); - mexErrCheck('A_times_B_kronecker_C', err); + gyy12 = A_times_B_kronecker_C(ghxx,yhat1,yhat2); + gy2u = A_times_B_kronecker_C(ghxu,yhat2,u); %construct terms of order 3, all based on first order component yhat1 y2a = kron(yhat1,yhat1); - [gyyy, err] = A_times_B_kronecker_C(ghxxx,y2a,yhat1); - mexErrCheck('A_times_B_kronecker_C', err); + gyyy = A_times_B_kronecker_C(ghxxx,y2a,yhat1); u2a = kron(u,u); - [guuu, err] = A_times_B_kronecker_C(ghuuu,u2a,u); - mexErrCheck('A_times_B_kronecker_C', err); + guuu = A_times_B_kronecker_C(ghuuu,u2a,u); yu = kron(yhat1,u); - [gyyu, err] = A_times_B_kronecker_C(ghxxu,yhat1,yu); - mexErrCheck('A_times_B_kronecker_C', err); - [gyuu, err] = A_times_B_kronecker_C(ghxuu,yu,u); - mexErrCheck('A_times_B_kronecker_C', err); + gyyu = A_times_B_kronecker_C(ghxxu,yhat1,yu); + gyuu = A_times_B_kronecker_C(ghxuu,yu,u); %add all terms of order 3, linear component based on third %order yhat3 yhat3 = ghx*yhat3 +gyy12 ... % prefactor is 1/2*2=1, see (65) Appendix Andreasen et al. diff --git a/matlab/slice_sampler.m b/matlab/slice_sampler.m index 8aa18fb1d..827fdc5e4 100644 --- a/matlab/slice_sampler.m +++ b/matlab/slice_sampler.m @@ -55,7 +55,12 @@ npar = length(theta); W1 = sampler_options.W1; neval = zeros(npar,1); -for it=1:npar +% % % fname0=fname; +fname = [ int2str(sampler_options.curr_block)]; + +it=0; +while it= thetaprior(:,1)) && all(theta(:) <= thetaprior(:,2)) + fxold = -feval(objective_function,theta,varargin{:}); + end + end + % restart from 1 + it = 1; + neval(it) = 0; + W = W1(it); + xold = theta(it); + XLB = thetaprior(it,1); + XUB = thetaprior(it,2); + end neval(it) = neval(it) + 1; Z = fxold + log(rand(1,1)); % ------------------------------------------------------------- @@ -79,6 +102,7 @@ for it=1:npar u = rand(1,1); L = max(XLB,xold-W*u); R = min(XUB,L+W); + mytxt{it,1} = ''; while(L > XLB) xsim = L; theta(it) = xsim; @@ -88,7 +112,26 @@ for it=1:npar break end L = max(XLB,L-W); + if neval(it)>30 + L=XLB; + xsim = L; + theta(it) = xsim; + fxl = -feval(objective_function,theta,varargin{:}); + icount = 0; + while (isinf(fxl) || isnan(fxl)) && icount<300 + icount = icount+1; + L=L+sqrt(eps); + xsim = L; + theta(it) = xsim; + fxl = -feval(objective_function,theta,varargin{:}); + end + mytxt{it,1} = sprintf('Getting L for [%s] is taking too long.', varargin{6}.name{it}); + save(['slice_iter_info_' fname],'mytxt','neval','it','theta','fxl') + %keyboard; + end end + neval1 = neval(it); + mytxt{it,2} = ''; while(R < XUB) xsim = R; theta(it) = xsim; @@ -98,11 +141,30 @@ for it=1:npar break end R = min(XUB,R+W); + if neval(it)>(neval1+30) + R=XUB; + xsim = R; + theta(it) = xsim; + fxr = -feval(objective_function,theta,varargin{:}); + icount = 0; + while (isinf(fxr) || isnan(fxr)) && icount<300 + icount = icount+1; + R=R-sqrt(eps); + xsim = R; + theta(it) = xsim; + fxr = -feval(objective_function,theta,varargin{:}); + end + mytxt{it,2} = sprintf('Getting R for [%s] is taking too long.', varargin{6}.name{it}); + save(['slice_iter_info_' fname],'mytxt','neval','it','theta','fxr') + %keyboard; + end end + neval2 = neval(it); % ------------------------------------------------------ % 3. SAMPLING FROM THE SET A = (I INTERSECT S) = (LA,RA) % ------------------------------------------------------ fxsim = Z-1; + mytxt{it,3} = ''; while (fxsim < Z) u = rand(1,1); xsim = L + u*(R - L); @@ -114,8 +176,20 @@ for it=1:npar else L = xsim; end + if (R-L)<1.e-6 %neval(it)>(30+neval2) + disp(sprintf('The sampling for variable [%s] is taking too long as the sampling set is too tight. Check the prior.', varargin{6}.name{it})) + mytxt{it,3} = sprintf('Sampling [%s] is taking too long.', varargin{6}.name{it}); + save(['slice_iter_info_' fname],'mytxt','neval','it') + break + end end + save(['slice_iter_info_' fname],'mytxt','neval','it','theta','fxsim') + if isinf(fxsim) || isnan(fxsim) + theta(it) = xold; + fxsim = fxold; + disp('SLICE: posterior density is infinite. Reset values at initial ones.') + end end if sampler_options.rotated && ~isempty(sampler_options.mode) % jumping diff --git a/matlab/solve_perfect_foresight_model.m b/matlab/solve_perfect_foresight_model.m index cedf3e060..93c5fb26f 100644 --- a/matlab/solve_perfect_foresight_model.m +++ b/matlab/solve_perfect_foresight_model.m @@ -1,6 +1,6 @@ function [flag,endo_simul,err] = solve_perfect_foresight_model(endo_simul,exo_simul,pfm) -% Copyright (C) 2012-2017 Dynare Team +% Copyright (C) 2012-2020 Dynare Team % % This file is part of Dynare. % @@ -33,7 +33,13 @@ if pfm.verbose end if pfm.use_bytecode - [flag, endo_simul]=bytecode(Y, exo_simul, pfm.params); + try + endo_simul=bytecode(Y, exo_simul, pfm.params); + flag = 0; + catch ME + disp(ME.message); + flag = 1; + end return end @@ -120,4 +126,4 @@ if nan_flag end if pfm.verbose disp (['-----------------------------------------------------']) ; -end \ No newline at end of file +end diff --git a/matlab/squeeze_shock_decomposition.m b/matlab/squeeze_shock_decomposition.m new file mode 100644 index 000000000..0dd9f9657 --- /dev/null +++ b/matlab/squeeze_shock_decomposition.m @@ -0,0 +1,98 @@ +function oo_ = squeeze_shock_decomposition(M_,oo_,options_,var_list_) +%function oo_ = squeeze_shock_decomposition(M_,oo_,options_,var_list_) +% INPUTS +% M_: [structure] Definition of the model +% oo_: [structure] Storage of results +% options_: [structure] Options +% var_list_: [cell of char arrays] List of variables +% +% OUTPUTS +% oo_: [structure] Storage of results +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 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 . + +if ~options_.shock_decomp.with_epilogue + endo_names = M_.endo_names; +else + endo_names = [M_.endo_names; M_.epilogue_names]; + +end +if isfield(oo_,'plot_shock_decomposition_info') && isfield(oo_.plot_shock_decomposition_info','i_var') + my_vars = oo_.plot_shock_decomposition_info.i_var; +else + my_vars=[]; +end +if nargin>3 + my_vars = [varlist_indices(var_list_,endo_names); my_vars]; +end +sd_vlist = endo_names(my_vars,:); + +if isfield(options_.plot_shock_decomp,'q2a') && isstruct(options_.plot_shock_decomp.q2a) + + avname={options_.plot_shock_decomp.q2a.qname}; + sda = options_.plot_shock_decomp.q2a(ismember(avname,sd_vlist)); + for k=1:length(sda) + if isstruct(sda(k).aux) + sd_vlist = [sd_vlist; {sda(k).aux.y}]; + end + end +end + +if isempty(sd_vlist) + disp('Nothing has been squeezed: there is no list of variables for it!') + return +end +i_var = varlist_indices(sd_vlist,endo_names); + +oo_.plot_shock_decomposition_info.i_var = i_var; +oo_.shock_decomposition_info.i_var = i_var; +if isfield (oo_,'shock_decomposition') + oo_.shock_decomposition = oo_.shock_decomposition(i_var,:,:); +end +if isfield (oo_,'realtime_conditional_shock_decomposition') + oo_.realtime_conditional_shock_decomposition = ... + my_squeeze(oo_.realtime_conditional_shock_decomposition, i_var); +end +if isfield (oo_,'realtime_forecast_shock_decomposition') + oo_.realtime_forecast_shock_decomposition = ... + my_squeeze(oo_.realtime_forecast_shock_decomposition, i_var); +end +if isfield (oo_,'realtime_shock_decomposition') + oo_.realtime_shock_decomposition = ... + my_squeeze(oo_.realtime_shock_decomposition, i_var); +end +if isfield (oo_,'conditional_shock_decomposition') + oo_.conditional_shock_decomposition = ... + my_squeeze(oo_.conditional_shock_decomposition, i_var); +end +if isfield (oo_,'initval_decomposition') + oo_.initval_decomposition = oo_.initval_decomposition(i_var,:,:); +end + +end + +function shock_decomposition = my_squeeze(shock_decomposition, i_var) +fnam = fieldnames(shock_decomposition); +for k=1:length(fnam) + shock_decomposition.(fnam{k}) = shock_decomposition.(fnam{k})(i_var,:,:); +end + +end diff --git a/matlab/steady.m b/matlab/steady.m index ba8beca7d..cc2502201 100644 --- a/matlab/steady.m +++ b/matlab/steady.m @@ -59,15 +59,15 @@ if info(1) disp('The last values for which a solution was found are:') for i=1:length(ip) fprintf('%12s %12.6f\n',char(M_.param_names(hv(ip(i),2))), ... - M_.params(hv(ip(i),2))) + M_.params(hv(ip(i),2))) end for i=1:length(ix) fprintf('%12s %12.6f\n',char(M_.exo_names(hv(ix(i),2))), ... - oo_.exo_steady_state(hv(ix(i),2))) + oo_.exo_steady_state(hv(ix(i),2))) end for i=1:length(ixd) fprintf('%12s %12.6f\n',char(M_.exo_det_names(hv(ixd(i),2))), ... - oo_.exo_det_steady_state(hv(ixd(i),2))) + oo_.exo_det_steady_state(hv(ixd(i),2))) end if options_.homotopy_force_continue diff --git a/matlab/stoch_simul.m b/matlab/stoch_simul.m index 43e5c068c..3418770fd 100644 --- a/matlab/stoch_simul.m +++ b/matlab/stoch_simul.m @@ -1,6 +1,6 @@ -function [info, oo_, options_] = stoch_simul(M_, options_, oo_, var_list) +function [info, oo_, options_, M_] = stoch_simul(M_, options_, oo_, var_list) -% Copyright (C) 2001-2019 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -38,7 +38,7 @@ if options_.order == 1 options_.replic = 1; end -if M_.hessian_eq_zero && options_.order~=1 +if options_.order~=1 && M_.hessian_eq_zero options_.order = 1; warning('stoch_simul: using order = 1 because Hessian is equal to zero'); end @@ -82,7 +82,7 @@ elseif options_.discretionary_policy if ~options_.linear error('discretionary_policy: only linear-quadratic problems can be solved'); end - [oo_.dr, ~, info] = discretionary_policy_1(oo_,options_.instruments); + [~,info,M_,options_,oo_] = discretionary_policy_1(options_.instruments,M_,options_,oo_); else if options_.logged_steady_state %if steady state was previously logged, undo this oo_.dr.ys=exp(oo_.dr.ys); @@ -201,7 +201,7 @@ end if options_.irf var_listTeX = M_.endo_names_tex(i_var); - if ~options_.nograph + if ~options_.nograph || (TeX && any(strcmp('eps',cellstr(options_.graph_format)))) if ~exist([M_.fname '/graphs'],'dir') mkdir(M_.fname,'graphs'); end @@ -393,3 +393,5 @@ end options_ = options_old; % temporary fix waiting for local options options_.partial_information = 0; + +oo_.gui.ran_stoch_simul = true; diff --git a/matlab/stochastic_solvers.m b/matlab/stochastic_solvers.m index 6dfcb8120..87d88bacf 100644 --- a/matlab/stochastic_solvers.m +++ b/matlab/stochastic_solvers.m @@ -24,7 +24,7 @@ function [dr, info] = stochastic_solvers(dr, task, M_, options_, oo_) % info=6 -> The jacobian matrix evaluated at the steady state is complex. % info=9 -> k_order_pert was unable to compute the solution -% Copyright (C) 1996-2018 Dynare Team +% Copyright (C) 1996-2020 Dynare Team % % This file is part of Dynare. % @@ -48,7 +48,7 @@ if options_.linear end local_order = options_.order; -if M_.hessian_eq_zero && local_order~=1 +if local_order~=1 && M_.hessian_eq_zero local_order = 1; warning('stochastic_solvers: using order = 1 because Hessian is equal to zero'); end @@ -111,8 +111,8 @@ it_ = M_.maximum_lag + 1; z = repmat(dr.ys,1,klen); if local_order == 1 if (options_.bytecode) - [chck, ~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... - M_.params, dr.ys, 1); + [~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... + M_.params, dr.ys, 1); jacobia_ = [loc_dr.g1 loc_dr.g1_x loc_dr.g1_xd]; else [~,jacobia_] = feval([M_.fname '.dynamic'],z(iyr0),exo_simul, ... @@ -120,8 +120,8 @@ if local_order == 1 end elseif local_order == 2 if (options_.bytecode) - [chck, ~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... - M_.params, dr.ys, 1); + [~, loc_dr] = bytecode('dynamic','evaluate', z,exo_simul, ... + M_.params, dr.ys, 1); jacobia_ = [loc_dr.g1 loc_dr.g1_x]; else [~,jacobia_,hessian1] = feval([M_.fname '.dynamic'],z(iyr0),... diff --git a/matlab/th_autocovariances.m b/matlab/th_autocovariances.m index 4b8239043..66169d4a8 100644 --- a/matlab/th_autocovariances.m +++ b/matlab/th_autocovariances.m @@ -42,7 +42,7 @@ function [Gamma_y,stationary_vars] = th_autocovariances(dr,ivar,M_,options_,node % E(x_t) = (I - {g_x}\right)^{- 1} 0.5\left( g_{\sigma\sigma} \sigma^2 + g_{xx} Var(\hat x_t) + g_{uu} Var(u_t) \right) % \] % -% Copyright (C) 2001-2017 Dynare Team +% Copyright (C) 2001-2020 Dynare Team % % This file is part of Dynare. % @@ -68,7 +68,7 @@ if options_.order >= 3 end local_order = options_.order; -if M_.hessian_eq_zero && local_order~=1 +if local_order~=1 && M_.hessian_eq_zero local_order = 1; end @@ -220,7 +220,7 @@ else% ==> Theoretical filters. bb = ghu(iky,:); %S in Uhlig (2001) lambda = options_.hp_filter; - ngrid = options_.hp_ngrid; + ngrid = options_.filtered_theoretical_moments_grid; freqs = 0 : ((2*pi)/ngrid) : (2*pi*(1 - .5/ngrid)); %[0,2*pi) tpos = exp( sqrt(-1)*freqs); %positive frequencies tneg = exp(-sqrt(-1)*freqs); %negative frequencies diff --git a/matlab/unfold_g3.m b/matlab/unfold_g3.m index e25e0eb11..619e181cb 100644 --- a/matlab/unfold_g3.m +++ b/matlab/unfold_g3.m @@ -42,4 +42,3 @@ for k = 1:length(v) end g3_unfolded = sparse(i_unfolded, j_unfolded, v_unfolded, size(g3, 1), size(g3, 2)); - diff --git a/matlab/unfold_g4.m b/matlab/unfold_g4.m new file mode 100644 index 000000000..ba379e855 --- /dev/null +++ b/matlab/unfold_g4.m @@ -0,0 +1,46 @@ +function g4_unfolded = unfold_g4(g4, ny) +% Given the 4th order derivatives stored in a sparse matrix and without +% symmetric elements (as returned by the static/dynamic files) and the number +% of (static or dynamic) variables in the jacobian, returns +% an unfolded version of the same matrix (i.e. with symmetric elements). + +% Copyright (C) 2019 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 . + +[i, j, v] = find(g4); + +i_unfolded = []; +j_unfolded = []; +v_unfolded = []; + +for k = 1:length(v) + l1 = rem(j(k)-1, ny); + j2 = floor((j(k)-1)/ny); + l2 = rem(j2, ny); + j3 = floor((j(k)-1)/ny^2); + l3 = rem(j3,ny); + l4 = floor(j3/ny); + + p = unique(perms([l1 l2 l3 l4]), 'rows'); + np = rows(p); + + i_unfolded = [i_unfolded; repmat(i(k), np, 1)]; + j_unfolded = [j_unfolded; 1 + p(:,1) + ny*(p(:,2) + ny*(p(:,3) + ny*p(:,4)))]; + v_unfolded = [v_unfolded; repmat(v(k), np, 1)]; +end + +g4_unfolded = sparse(i_unfolded, j_unfolded, v_unfolded, size(g4, 1), size(g4, 2)); diff --git a/matlab/uniform_specification.m b/matlab/uniform_specification.m index 544214ca5..19b3b1468 100644 --- a/matlab/uniform_specification.m +++ b/matlab/uniform_specification.m @@ -45,5 +45,5 @@ if ~(isnan(p3) || isnan(p4)) else p6 = m-s*sqrt(3); p7 = m+s*sqrt(3); - + end \ No newline at end of file diff --git a/matlab/uperm.m b/matlab/uperm.m new file mode 100644 index 000000000..3322af96b --- /dev/null +++ b/matlab/uperm.m @@ -0,0 +1,49 @@ +function p = uperm(a) +% Return all unique permutations of possibly-repeating array elements +% ========================================================================= +% Copyright (C) 2014 Bruno Luong +% Copyright (C) 2020 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 . +% ========================================================================= +% Original author: Bruno Luong , April 20, 2014 +% https://groups.google.com/d/msg/comp.soft-sys.matlab/yQKVPTYrv6Q/gw1MzNd9sYkJ +% https://stackoverflow.com/a/42810388 + +[u, ~, J] = unique(a); +p = u(up(J, length(a))); + +function p = up(J, n) +ktab = histc(J,1:max(J)); +l = n; +p = zeros(1, n); +s = 1; +for i=1:length(ktab) + k = ktab(i); + c = nchoosek(1:l, k); + m = size(c,1); + [t, ~] = find(~p.'); + t = reshape(t, [], s); + c = t(c,:)'; + s = s*m; + r = repmat((1:s)',[1 k]); + q = accumarray([r(:) c(:)], i, [s n]); + p = repmat(p, [m 1]) + q; + l = l - k; +end +end + +end % uperm \ No newline at end of file diff --git a/matlab/utilities/dataset/makedataset.m b/matlab/utilities/dataset/makedataset.m index 0e895f0ac..d5140bd41 100644 --- a/matlab/utilities/dataset/makedataset.m +++ b/matlab/utilities/dataset/makedataset.m @@ -40,7 +40,7 @@ function [DynareDataset, DatasetInfo, newdatainterface] = makedataset(DynareOpti % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . - + if nargin<3 gsa_flag = 0; diff --git a/matlab/utilities/general/demean.m b/matlab/utilities/general/demean.m index c56c47367..74c6a5510 100644 --- a/matlab/utilities/general/demean.m +++ b/matlab/utilities/general/demean.m @@ -2,10 +2,10 @@ function c = demean(x) % Removes the mean of each column of a matrix. % -% INPUTS +% INPUTS % - x [double] T*N matrix of data. % -% OUTPUTS +% OUTPUTS % - c [double] T*N matrix of demeaned data. % Copyright (C) 2011-2018 Dynare Team diff --git a/matlab/utilities/graphics/colorspace.m b/matlab/utilities/graphics/colorspace.m index a83aee2ff..c9332ca74 100644 --- a/matlab/utilities/graphics/colorspace.m +++ b/matlab/utilities/graphics/colorspace.m @@ -84,20 +84,27 @@ function varargout = colorspace(Conversion,varargin) % Copyright (C) 2005-2010 Pascal Getreuer % Copyright (C) 2017 Dynare Team % -% This file is part of Dynare. +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are +% met: % -% 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. +% * Redistributions of source code must retain the above copyright +% notice, this list of conditions and the following disclaimer. +% * Redistributions in binary form must reproduce the above copyright +% notice, this list of conditions and the following disclaimer in +% the documentation and/or other materials provided with the distribution % -% 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 . +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +% POSSIBILITY OF SUCH DAMAGE. %%% Input parsing %%% if nargin < 2, error('Not enough input arguments.'); end diff --git a/matlab/utilities/graphics/distinguishable_colors.m b/matlab/utilities/graphics/distinguishable_colors.m index 027ad2cb6..549033c8e 100644 --- a/matlab/utilities/graphics/distinguishable_colors.m +++ b/matlab/utilities/graphics/distinguishable_colors.m @@ -53,24 +53,31 @@ function colors = distinguishable_colors(n_colors,bg,func) % Example using the file exchange's 'colorspace': % func = @(x) colorspace('RGB->Lab',x); % c = distinguishable_colors(25,'w',func); - -% Copyright (C) 2005-2010 2010-2011 by Timothy E. Holy + +% Copyright (C) 2010-2011 by Timothy E. Holy % Copyright (C) 2017 Dynare Team % -% This file is part of Dynare. +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are +% met: % -% 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. +% * Redistributions of source code must retain the above copyright +% notice, this list of conditions and the following disclaimer. +% * Redistributions in binary form must reproduce the above copyright +% notice, this list of conditions and the following disclaimer in +% the documentation and/or other materials provided with the distribution % -% 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 . +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +% POSSIBILITY OF SUCH DAMAGE. % Parse the inputs if (nargin < 2) diff --git a/matlab/variance_decomposition_ME_mc_analysis.m b/matlab/variance_decomposition_ME_mc_analysis.m index d5c873df1..95bf83899 100644 --- a/matlab/variance_decomposition_ME_mc_analysis.m +++ b/matlab/variance_decomposition_ME_mc_analysis.m @@ -58,10 +58,10 @@ end jndx = check_name(exonames,exo); if isempty(jndx) if isequal(exo,'ME') - jndx=size(exonames,1)+1; + jndx=size(exonames,1)+1; else disp([ type '_analysis:: ' exo ' is not a declared exogenous variable!']) - return + return end end diff --git a/matlab/variance_decomposition_mc_analysis.m b/matlab/variance_decomposition_mc_analysis.m index c3acd14a6..ffdc755cb 100644 --- a/matlab/variance_decomposition_mc_analysis.m +++ b/matlab/variance_decomposition_mc_analysis.m @@ -57,10 +57,10 @@ if isempty(indx) end jndx = check_name(exonames,exo); if isempty(jndx) - if ~isequal(exo,'ME') - disp([ type '_analysis:: ' exo ' is not a declared exogenous variable!']) - end - return + if ~isequal(exo,'ME') + disp([ type '_analysis:: ' exo ' is not a declared exogenous variable!']) + end + return end var=deblank(var); diff --git a/matlab/write_latex_parameter_table.m b/matlab/write_latex_parameter_table.m index 8b1b1b98b..521246240 100644 --- a/matlab/write_latex_parameter_table.m +++ b/matlab/write_latex_parameter_table.m @@ -40,7 +40,7 @@ end if ~exist([M_.fname '/latex'],'dir') mkdir(M_.fname,'latex'); end - + fid = fopen([M_.fname, '/latex/' M_.fname '_latex_parameters.tex'], 'w'); fprintf(fid, '\\begin{center}\n'); if Long_names_present==1 diff --git a/mex/build/local_state_space_iterations.am b/mex/build/local_state_space_iterations.am index 714b093eb..645e24b07 100644 --- a/mex/build/local_state_space_iterations.am +++ b/mex/build/local_state_space_iterations.am @@ -1,12 +1,19 @@ -mex_PROGRAMS = local_state_space_iteration_2 +mex_PROGRAMS = local_state_space_iteration_2 local_state_space_iteration_k nodist_local_state_space_iteration_2_SOURCES = local_state_space_iteration_2.cc +nodist_local_state_space_iteration_k_SOURCES = local_state_space_iteration_k.cc local_state_space_iteration_2_CXXFLAGS = $(AM_CXXFLAGS) -fopenmp local_state_space_iteration_2_LDFLAGS = $(AM_LDFLAGS) $(OPENMP_LDFLAGS) -BUILT_SOURCES = $(nodist_local_state_space_iteration_2_SOURCES) -CLEANFILES = $(nodist_local_state_space_iteration_2_SOURCES) +local_state_space_iteration_k_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/../../../dynare++/sylv/cc -I$(top_srcdir)/../../../dynare++/tl/cc -I$(top_srcdir)/../../../dynare++/kord -I$(top_srcdir)/../../../dynare++/utils/cc $(CPPFLAGS_MATIO) +local_state_space_iteration_k_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MATIO) +local_state_space_iteration_k_LDADD = ../libdynare++/libdynare++.a $(LIBADD_MATIO) + +BUILT_SOURCES = $(nodist_local_state_space_iteration_2_SOURCES) \ + $(nodist_local_state_space_iteration_k_SOURCES) +CLEANFILES = $(nodist_local_state_space_iteration_2_SOURCES) \ + $(nodist_local_state_space_iteration_k_SOURCES) %.cc: $(top_srcdir)/../../sources/local_state_space_iterations/%.cc $(LN_S) -f $< $@ diff --git a/mex/build/matlab/Makefile.am b/mex/build/matlab/Makefile.am index b8958c0de..bce39c39c 100644 --- a/mex/build/matlab/Makefile.am +++ b/mex/build/matlab/Makefile.am @@ -1,10 +1,10 @@ ACLOCAL_AMFLAGS = -I ../../../m4 -SUBDIRS = mjdgges kronecker bytecode block_kalman_filter sobol local_state_space_iterations perfect_foresight_problem num_procs block_trust_region +SUBDIRS = mjdgges kronecker bytecode block_kalman_filter sobol perfect_foresight_problem num_procs block_trust_region # libdynare++ must come before gensylv, k_order_perturbation, dynare_simul_ if ENABLE_MEX_DYNAREPLUSPLUS -SUBDIRS += libdynare++ gensylv k_order_perturbation dynare_simul_ +SUBDIRS += libdynare++ gensylv k_order_perturbation dynare_simul_ local_state_space_iterations endif if ENABLE_MEX_MS_SBVAR diff --git a/mex/build/matlab/configure.ac b/mex/build/matlab/configure.ac index eeee28163..95f4c5380 100644 --- a/mex/build/matlab/configure.ac +++ b/mex/build/matlab/configure.ac @@ -18,7 +18,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with Dynare. If not, see . AC_PREREQ([2.62]) -AC_INIT([dynare], [4.6-unstable]) +AC_INIT([dynare], [4.7-unstable]) AC_CONFIG_SRCDIR([configure.ac]) AM_INIT_AUTOMAKE([-Wall -Wno-portability foreign]) diff --git a/mex/build/matlab/mex.am b/mex/build/matlab/mex.am index d4307e3bb..5ba01b723 100644 --- a/mex/build/matlab/mex.am +++ b/mex/build/matlab/mex.am @@ -29,10 +29,6 @@ clean-local: cd $(top_srcdir)/../../matlab && rm -f $(PROGRAMS); \ fi -# Automake provides a default rule for .f08 files, but not .F08. -%.o: %.F08 - $(AM_V_FC)$(FCCOMPILE) $(DEFS) -c -o $@ $< - # Rules for the Fortran 2008 interface to MEX and BLAS/LAPACK functions matlab_mat.mod: matlab_mex.o matlab_mex.mod: matlab_mex.o diff --git a/mex/build/mjdgges.am b/mex/build/mjdgges.am index 6a238c9c6..d9e05a2d2 100644 --- a/mex/build/mjdgges.am +++ b/mex/build/mjdgges.am @@ -1,9 +1,11 @@ mex_PROGRAMS = mjdgges -nodist_mjdgges_SOURCES = mjdgges.cc +nodist_mjdgges_SOURCES = mjdgges.F08 matlab_mex.F08 blas_lapack.F08 BUILT_SOURCES = $(nodist_mjdgges_SOURCES) CLEANFILES = $(nodist_mjdgges_SOURCES) -%.cc: $(top_srcdir)/../../sources/mjdgges/%.cc +mjdgges.o : matlab_mex.mod lapack.mod + +%.F08: $(top_srcdir)/../../sources/mjdgges/%.F08 $(LN_S) -f $< $@ diff --git a/mex/build/octave/Makefile.am b/mex/build/octave/Makefile.am index 7819dd358..a2b6fa124 100644 --- a/mex/build/octave/Makefile.am +++ b/mex/build/octave/Makefile.am @@ -1,10 +1,10 @@ ACLOCAL_AMFLAGS = -I ../../../m4 -SUBDIRS = mjdgges kronecker bytecode block_kalman_filter sobol local_state_space_iterations perfect_foresight_problem num_procs block_trust_region +SUBDIRS = mjdgges kronecker bytecode block_kalman_filter sobol perfect_foresight_problem num_procs block_trust_region # libdynare++ must come before gensylv, k_order_perturbation, dynare_simul_ if ENABLE_MEX_DYNAREPLUSPLUS -SUBDIRS += libdynare++ gensylv k_order_perturbation dynare_simul_ +SUBDIRS += libdynare++ gensylv k_order_perturbation dynare_simul_ local_state_space_iterations endif if ENABLE_MEX_MS_SBVAR diff --git a/mex/build/octave/configure.ac b/mex/build/octave/configure.ac index 435003150..3d7c23536 100644 --- a/mex/build/octave/configure.ac +++ b/mex/build/octave/configure.ac @@ -18,7 +18,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with Dynare. If not, see . AC_PREREQ([2.62]) -AC_INIT([dynare], [4.6-unstable]) +AC_INIT([dynare], [4.7-unstable]) AC_CONFIG_SRCDIR([configure.ac]) AM_INIT_AUTOMAKE([-Wall -Wno-portability foreign]) @@ -33,8 +33,16 @@ FFLAGS="$($MKOCTFILE -p FFLAGS) -Wall" CXXFLAGS="$($MKOCTFILE -p CXXFLAGS) -Wall -Wno-parentheses -Wold-style-cast" LDFLAGS="$($MKOCTFILE -p LFLAGS) $($MKOCTFILE -p LDFLAGS)" +AC_CANONICAL_HOST +case ${host_os} in + darwin*) + CXXFLAGS="$($MKOCTFILE -p ALL_CXXFLAGS) -Wall -Wno-parentheses -Wold-style-cast -O2" + LDFLAGS+="$($MKOCTFILE -p OCTAVE_LIBS)" + ;; +esac + OCTAVE_VERSION=$($MKOCTFILE -v 2>&1 | sed 's/mkoctfile, version //') -AX_COMPARE_VERSION([$OCTAVE_VERSION], [lt], [4.2], [AC_MSG_ERROR([Your Octave is too old, please upgrade to version 4.2 at least (or disable Octave support with --disable-octave).])]) +AX_COMPARE_VERSION([$OCTAVE_VERSION], [lt], [4.4], [AC_MSG_ERROR([Your Octave is too old, please upgrade to version 4.4 at least (or disable Octave support with --disable-octave).])]) AC_PROG_FC AC_PROG_CC diff --git a/mex/build/octave/mex.am b/mex/build/octave/mex.am index f98d1781a..1d8e1088f 100644 --- a/mex/build/octave/mex.am +++ b/mex/build/octave/mex.am @@ -36,10 +36,6 @@ clean-local: cd $(top_srcdir)/../../octave && rm -f $(PROGRAMS); \ fi -# Automake provides a default rule for .f08 files, but not .F08 -%.o: %.F08 - $(AM_V_FC)$(FCCOMPILE) $(DEFS) -c -o $@ $< - # Rules for the Fortran 2008 interface to MEX and BLAS/LAPACK functions matlab_mat.mod: matlab_mex.o matlab_mex.mod: matlab_mex.o diff --git a/mex/sources/Makefile.am b/mex/sources/Makefile.am index a60128206..fe1c95137 100644 --- a/mex/sources/Makefile.am +++ b/mex/sources/Makefile.am @@ -3,6 +3,9 @@ EXTRA_DIST = \ dynlapack.h \ dynumfpack.h \ dynmex.h \ + blas_lapack.F08 \ + defines.F08 \ + matlab_mex.F08 \ mjdgges \ kronecker \ bytecode \ diff --git a/mex/sources/blas_lapack.F08 b/mex/sources/blas_lapack.F08 index 440e10513..a93aff118 100644 --- a/mex/sources/blas_lapack.F08 +++ b/mex/sources/blas_lapack.F08 @@ -1,4 +1,4 @@ -! Copyright © 2019 Dynare Team +! Copyright © 2019-2020 Dynare Team ! ! This file is part of Dynare. ! @@ -20,8 +20,10 @@ module blas #if defined(MATLAB_MEX_FILE) && __SIZEOF_POINTER__ == 8 integer, parameter :: blint = int64 + integer, parameter :: bllog = 8 ! Logical kind, gfortran-specific #else integer, parameter :: blint = int32 + integer, parameter :: bllog = 4 ! Logical kind, gfortran-specific #endif interface @@ -43,10 +45,29 @@ module lapack subroutine dgesv(n, nrhs, a, lda, ipiv, b, ldb, info) import :: blint, real64 integer(blint), intent(in) :: n, nrhs, lda, ldb - real(real64), dimension(*), intent(inout) :: a - real(real64), dimension(*), intent(inout) :: b + real(real64), dimension(*), intent(inout) :: a, b integer(blint), dimension(*), intent(out) :: ipiv integer(blint), intent(out) :: info end subroutine dgesv end interface + + interface + subroutine dgges(jobvsl, jobvsr, sort, selctg, n, a, lda, b, ldb, sdim, & + alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, work, lwork, bwork, & + info) + import :: blint, bllog, real64 + character :: jobvsl, jobvsr, sort + interface + logical(bllog) function selctg(alphar, alphai, beta) + import :: bllog, real64 + real(real64), intent(in) :: alphar, alphai, beta + end function selctg + end interface + integer(blint), intent(in) :: n, lda, ldb, ldvsl, ldvsr, lwork + real(real64), dimension(*), intent(inout) :: a, b + real(real64), dimension(*), intent(out) :: alphar, alphai, beta, vsl, vsr, work + logical(bllog), dimension(*), intent(out) :: bwork + integer(blint), intent(out) :: sdim, info + end subroutine dgges + end interface end module lapack diff --git a/mex/sources/block_kalman_filter/block_kalman_filter.cc b/mex/sources/block_kalman_filter/block_kalman_filter.cc index 4608411c7..0ad1f60c8 100644 --- a/mex/sources/block_kalman_filter/block_kalman_filter.cc +++ b/mex/sources/block_kalman_filter/block_kalman_filter.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2019 Dynare Team + * Copyright © 2007-2020 Dynare Team * * This file is part of Dynare. * @@ -143,10 +143,10 @@ det(const double *F, int dim, const lapack_int *ipiv) BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { - if (nlhs > 3) - DYN_MEX_FUNC_ERR_MSG_TXT("block_kalman_filter provides at most 3 output argument."); + if (nlhs > 2) + mexErrMsgTxt("block_kalman_filter provides at most 2 output argument."); if (nrhs != 13 && nrhs != 16) - DYN_MEX_FUNC_ERR_MSG_TXT("block_kalman_filter requires exactly \n 13 input arguments for standard Kalman filter \nor\n 16 input arguments for missing observations Kalman filter."); + mexErrMsgTxt("block_kalman_filter requires exactly \n 13 input arguments for standard Kalman filter \nor\n 16 input arguments for missing observations Kalman filter."); if (nrhs == 16) missing_observations = true; else @@ -154,13 +154,13 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const if (missing_observations) { if (!mxIsCell(prhs[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("the first input argument of block_missing_observations_kalman_filter must be a Cell Array."); + mexErrMsgTxt("the first input argument of block_missing_observations_kalman_filter must be a Cell Array."); pdata_index = prhs[0]; if (!mxIsDouble(prhs[1])) - DYN_MEX_FUNC_ERR_MSG_TXT("the second input argument of block_missing_observations_kalman_filter must be a scalar."); + mexErrMsgTxt("the second input argument of block_missing_observations_kalman_filter must be a scalar."); number_of_observations = ceil(mxGetScalar(prhs[1])); if (!mxIsDouble(prhs[2])) - DYN_MEX_FUNC_ERR_MSG_TXT("the third input argument of block_missing_observations_kalman_filter must be a scalar."); + mexErrMsgTxt("the third input argument of block_missing_observations_kalman_filter must be a scalar."); no_more_missing_observations = ceil(mxGetScalar(prhs[2])); pT = mxDuplicateArray(prhs[3]); pR = mxDuplicateArray(prhs[4]); @@ -187,9 +187,9 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const pY = mxDuplicateArray(prhs[5]); start = mxGetScalar(prhs[6]); /*Defining the initials values*/ - n = mxGetN(pT); // Number of state variables. - pp = mxGetM(pY); // Maximum number of observed variables. - smpl = mxGetN(pY); // Sample size. ; + n = mxGetN(pT); // Number of state variables. + pp = mxGetM(pY); // Maximum number of observed variables. + smpl = mxGetN(pY); // Sample size. ; mfd = mxGetPr(prhs[7]); kalman_tol = mxGetScalar(prhs[8]); riccati_tol = mxGetScalar(prhs[9]); @@ -204,9 +204,9 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const P = mxGetPr(pP); Y = mxGetPr(pY); - n = mxGetN(pT); // Number of state variables. - pp = mxGetM(pY); // Maximum number of observed variables. - smpl = mxGetN(pY); // Sample size. ; + n = mxGetN(pT); // Number of state variables. + pp = mxGetM(pY); // Maximum number of observed variables. + smpl = mxGetN(pY); // Sample size. ; n_state = n - pure_obs; /*mexPrintf("T\n"); @@ -218,33 +218,33 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const if (missing_observations) if (mxGetNumberOfElements(pdata_index) != static_cast(smpl)) - DYN_MEX_FUNC_ERR_MSG_TXT("the number of element in the cell array passed to block_missing_observation_kalman_filter as first argument has to be equal to the smpl size"); + mexErrMsgTxt("the number of element in the cell array passed to block_missing_observation_kalman_filter as first argument has to be equal to the smpl size"); i_nz_state_var = std::make_unique(n); for (int i = 0; i < n; i++) i_nz_state_var[i] = nz_state_var[i]; - pa = mxCreateDoubleMatrix(n, 1, mxREAL); // State vector. + pa = mxCreateDoubleMatrix(n, 1, mxREAL); // State vector. a = mxGetPr(pa); tmp_a = std::make_unique(n); - dF = 0.0; // det(F). + dF = 0.0; // det(F). p_tmp1 = mxCreateDoubleMatrix(n, n_shocks, mxREAL); tmp1 = mxGetPr(p_tmp1); - t = 0; // Initialization of the time index. - plik = mxCreateDoubleMatrix(smpl, 1, mxREAL); + t = 0; // Initialization of the time index. + plik = mxCreateDoubleMatrix(smpl, 1, mxREAL); lik = mxGetPr(plik); - Inf = mxGetInf(); - LIK = 0.0; // Default value of the log likelihood. - notsteady = true; // Steady state flag. - F_singular = true; + Inf = mxGetInf(); + LIK = 0.0; // Default value of the log likelihood. + notsteady = true; // Steady state flag. + F_singular = true; v_pp = std::make_unique(pp); v_n = std::make_unique(n); mf = std::make_unique(pp); for (int i = 0; i < pp; i++) mf[i] = mfd[i] - 1; - /*compute QQ = R*Q*transpose(R)*/ // Variance of R times the vector of structural innovations.; + /*compute QQ = R*Q*transpose(R)*/ // Variance of R times the vector of structural innovations.; // tmp = R * Q; for (int i = 0; i < n; i++) for (int j = 0; j < n_shocks; j++) @@ -270,9 +270,9 @@ BlockKalmanFilter::BlockKalmanFilter(int nlhs, mxArray *plhs[], int nrhs, const pv = mxCreateDoubleMatrix(pp, 1, mxREAL); v = mxGetPr(pv); - pF = mxCreateDoubleMatrix(pp, pp, mxREAL); + pF = mxCreateDoubleMatrix(pp, pp, mxREAL); F = mxGetPr(pF); - piF = mxCreateDoubleMatrix(pp, pp, mxREAL); + piF = mxCreateDoubleMatrix(pp, pp, mxREAL); iF = mxGetPr(piF); lw = pp * 4; w = std::make_unique(lw); @@ -316,7 +316,7 @@ BlockKalmanFilter::block_kalman_filter_ss() { //v = Y(:,t)-a(mf); for (int i = 0; i < pp; i++) - v[i] = Y[i + t * pp] - a[mf[i]]; + v[i] = Y[i + t * pp] - a[mf[i]]; //a = T*(a+K*v); for (int i = pure_obs; i < n; i++) @@ -375,7 +375,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[]) for (auto i = d_index.begin(); i != d_index.end(); i++) { //mexPrintf("i_i=%d, omp_get_max_threads()=%d\n",i_i,omp_get_max_threads()); - v[i_i] = Y[*i + t * pp] - a[mf[*i]]; + v[i_i] = Y[*i + t * pp] - a[mf[*i]]; i_i++; } @@ -404,7 +404,7 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[]) //v = Y(:,t) - a(mf) for (int i = 0; i < pp; i++) - v[i] = Y[i + t * pp] - a[mf[i]]; + v[i] = Y[i + t * pp] - a[mf[i]]; //F = P(mf,mf) + H; if (H_size == 1) @@ -432,11 +432,11 @@ BlockKalmanFilter::block_kalman_filter(int nlhs, mxArray *plhs[]) mexPrintf("dgecon failure with error %d\n", static_cast(info)); if (rcond < kalman_tol) - if (not_all_abs_F_bellow_crit(F, size_d_index * size_d_index, kalman_tol)) //~all(abs(F(:))= 2) + if (nlhs >= 1) { - plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL); - double *pind = mxGetPr(plhs[1]); + plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); + double *pind = mxGetPr(plhs[0]); pind[0] = LIK; } - if (nlhs == 3) - plhs[2] = plik; + if (nlhs == 2) + plhs[1] = plik; else mxDestroyArray(plik); diff --git a/mex/sources/bytecode/ErrorHandling.hh b/mex/sources/bytecode/ErrorHandling.hh index a3c669986..fbded6d6f 100644 --- a/mex/sources/bytecode/ErrorHandling.hh +++ b/mex/sources/bytecode/ErrorHandling.hh @@ -103,11 +103,11 @@ public: inline double erf(double x) const { - const double a1 = -1.26551223, a2 = 1.00002368, - a3 = 0.37409196, a4 = 0.09678418, - a5 = -0.18628806, a6 = 0.27886807, - a7 = -1.13520398, a8 = 1.48851587, - a9 = -0.82215223, a10 = 0.17087277; + const double a1 = -1.26551223, a2 = 1.00002368, + a3 = 0.37409196, a4 = 0.09678418, + a5 = -0.18628806, a6 = 0.27886807, + a7 = -1.13520398, a8 = 1.48851587, + a9 = -0.82215223, a10 = 0.17087277; double v = 1; double z = abs(x); if (z <= 0) @@ -152,7 +152,7 @@ using namespace std; const int NO_ERROR_ON_EXIT = 0; const int ERROR_ON_EXIT = 1; -typedef vector > code_liste_type; +typedef vector> code_liste_type; typedef code_liste_type::const_iterator it_code_type; class GeneralExceptionHandling @@ -271,7 +271,7 @@ struct s_plan { string var, exo; int var_num, exo_num; - vector > per_value; + vector> per_value; vector value; }; @@ -310,7 +310,7 @@ public: vector jacobian_block, jacobian_other_endo_block, jacobian_exo_block, jacobian_det_exo_block; map TEF; map, double > TEFD; - map >, double > TEFDD; + map>, double > TEFDD; ExpressionType EQN_type; it_code_type it_code_expr; @@ -319,7 +319,7 @@ public: size_t /*unsigned int*/ endo_name_length, exo_name_length, param_name_length; unsigned int EQN_equation, EQN_block, EQN_block_number; unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3; - vector > > Variable_list; + vector>> Variable_list; inline ErrorMsg() @@ -955,7 +955,7 @@ public: Stack.pop(); if (compute) { - x[it_+lag+var*nb_row_x] = Stackf.top(); + x[it_+lag+var*nb_row_x] = Stackf.top(); Stackf.pop(); } break; @@ -1036,7 +1036,7 @@ public: Stack.pop(); if (compute) { - x[var] = Stackf.top(); + x[var] = Stackf.top(); Stackf.pop(); } break; @@ -2134,7 +2134,7 @@ public: #ifdef DEBUG double rr = Stackf.top(); mexPrintf("rr=%f\n", rr); - map >, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); + map>, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); mexPrintf("FSTP TEFDD[make_pair(indx, make_pair(row, col))]=%f done\n", it->second); mexEvalString("drawnow;"); #endif @@ -2157,13 +2157,13 @@ public: #ifdef DEBUG mexPrintf("FLDTEFD\n"); mexPrintf("indx=%d Stack.size()=%d\n", indx, Stack.size()); - map >, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); + map>, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); mexPrintf("FLD TEFD[make_pair(indx, make_pair(row, col))]=%f done\n", it->second); mexEvalString("drawnow;"); #endif if (compute) { - map >, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); + map>, double>::const_iterator it = TEFDD.find(make_pair(indx, make_pair(row-1, col-1))); Stackf.push(it->second); } tmp_out.str(""); diff --git a/mex/sources/bytecode/Evaluate.cc b/mex/sources/bytecode/Evaluate.cc index 2ac731eab..a488a0350 100644 --- a/mex/sources/bytecode/Evaluate.cc +++ b/mex/sources/bytecode/Evaluate.cc @@ -36,7 +36,7 @@ Evaluate::Evaluate() } Evaluate::Evaluate(const int y_size_arg, const int y_kmin_arg, const int y_kmax_arg, const bool print_it_arg, const bool steady_state_arg, const int periods_arg, const int minimal_solving_periods_arg, const double slowc_arg) : - print_it(print_it_arg), minimal_solving_periods(minimal_solving_periods_arg) + print_it(print_it_arg), minimal_solving_periods(minimal_solving_periods_arg) { symbol_table_endo_nbr = 0; Block_List_Max_Lag = 0; @@ -45,7 +45,7 @@ Evaluate::Evaluate(const int y_size_arg, const int y_kmin_arg, const int y_kmax_ block = -1; y_size = y_size_arg; y_kmin = y_kmin_arg; - y_kmax = y_kmax_arg; + y_kmax = y_kmax_arg; periods = periods_arg; steady_state = steady_state_arg; slowc = slowc_arg; @@ -545,7 +545,7 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int case SymbolType::exogenous: var = static_cast(it_code->second)->get_pos(); lag = static_cast(it_code->second)->get_lead_lag(); - x[it_+lag+var*nb_row_x] = Stack.top(); + x[it_+lag+var*nb_row_x] = Stack.top(); #ifdef DEBUG tmp_out << "=>"; mexPrintf(" x[%d, %d](%f)=%s\n", it_+lag, var, x[it_+lag+var*nb_row_x], tmp_out.str().c_str()); @@ -591,7 +591,7 @@ Evaluate::compute_block_time(const int Per_u_, const bool evaluate, /*const int case SymbolType::exogenous: case SymbolType::exogenousDet: var = static_cast(it_code->second)->get_pos(); - x[var] = Stack.top(); + x[var] = Stack.top(); #ifdef DEBUG tmp_out << "=>"; mexPrintf(" x[%d, %d](%f)=%s\n", it_+lag, var, x[var], tmp_out.str().c_str()); diff --git a/mex/sources/bytecode/Evaluate.hh b/mex/sources/bytecode/Evaluate.hh index a6aa83da1..84e592411 100644 --- a/mex/sources/bytecode/Evaluate.hh +++ b/mex/sources/bytecode/Evaluate.hh @@ -73,7 +73,7 @@ protected: vector Block_Contain; int size; - int *index_vara; + int *index_vara; bool print_it, forward; int minimal_solving_periods; diff --git a/mex/sources/bytecode/Interpreter.cc b/mex/sources/bytecode/Interpreter.cc index cc11c15af..a9f919885 100644 --- a/mex/sources/bytecode/Interpreter.cc +++ b/mex/sources/bytecode/Interpreter.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2017 Dynare Team + * Copyright © 2007-2020 Dynare Team * * This file is part of Dynare. * @@ -87,9 +87,9 @@ Interpreter::evaluate_a_block(bool initialization) { it_code_type begining; - switch (type) + switch (static_cast(type)) { - case EVALUATE_FORWARD: + case BlockSimulationType::evaluateForward: if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state, */ false); @@ -117,7 +117,7 @@ Interpreter::evaluate_a_block(bool initialization) } } break; - case SOLVE_FORWARD_SIMPLE: + case BlockSimulationType::solveForwardSimple: g1 = static_cast(mxMalloc(size*size*sizeof(double))); test_mxMalloc(g1, __LINE__, __FILE__, __func__, size*size*sizeof(double)); r = static_cast(mxMalloc(size*sizeof(double))); @@ -151,14 +151,14 @@ Interpreter::evaluate_a_block(bool initialization) mxFree(g1); mxFree(r); break; - case SOLVE_FORWARD_COMPLETE: + case BlockSimulationType::solveForwardComplete: if (initialization) { fixe_u(&u, u_count_int, u_count_int); Read_SparseMatrix(bin_base_name, size, 1, 0, 0, false, stack_solve_algo, solve_algo); } #ifdef DEBUG - mexPrintf("in SOLVE_FORWARD_COMPLETE r = mxMalloc(%d*sizeof(double))\n", size); + mexPrintf("in SOLVE FORWARD COMPLETE r = mxMalloc(%d*sizeof(double))\n", size); #endif r = static_cast(mxMalloc(size*sizeof(double))); test_mxMalloc(r, __LINE__, __FILE__, __func__, size*sizeof(double)); @@ -190,7 +190,7 @@ Interpreter::evaluate_a_block(bool initialization) } mxFree(r); break; - case EVALUATE_BACKWARD: + case BlockSimulationType::evaluateBackward: if (steady_state) { compute_block_time(0, true, /*block_num, size, steady_state,*/ false); @@ -218,7 +218,7 @@ Interpreter::evaluate_a_block(bool initialization) } } break; - case SOLVE_BACKWARD_SIMPLE: + case BlockSimulationType::solveBackwardSimple: g1 = static_cast(mxMalloc(size*size*sizeof(double))); test_mxMalloc(g1, __LINE__, __FILE__, __func__, size*size*sizeof(double)); r = static_cast(mxMalloc(size*sizeof(double))); @@ -252,7 +252,7 @@ Interpreter::evaluate_a_block(bool initialization) mxFree(g1); mxFree(r); break; - case SOLVE_BACKWARD_COMPLETE: + case BlockSimulationType::solveBackwardComplete: if (initialization) { fixe_u(&u, u_count_int, u_count_int); @@ -288,8 +288,8 @@ Interpreter::evaluate_a_block(bool initialization) } mxFree(r); break; - case SOLVE_TWO_BOUNDARIES_SIMPLE: - case SOLVE_TWO_BOUNDARIES_COMPLETE: + case BlockSimulationType::solveTwoBoundariesSimple: + case BlockSimulationType::solveTwoBoundariesComplete: if (initialization) { fixe_u(&u, u_count_int, u_count_int); @@ -314,6 +314,8 @@ Interpreter::evaluate_a_block(bool initialization) } mxFree(r); break; + case BlockSimulationType::unknown: + throw FatalExceptionHandling("UNKNOWN block simulation type: impossible case"); } } @@ -329,39 +331,39 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c mexPrintf("simulate_a_block type = %d, periods=%d, y_kmin=%d, y_kmax=%d\n", type, periods, y_kmin, y_kmax); mexEvalString("drawnow;"); #endif - switch (type) + switch (static_cast(type)) { - case EVALUATE_FORWARD: + case BlockSimulationType::evaluateForward: #ifdef DEBUG - mexPrintf("EVALUATE_FORWARD\n"); + mexPrintf("EVALUATE FORWARD\n"); mexEvalString("drawnow;"); #endif evaluate_over_periods(true); break; - case EVALUATE_BACKWARD: + case BlockSimulationType::evaluateBackward: #ifdef DEBUG - mexPrintf("EVALUATE_BACKWARD\n"); + mexPrintf("EVALUATE BACKWARD\n"); mexEvalString("drawnow;"); #endif evaluate_over_periods(false); break; - case SOLVE_FORWARD_SIMPLE: + case BlockSimulationType::solveForwardSimple: #ifdef DEBUG - mexPrintf("SOLVE_FORWARD_SIMPLE size=%d\n", size); + mexPrintf("SOLVE FORWARD SIMPLE size=%d\n", size); mexEvalString("drawnow;"); #endif solve_simple_over_periods(true); break; - case SOLVE_BACKWARD_SIMPLE: + case BlockSimulationType::solveBackwardSimple: #ifdef DEBUG - mexPrintf("SOLVE_BACKWARD_SIMPLE\n"); + mexPrintf("SOLVE BACKWARD SIMPLE\n"); mexEvalString("drawnow;"); #endif solve_simple_over_periods(false); break; - case SOLVE_FORWARD_COMPLETE: + case BlockSimulationType::solveForwardComplete: #ifdef DEBUG - mexPrintf("SOLVE_FORWARD_COMPLETE\n"); + mexPrintf("SOLVE FORWARD COMPLETE\n"); mexEvalString("drawnow;"); #endif if (vector_table_conditional_local.size()) @@ -386,9 +388,9 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c memset(direction, 0, size_of_direction); End_Solver(); break; - case SOLVE_BACKWARD_COMPLETE: + case BlockSimulationType::solveBackwardComplete: #ifdef DEBUG - mexPrintf("SOLVE_BACKWARD_COMPLETE\n"); + mexPrintf("SOLVE BACKWARD COMPLETE\n"); mexEvalString("drawnow;"); #endif if (vector_table_conditional_local.size()) @@ -413,15 +415,15 @@ Interpreter::simulate_a_block(vector_table_conditional_local_type vector_table_c mxFree(u); End_Solver(); break; - case SOLVE_TWO_BOUNDARIES_SIMPLE: - case SOLVE_TWO_BOUNDARIES_COMPLETE: + case BlockSimulationType::solveTwoBoundariesSimple: + case BlockSimulationType::solveTwoBoundariesComplete: #ifdef DEBUG - mexPrintf("SOLVE_TWO_BOUNDARIES\n"); + mexPrintf("SOLVE TWO BOUNDARIES\n"); mexEvalString("drawnow;"); #endif if (steady_state) { - mexPrintf("SOLVE_TWO_BOUNDARIES in a steady state model: impossible case\n"); + mexPrintf("SOLVE TWO BOUNDARIES in a steady state model: impossible case\n"); return ERROR_ON_EXIT; } if (vector_table_conditional_local.size()) @@ -606,13 +608,13 @@ Interpreter::check_for_controlled_exo_validity(FBEGINBLOCK_ *fb, vector vector endogenous = fb->get_endogenous(); for (vector::iterator it = sconstrained_extended_path.begin(); it != sconstrained_extended_path.end(); it++) { - if ((find(endogenous.begin(), endogenous.end(), it->exo_num) != endogenous.end()) && (find(exogenous.begin(), exogenous.end(), it->var_num) == exogenous.end())) + if ((find(endogenous.begin(), endogenous.end(), it->exo_num) != endogenous.end()) && (find(exogenous.begin(), exogenous.end(), it->var_num) == exogenous.end())) { ostringstream tmp; tmp << "\n the conditional forecast involving as constrained variable " << get_variable(SymbolType::endogenous, it->exo_num) << " and as endogenized exogenous " << get_variable(SymbolType::exogenous, it->var_num) << " that do not appear in block=" << Block_Count+1 << ")\n You should not use block in model options\n"; throw FatalExceptionHandling(tmp.str()); } - else if ((find(endogenous.begin(), endogenous.end(), it->exo_num) != endogenous.end()) && (find(exogenous.begin(), exogenous.end(), it->var_num) != exogenous.end()) && ((fb->get_type() == EVALUATE_FORWARD) || (fb->get_type() != EVALUATE_BACKWARD))) + else if ((find(endogenous.begin(), endogenous.end(), it->exo_num) != endogenous.end()) && (find(exogenous.begin(), exogenous.end(), it->var_num) != exogenous.end()) && ((fb->get_type() == static_cast(BlockSimulationType::evaluateForward)) || (fb->get_type() != static_cast(BlockSimulationType::evaluateBackward)))) { ostringstream tmp; tmp << "\n the conditional forecast cannot be implemented for the block=" << Block_Count+1 << ") that has to be evaluated instead to be solved\n You should not use block in model options\n"; @@ -921,9 +923,9 @@ Interpreter::extended_path(string file_name, string bin_basename, bool evaluate, MainLoop(bin_basename, code, evaluate, block, true, true, sconstrained_extended_path, vector_table_conditional_local); for (int j = 0; j < y_size; j++) { - y_save[j + (t + y_kmin) * y_size] = y[ j + (y_kmin) * y_size]; + y_save[j + (t + y_kmin) * y_size] = y[j + y_kmin * y_size]; if (y_kmin > 0) - y[j ] = y[ j + (y_kmin) * y_size]; + y[j] = y[j + y_kmin * y_size]; } for (int j = 0; j < col_x; j++) { @@ -951,7 +953,7 @@ Interpreter::extended_path(string file_name, string bin_basename, bool evaluate, y_save[j + (k + y_kmin) * y_size] = y[ j + ( k - (nb_periods-1) + y_kmin) * y_size]; }*/ for (int i = 0; i < y_size * col_y; i++) - y[i] = y_save[i]; + y[i] = y_save[i]; for (int j = 0; j < col_x * nb_row_x; j++) x[j] = x_save[j]; if (Init_Code->second) diff --git a/mex/sources/bytecode/Mem_Mngr.cc b/mex/sources/bytecode/Mem_Mngr.cc index fae613bc4..9695b24bd 100644 --- a/mex/sources/bytecode/Mem_Mngr.cc +++ b/mex/sources/bytecode/Mem_Mngr.cc @@ -63,7 +63,7 @@ NonZeroElem * Mem_Mngr::mxMalloc_NZE() { long unsigned int i; - if (!Chunk_Stack.empty()) /*An unused block of memory available inside the heap*/ + if (!Chunk_Stack.empty()) /*An unused block of memory available inside the heap*/ { NonZeroElem *p1 = Chunk_Stack.back(); Chunk_Stack.pop_back(); @@ -74,23 +74,23 @@ Mem_Mngr::mxMalloc_NZE() i = CHUNK_heap_pos++; return (NZE_Mem_add[i]); } - else /*We have to allocate extra memory space*/ + else /*We have to allocate extra memory space*/ { CHUNK_SIZE += CHUNK_BLCK_SIZE; Nb_CHUNK++; - NZE_Mem = static_cast(mxMalloc(CHUNK_BLCK_SIZE*sizeof(NonZeroElem))); /*The block of memory allocated*/ + NZE_Mem = static_cast(mxMalloc(CHUNK_BLCK_SIZE*sizeof(NonZeroElem))); /*The block of memory allocated*/ error_msg.test_mxMalloc(NZE_Mem, __LINE__, __FILE__, __func__, CHUNK_BLCK_SIZE*sizeof(NonZeroElem)); NZE_Mem_Allocated.push_back(NZE_Mem); if (!NZE_Mem) mexPrintf("Not enough memory available\n"); if (NZE_Mem_add) { - NZE_Mem_add = static_cast(mxRealloc(NZE_Mem_add, CHUNK_SIZE*sizeof(NonZeroElem *))); /*We have to redefine the size of pointer on the memory*/ + NZE_Mem_add = static_cast(mxRealloc(NZE_Mem_add, CHUNK_SIZE*sizeof(NonZeroElem *))); /*We have to redefine the size of pointer on the memory*/ error_msg.test_mxMalloc(NZE_Mem_add, __LINE__, __FILE__, __func__, CHUNK_SIZE*sizeof(NonZeroElem *)); } else { - NZE_Mem_add = static_cast(mxMalloc(CHUNK_SIZE*sizeof(NonZeroElem *))); /*We have to define the size of pointer on the memory*/ + NZE_Mem_add = static_cast(mxMalloc(CHUNK_SIZE*sizeof(NonZeroElem *))); /*We have to define the size of pointer on the memory*/ error_msg.test_mxMalloc(NZE_Mem_add, __LINE__, __FILE__, __func__, CHUNK_SIZE*sizeof(NonZeroElem *)); } diff --git a/mex/sources/bytecode/Mem_Mngr.hh b/mex/sources/bytecode/Mem_Mngr.hh index 48c65b2d3..b754157fe 100644 --- a/mex/sources/bytecode/Mem_Mngr.hh +++ b/mex/sources/bytecode/Mem_Mngr.hh @@ -60,7 +60,7 @@ private: NonZeroElem *NZE_Mem; vector NZE_Mem_Allocated; int swp_f_b; - fstream SaveCode_swp; + fstream SaveCode_swp; string filename_mem; }; diff --git a/mex/sources/bytecode/SparseMatrix.cc b/mex/sources/bytecode/SparseMatrix.cc index 322b6943f..4af1ffa20 100644 --- a/mex/sources/bytecode/SparseMatrix.cc +++ b/mex/sources/bytecode/SparseMatrix.cc @@ -39,49 +39,49 @@ HINSTANCE hinstLib; # define UMFPACK_INFO 90 # define UMFPACK_CONTROL 20 /* used in all UMFPACK_report_* routines: */ -# define UMFPACK_PRL 0 /* print level */ +# define UMFPACK_PRL 0 /* print level */ /* returned by all routines that use Info: */ # define UMFPACK_OK (0) -# define UMFPACK_STATUS 0 /* UMFPACK_OK, or other result */ +# define UMFPACK_STATUS 0 /* UMFPACK_OK, or other result */ typedef void (*t_umfpack_dl_free_numeric)(void **Numeric); t_umfpack_dl_free_numeric umfpack_dl_free_numeric; typedef void (*t_umfpack_dl_free_symbolic)(void **Symbolic); t_umfpack_dl_free_symbolic umfpack_dl_free_symbolic; typedef int64_t (*t_umfpack_dl_solve)(int64_t sys, - const int64_t Ap [], - const int64_t Ai [], - const double Ax [], - double X [], - const double B [], + const int64_t Ap[], + const int64_t Ai[], + const double Ax[], + double X[], + const double B[], void *Numeric, - const double Control [UMFPACK_CONTROL], - double Info [UMFPACK_INFO]); + const double Control[UMFPACK_CONTROL], + double Info[UMFPACK_INFO]); t_umfpack_dl_solve umfpack_dl_solve; -typedef int64_t (*t_umfpack_dl_numeric)(const int64_t Ap [], - const int64_t Ai [], - const double Ax [], +typedef int64_t (*t_umfpack_dl_numeric)(const int64_t Ap[], + const int64_t Ai[], + const double Ax[], void *Symbolic, void **Numeric, - const double Control [UMFPACK_CONTROL], - double Info [UMFPACK_INFO]); + const double Control[UMFPACK_CONTROL], + double Info[UMFPACK_INFO]); t_umfpack_dl_numeric umfpack_dl_numeric; typedef int64_t (*t_umfpack_dl_symbolic)(int64_t n_row, int64_t n_col, - const int64_t Ap [], - const int64_t Ai [], - const double Ax [], + const int64_t Ap[], + const int64_t Ai[], + const double Ax[], void **Symbolic, - const double Control [UMFPACK_CONTROL], - double Info [UMFPACK_INFO]); + const double Control[UMFPACK_CONTROL], + double Info[UMFPACK_INFO]); t_umfpack_dl_symbolic umfpack_dl_symbolic; -typedef void (*t_umfpack_dl_report_info)(const double Control [UMFPACK_CONTROL], - const double Info [UMFPACK_INFO]); +typedef void (*t_umfpack_dl_report_info)(const double Control[UMFPACK_CONTROL], + const double Info[UMFPACK_INFO]); t_umfpack_dl_report_info umfpack_dl_report_info; -typedef void (*t_umfpack_dl_report_status)(const double Control [UMFPACK_CONTROL], +typedef void (*t_umfpack_dl_report_status)(const double Control[UMFPACK_CONTROL], int64_t status); t_umfpack_dl_report_status umfpack_dl_report_status; -typedef void (*t_umfpack_dl_defaults)(double Control [UMFPACK_CONTROL]); +typedef void (*t_umfpack_dl_defaults)(double Control[UMFPACK_CONTROL]); t_umfpack_dl_defaults umfpack_dl_defaults; #endif @@ -688,7 +688,7 @@ dynSparseMatrix::Simple_Init(int Size, map, int>, int> &IM, var = it4->first.first.second; eq = it4->first.first.first; lag = it4->first.second; - if (lag == 0) /*Build the index for sparse matrix containing the jacobian : u*/ + if (lag == 0) /*Build the index for sparse matrix containing the jacobian : u*/ { NbNZRow[eq]++; NbNZCol[var]++; @@ -796,7 +796,7 @@ dynSparseMatrix::Init_Matlab_Sparse_Simple(int Size, map, in var = it4->first.first.first; if (var != last_var) { - Aj[1+last_var ] = NZE; + Aj[1+last_var] = NZE; last_var = var; } eq = it4->first.second; @@ -894,7 +894,7 @@ dynSparseMatrix::Init_UMFPACK_Sparse_Simple(int Size, map, i ya[eq+it_*y_size] = y[eq+it_*y_size]; } #ifdef DEBUG - unsigned int max_nze = prior_nz;//mxGetNzmax(A_m); + unsigned int max_nze = prior_nz; //mxGetNzmax(A_m); #endif unsigned int NZE = 0; int last_var = 0; @@ -918,7 +918,7 @@ dynSparseMatrix::Init_UMFPACK_Sparse_Simple(int Size, map, i var = it4->first.first.first; if (var != last_var) { - (*Ap)[1+last_var ] = NZE; + (*Ap)[1+last_var] = NZE; last_var = var; } eq = it4->first.second; @@ -980,11 +980,11 @@ dynSparseMatrix::find_exo_num(vector sconstrained_extended_path, int val } int -dynSparseMatrix::find_int_date(vector > per_value, int value) +dynSparseMatrix::find_int_date(vector> per_value, int value) { int res = -1; int i = 0; - for (vector >::iterator it = per_value.begin(); it != per_value.end(); it++, i++) + for (vector>::iterator it = per_value.begin(); it != per_value.end(); it++, i++) if (it->first == value) { res = i; @@ -1158,7 +1158,7 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si throw FatalExceptionHandling(tmp.str()); } #endif - u[k] -= jacob_exo[k + row_x*flip_exo] * x[t+y_kmin+flip_exo*nb_row_x]; + u[k] -= jacob_exo[k + row_x*flip_exo] * x[t+y_kmin+flip_exo*nb_row_x]; } } } @@ -1178,7 +1178,7 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si ti_y_kmax = min(periods-(t +1), y_kmax); int ti_new_y_kmax = min(t, y_kmax); int ti_new_y_kmin = -min(periods-(t+1), y_kmin); - if (lag <= ti_new_y_kmax && lag >= ti_new_y_kmin) /*Build the index for sparse matrix containing the jacobian : u*/ + if (lag <= ti_new_y_kmax && lag >= ti_new_y_kmin) /*Build the index for sparse matrix containing the jacobian : u*/ { #ifdef DEBUG if (index < 0 || index >= u_count_alloc || index > Size + Size*Size) @@ -1248,10 +1248,10 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si throw FatalExceptionHandling(tmp.str()); } #endif - (*b)[eq] += u[index+lag*u_count_init]*y[index_vara[var+Size*(y_kmin+t+lag)]]; + (*b)[eq] += u[index+lag*u_count_init]*y[index_vara[var+Size*(y_kmin+t+lag)]]; } } - else /* ...and store it in the u vector*/ + else /* ...and store it in the u vector*/ { #ifdef DEBUG if (index < 0 || index >= u_count_alloc) @@ -1267,7 +1267,7 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si throw FatalExceptionHandling(tmp.str()); } #endif - (*b)[eq] += u[index]; + (*b)[eq] += u[index]; } it4++; } @@ -1369,7 +1369,7 @@ dynSparseMatrix::Init_CUDA_Sparse_Simple(int Size, map, int> var = it4->first.first.first; if (var != last_var) { - (*Ap)[1+last_var ] = NZE; + (*Ap)[1+last_var] = NZE; last_var = var; } eq = it4->first.second; @@ -1509,7 +1509,7 @@ dynSparseMatrix::Init_CUDA_Sparse(int periods, int y_kmin, int y_kmax, int Size, # endif Host_Ap[1+last_eq + t * Size] = NZE; if (preconditioner == 3 && t == 0) - Host_Ap_tild[1+last_eq ] = NZE_tild; + Host_Ap_tild[1+last_eq] = NZE_tild; last_eq = eq; } var = it4->first.second+Size*t; @@ -1519,7 +1519,7 @@ dynSparseMatrix::Init_CUDA_Sparse(int periods, int y_kmin, int y_kmax, int Size, { ti_y_kmin = -min(t, y_kmin); ti_y_kmax = min(periods-(t + 1), y_kmax); - if ((lag <= ti_y_kmax && lag >= ti_y_kmin) || preconditioner == 3) /*Build the index for sparse matrix containing the jacobian : u*/ + if ((lag <= ti_y_kmax && lag >= ti_y_kmin) || preconditioner == 3) /*Build the index for sparse matrix containing the jacobian : u*/ { # ifdef DEBUG if (index < 0 || index >= u_count_alloc || index > (periods-1)* IM.size() + Size * Size + periods * Size) @@ -1547,7 +1547,7 @@ dynSparseMatrix::Init_CUDA_Sparse(int periods, int y_kmin, int y_kmax, int Size, { if (lag > ti_y_kmax || lag < ti_y_kmin) { - Host_b[eq + t * Size] += u[index]*y[index_vara[var+Size*(y_kmin+lag)]]; + Host_b[eq + t * Size] += u[index]*y[index_vara[var+Size*(y_kmin+lag)]]; to_store = false; } if (t == 0) @@ -1593,10 +1593,10 @@ dynSparseMatrix::Init_CUDA_Sparse(int periods, int y_kmin, int y_kmax, int Size, throw FatalExceptionHandling(tmp.str()); } # endif - Host_b[eq + t * Size] += u[index]*y[index_vara[var+Size*(y_kmin+lag)]]; + Host_b[eq + t * Size] += u[index]*y[index_vara[var+Size*(y_kmin+lag)]]; } } - else // ...and store it in the u vector + else // ...and store it in the u vector { # ifdef DEBUG if (index < 0 || index >= u_count_alloc) @@ -1612,7 +1612,7 @@ dynSparseMatrix::Init_CUDA_Sparse(int periods, int y_kmin, int y_kmax, int Size, throw FatalExceptionHandling(tmp.str()); } # endif - Host_b[var] += u[index]; + Host_b[var] += u[index]; } it4++; } @@ -1680,15 +1680,15 @@ dynSparseMatrix::Init_CUDA_Sparse(int periods, int y_kmin, int y_kmax, int Size, } cudaChk(cudaMalloc((void **) A_tild, preconditioner_size * sizeof(double)), " in Init_Cuda_Sparse, can't allocate A_tild on the graphic card\n"); - cudaChk(cudaMemcpy(*x0, Host_x0, n * sizeof(double), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy x0 = Host_x0 failed"); - cudaChk(cudaMemcpy(*b, Host_b, n * sizeof(double), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy b = Host_b failed"); - cudaChk(cudaMemcpy(*Ap, Host_Ap, (n + 1) * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ap = Host_Ap failed"); - cudaChk(cudaMemcpy(*Ai, Host_Ai, NZE * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ai = Host_Ai failed"); - cudaChk(cudaMemcpy(*Ax, Host_Ax, NZE * sizeof(double), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ax = Host_Ax failed"); + cudaChk(cudaMemcpy(*x0, Host_x0, n * sizeof(double), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy x0 = Host_x0 failed"); + cudaChk(cudaMemcpy(*b, Host_b, n * sizeof(double), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy b = Host_b failed"); + cudaChk(cudaMemcpy(*Ap, Host_Ap, (n + 1) * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ap = Host_Ap failed"); + cudaChk(cudaMemcpy(*Ai, Host_Ai, NZE * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ai = Host_Ai failed"); + cudaChk(cudaMemcpy(*Ax, Host_Ax, NZE * sizeof(double), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ax = Host_Ax failed"); if (preconditioner == 3) { - cudaChk(cudaMemcpy(*Ap_tild, Host_Ap_tild, (n + 1) * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ap_tild = Host_Ap_tild failed"); - cudaChk(cudaMemcpy(*Ai_tild, Host_Ai_tild, NZE_tild * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ai_tild = Host_Ai_til failed"); + cudaChk(cudaMemcpy(*Ap_tild, Host_Ap_tild, (n + 1) * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ap_tild = Host_Ap_tild failed"); + cudaChk(cudaMemcpy(*Ai_tild, Host_Ai_tild, NZE_tild * sizeof(int), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy Ai_tild = Host_Ai_til failed"); } cudaChk(cudaMemcpy(*A_tild, Host_A_tild, preconditioner_size * sizeof(double), cudaMemcpyHostToDevice), " in Init_CUDA_Sparse, cudaMemcpy A_tild = Host_A_tild failed"); } @@ -1800,7 +1800,7 @@ dynSparseMatrix::Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Siz ti_y_kmax = min(periods-(t +1), y_kmax); int ti_new_y_kmax = min(t, y_kmax); int ti_new_y_kmin = -min(periods-(t+1), y_kmin); - if (lag <= ti_new_y_kmax && lag >= ti_new_y_kmin) /*Build the index for sparse matrix containing the jacobian : u*/ + if (lag <= ti_new_y_kmax && lag >= ti_new_y_kmin) /*Build the index for sparse matrix containing the jacobian : u*/ { #ifdef DEBUG if (index < 0 || index >= u_count_alloc || index > Size + Size*Size) @@ -1842,10 +1842,10 @@ dynSparseMatrix::Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Siz throw FatalExceptionHandling(tmp.str()); } #endif - b[eq] += u[index+lag*u_count_init]*y[index_vara[var+Size*(y_kmin+t+lag)]]; + b[eq] += u[index+lag*u_count_init]*y[index_vara[var+Size*(y_kmin+t+lag)]]; } } - else /* ...and store it in the u vector*/ + else /* ...and store it in the u vector*/ { #ifdef DEBUG if (index < 0 || index >= u_count_alloc) @@ -1861,7 +1861,7 @@ dynSparseMatrix::Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Siz throw FatalExceptionHandling(tmp.str()); } #endif - b[eq] += u[index]; + b[eq] += u[index]; } it4++; } @@ -1941,7 +1941,7 @@ dynSparseMatrix::Init_GE(int periods, int y_kmin, int y_kmax, int Size, mapfirst.second; - if (lag <= ti_y_kmax && lag >= ti_y_kmin) /*Build the index for sparse matrix containing the jacobian : u*/ + if (lag <= ti_y_kmax && lag >= ti_y_kmin) /*Build the index for sparse matrix containing the jacobian : u*/ { nnz++; var += Size*t; @@ -1965,7 +1965,7 @@ dynSparseMatrix::Init_GE(int periods, int y_kmin, int y_kmax, int Size, mapsecond+u_count_init*t; u[b[eq]] += tmp_b; @@ -2062,7 +2062,7 @@ dynSparseMatrix::End_GE(int Size) } bool -dynSparseMatrix::compare(int *save_op, int *save_opa, int *save_opaa, int beg_t, int periods, long int nop4, int Size) +dynSparseMatrix::compare(int *save_op, int *save_opa, int *save_opaa, int beg_t, int periods, long int nop4, int Size) { long int i, j, nop = nop4/2; double r = 0.0; @@ -2981,7 +2981,7 @@ dynSparseMatrix::golden(double ax, double bx, double cx, double tol, double solv } void -dynSparseMatrix::Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned int Size, double slowc_l, bool is_two_boundaries, int it_) +dynSparseMatrix::Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned int Size, double slowc_l, bool is_two_boundaries, int it_) { mxArray *B1, *C1, *A2, *B2, *A3, *b1, *b2; double *b_m_d = mxGetPr(b_m); @@ -3133,7 +3133,7 @@ dynSparseMatrix::Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned in while (A3_var < Size) A3_j[++A3_var] = A3_nze; mxArray *d1 = NULL; - vector > triangular_form; + vector> triangular_form; double sumc = 0, C_sumc = 1000; mxArray *B1_inv = NULL; mxArray *B1_inv_t = NULL; @@ -3255,7 +3255,7 @@ dynSparseMatrix::Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned in } void -dynSparseMatrix::Solve_Matlab_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_) +dynSparseMatrix::Solve_Matlab_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_) { size_t n = mxGetM(A_m); mxArray *z; @@ -3305,12 +3305,12 @@ void dynSparseMatrix::Printfull_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n) { double A[n*n]; - for (int i = 0; i < n*n; i++) + for (int i = 0; i < n*n; i++) A[i] = 0; int k = 0; for (int i = 0; i < n; i++) for (int j = Ap[i]; j < Ap[i+1]; j++) - A[Ai[j] * n + i] = Ax[k++]; + A[Ai[j] * n + i] = Ax[k++]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) @@ -3329,11 +3329,11 @@ dynSparseMatrix::Print_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, doubl } void -dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, vector_table_conditional_local_type vector_table_conditional_local) +dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, vector_table_conditional_local_type vector_table_conditional_local) { SuiteSparse_long status, sys = 0; #ifndef _MSC_VER - double Control [UMFPACK_CONTROL], Info [UMFPACK_INFO], res [n]; + double Control[UMFPACK_CONTROL], Info[UMFPACK_INFO], res[n]; #else double *Control, *Info, *res; Control = (double *) mxMalloc(UMFPACK_CONTROL * sizeof(double)); @@ -3345,7 +3345,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do #endif umfpack_dl_defaults(Control); - Control [UMFPACK_PRL] = 5; + Control[UMFPACK_PRL] = 5; status = 0; if (iter == 0) { @@ -3354,7 +3354,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do { umfpack_dl_report_info(Control, Info); umfpack_dl_report_status(Control, status); - ostringstream Error; + ostringstream Error; Error << " umfpack_dl_symbolic failed\n"; throw FatalExceptionHandling(Error.str()); } @@ -3366,7 +3366,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do { umfpack_dl_report_info(Control, Info); umfpack_dl_report_status(Control, status); - ostringstream Error; + ostringstream Error; Error << " umfpack_dl_numeric failed\n"; throw FatalExceptionHandling(Error.str()); } @@ -3375,7 +3375,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do { umfpack_dl_report_info(Control, Info); umfpack_dl_report_status(Control, status); - ostringstream Error; + ostringstream Error; Error << " umfpack_dl_solve failed\n"; throw FatalExceptionHandling(Error.str()); } @@ -3393,14 +3393,14 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do { int eq = index_vara[i+Size*(y_kmin)]; int flip_exo = vector_table_conditional_local[i].var_exo; - double yy = -(res[i] + x[y_kmin + flip_exo*nb_row_x]); + double yy = -(res[i] + x[y_kmin + flip_exo*nb_row_x]); direction[eq] = 0; x[flip_exo*nb_row_x + y_kmin] += slowc_l * yy; } else { int eq = index_vara[i+Size*(y_kmin)]; - double yy = -(res[i ] + y[eq]); + double yy = -(res[i] + y[eq]); direction[eq] = yy; y[eq] += slowc_l * yy; } @@ -3457,11 +3457,11 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do } void -dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_) +dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_) { SuiteSparse_long status, sys = 0; #ifndef _MSC_VER - double Control [UMFPACK_CONTROL], Info [UMFPACK_INFO], res [n]; + double Control[UMFPACK_CONTROL], Info[UMFPACK_INFO], res[n]; #else double *Control, *Info, *res; Control = (double *) mxMalloc(UMFPACK_CONTROL * sizeof(double)); @@ -3473,7 +3473,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do #endif umfpack_dl_defaults(Control); - Control [UMFPACK_PRL] = 5; + Control[UMFPACK_PRL] = 5; status = 0; if (iter == 0) { @@ -3482,7 +3482,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do { umfpack_dl_report_info(Control, Info); umfpack_dl_report_status(Control, status); - ostringstream Error; + ostringstream Error; Error << " umfpack_dl_symbolic failed\n"; throw FatalExceptionHandling(Error.str()); } @@ -3494,7 +3494,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do { umfpack_dl_report_info(Control, Info); umfpack_dl_report_status(Control, status); - ostringstream Error; + ostringstream Error; Error << " umfpack_dl_numeric failed\n"; throw FatalExceptionHandling(Error.str()); } @@ -3503,7 +3503,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do { umfpack_dl_report_info(Control, Info); umfpack_dl_report_status(Control, status); - ostringstream Error; + ostringstream Error; Error << " umfpack_dl_solve failed\n"; throw FatalExceptionHandling(Error.str()); } @@ -3536,7 +3536,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do } void -dynSparseMatrix::Solve_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_) +dynSparseMatrix::Solve_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_) { SuiteSparse_long n = mxGetM(A_m); @@ -3544,10 +3544,10 @@ dynSparseMatrix::Solve_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double s SuiteSparse_long *Ai = reinterpret_cast(mxGetIr(A_m)); double *Ax = mxGetPr(A_m); - double *B = mxGetPr(b_m); + double *B = mxGetPr(b_m); SuiteSparse_long status, sys = 0; #ifndef _MSC_VER - double Control [UMFPACK_CONTROL], Info [UMFPACK_INFO], res [n]; + double Control[UMFPACK_CONTROL], Info[UMFPACK_INFO], res[n]; #else double *Control, *Info, *res; Control = (double *) mxMalloc(UMFPACK_CONTROL * sizeof(double)); @@ -3600,7 +3600,7 @@ dynSparseMatrix::Solve_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double s #ifdef CUDA void -printM(int n, double *Ax, int *Ap, int *Ai, cusparseMatDescr_t descrA, cusparseHandle_t cusparse_handle) +printM(int n, double *Ax, int *Ap, int *Ai, cusparseMatDescr_t descrA, cusparseHandle_t cusparse_handle) { //cudaError_t cuda_error; //cusparseStatus_t cusparse_status; @@ -3627,8 +3627,8 @@ printM(int n, double *Ax, int *Ap, int *Ai, cusparseMatDescr_t descrA, cusparse void dynSparseMatrix::Solve_CUDA_BiCGStab_Free(double *tmp_vect_host, double *p, double *r, double *v, double *s, double *t, double *y_, double *z, double *tmp_, - int *Ai, double *Ax, int *Ap, double *x0, double *b, double *A_tild, int *A_tild_i, int *A_tild_p/*, double* Lx, int* Li, int* Lp, - double* Ux, int* Ui, int* Up, int* device_n*/, cusparseSolveAnalysisInfo_t infoL, cusparseSolveAnalysisInfo_t infoU, + int *Ai, double *Ax, int *Ap, double *x0, double *b, double *A_tild, int *A_tild_i, int *A_tild_p /*, double* Lx, int* Li, int* Lp, + double* Ux, int* Ui, int* Up, int* device_n*/, cusparseSolveAnalysisInfo_t infoL, cusparseSolveAnalysisInfo_t infoU, cusparseMatDescr_t descrL, cusparseMatDescr_t descrU, int preconditioner) { //cudaError_t cuda_error; @@ -3726,7 +3726,7 @@ Check(int n, double *Ax, int *Ap, int *Ai, double *b, double *x, bool Lower) if (k < i) sum += x[k] * Ax[j]; } - double err = b[i] - sum - x[i]; + double err = b[i] - sum - x[i]; if (abs(err) > 1e-10) mexPrintf("error at i=%d\n", i); } @@ -3742,7 +3742,7 @@ Check(int n, double *Ax, int *Ap, int *Ai, double *b, double *x, bool Lower) if (k >= i) sum += x[k] * Ax[j]; } - double err = b[i] - sum; + double err = b[i] - sum; if (abs(err) > 1e-10) mexPrintf("error at i=%d\n", i); } @@ -3752,11 +3752,11 @@ Check(int n, double *Ax, int *Ap, int *Ai, double *b, double *x, bool Lower) #ifdef CUDA int dynSparseMatrix::Solve_CUDA_BiCGStab(int *Ap, int *Ai, double *Ax, int *Ap_tild, int *Ai_tild, double *A_tild, double *b, double *x0, int n, int Size, double slowc_l, bool is_two_boundaries, - int it_, int nnz, int nnz_tild, int preconditioner, int max_iterations, int block) + int it_, int nnz, int nnz_tild, int preconditioner, int max_iterations, int block) { cusparseSolveAnalysisInfo_t info, infoL, infoU; cusparseMatDescr_t descrL, descrU; - const double tol = 1.0e-6;//1.0e-6; + const double tol = 1.0e-6; //1.0e-6; const double eps = 1.0e-16; double *p, *r, *r0, *v, *s, *t, *y_, *z, *tmp_; int *A_tild_i, *A_tild_p; @@ -4277,14 +4277,14 @@ dynSparseMatrix::Solve_CUDA_BiCGStab(int *Ap, int *Ai, double *Ax, int *Ap_tild, for (int t = 0; t < periods; t++) for (int i = 0; i < Size; i++) { - for (mwIndex l = Ujw_host[i]; l < Ujw_host[i+1]; l++) + for (mwIndex l = Ujw_host[i]; l < Ujw_host[i+1]; l++) { Wi[W_nnz] = Uiw_host[l] + t * Size; pW[W_nnz] = Ux_host[l]; //mexPrintf("Wj[%d] = %d, Wi[%d] = Uiw_host[%d] + t * Size = %d, pW[%d]=%f\n", i + t * Size, Wj[i + t * Size], W_nnz, l, Uiw_host[l] + t * Size, W_nnz, Ux_host[l]); W_nnz++; } - for (mwIndex l = Ljw_host[i]; l < Ljw_host[i+1]; l++) + for (mwIndex l = Ljw_host[i]; l < Ljw_host[i+1]; l++) { if (Liw_host[l] > i) { @@ -4405,7 +4405,7 @@ dynSparseMatrix::Solve_CUDA_BiCGStab(int *Ap, int *Ai, double *Ax, int *Ap_tild, " in Solve_Cuda_BiCGStab, cusparseSetMatDiagType has failed for descrU\n"); int host_nnz_tild; - if (preconditioner == 3) + if (preconditioner == 3) host_nnz_tild = W_nnz; else host_nnz_tild = nnz; @@ -4601,7 +4601,7 @@ dynSparseMatrix::Solve_CUDA_BiCGStab(int *Ap, int *Ai, double *Ax, int *Ap_tild, &tmp2), " in Solve_Cuda_BiCGStab, cublasDnrm2(y_) has failed\n"); mexPrintf("abs(alpha)*tmp1 = %f, alpha = %f, tmp1 = %f, tmp2 = %f, eps = %f\n", abs(alpha)*tmp1, alpha, tmp1, tmp2, eps); - if (abs(alpha)*tmp1 < eps * tmp2) + if (abs(alpha)*tmp1 < eps * tmp2) stagnation++; else stagnation = 0; @@ -4979,7 +4979,7 @@ dynSparseMatrix::Solve_Matlab_BiCGStab(mxArray *A_m, mxArray *b_m, int Size, dou double flags = 2; mxArray *z; z = NULL; - if (steady_state) /*Octave BicStab algorihtm involves a 0 division in case of a preconditionner equal to the LU decomposition of A matrix*/ + if (steady_state) /*Octave BicStab algorihtm involves a 0 division in case of a preconditionner equal to the LU decomposition of A matrix*/ { mxArray *res = mult_SAT_B(Sparse_transpose(A_m), x0_m); double *resid = mxGetPr(res); @@ -5129,7 +5129,7 @@ dynSparseMatrix::Singular_display(int block, int Size) { int k = first->u_index; int jj = first->r_index; - pind[ii * Size + jj ] = u[k]; + pind[ii * Size + jj] = u[k]; first = first->NZE_C_N; } } @@ -5314,8 +5314,8 @@ dynSparseMatrix::Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, i if (markovitz > markovitz_max) { piv = piv_v[j]; - pivj = pivj_v[j]; //Line number - pivk = pivk_v[j]; //positi + pivj = pivj_v[j]; //Line number + pivk = pivk_v[j]; //positi markovitz_max = markovitz; } } @@ -5341,8 +5341,8 @@ dynSparseMatrix::Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, i if (NR[j] == 1) { piv = piv_v[j]; - pivj = pivj_v[j]; //Line number - pivk = pivk_v[j]; //positi + pivj = pivj_v[j]; //Line number + pivk = pivk_v[j]; //positi markovitz_max = markovitz; } } @@ -5588,8 +5588,8 @@ dynSparseMatrix::Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bo if (markovitz > markovitz_max) { piv = piv_v[j]; - pivj = pivj_v[j]; //Line number - pivk = pivk_v[j]; //positi + pivj = pivj_v[j]; //Line number + pivk = pivk_v[j]; //positi markovitz_max = markovitz; NR_max = NR[j]; } @@ -5616,8 +5616,8 @@ dynSparseMatrix::Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bo if (NR[j] == 1) { piv = piv_v[j]; - pivj = pivj_v[j]; //Line number - pivk = pivk_v[j]; //positi + pivj = pivj_v[j]; //Line number + pivk = pivk_v[j]; //positi markovitz_max = markovitz; NR_max = NR[j]; } @@ -6458,7 +6458,6 @@ dynSparseMatrix::solve_linear(const int block_num, const int y_size, const int y void dynSparseMatrix::solve_non_linear(const int block_num, const int y_size, const int y_kmin, const int y_kmax, const int size) - { max_res_idx = 0; bool cvg = false; diff --git a/mex/sources/bytecode/SparseMatrix.hh b/mex/sources/bytecode/SparseMatrix.hh index 953d0a229..017497f6a 100644 --- a/mex/sources/bytecode/SparseMatrix.hh +++ b/mex/sources/bytecode/SparseMatrix.hh @@ -86,7 +86,7 @@ struct t_save_op_s int first, second; }; -const int IFLD = 0; +const int IFLD = 0; const int IFDIV = 1; const int IFLESS = 2; const int IFSUB = 3; @@ -122,7 +122,7 @@ public: double g0, gp0, glambda2; int try_at_iteration; int find_exo_num(vector sconstrained_extended_path, int value); - int find_int_date(vector > per_value, int value); + int find_int_date(vector> per_value, int value); private: void Init_GE(int periods, int y_kmin, int y_kmax, int Size, map, int>, int> &IM); @@ -140,14 +140,14 @@ private: bool golden(double ax, double bx, double cx, double tol, double solve_tolf, double *xmin); void Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bool symbolic, int Block_number); bool Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, int it_); - void Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned int Size, double slowc_l, bool is_two_boundaries, int it_); + void Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned int Size, double slowc_l, bool is_two_boundaries, int it_); void Solve_Matlab_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_); void Print_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, int n); void Printfull_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n); void PrintM(int n, double *Ax, mwIndex *Ap, mwIndex *Ai); - void Solve_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_); - void Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, vector_table_conditional_local_type vector_table_conditional_local); - void Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_); + void Solve_LU_UMFPack(mxArray *A_m, mxArray *b_m, int Size, double slowc_l, bool is_two_boundaries, int it_); + void Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, vector_table_conditional_local_type vector_table_conditional_local); + void Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, double *Ax, double *b, int n, int Size, double slowc_l, bool is_two_boundaries, int it_); void End_Matlab_LU_UMFPack(); #ifdef CUDA @@ -155,7 +155,7 @@ private: int *Ai, double *Ax, int *Ap, double *x0, double *b, double *A_tild, int *A_tild_i, int *A_tild_p, cusparseSolveAnalysisInfo_t infoL, cusparseSolveAnalysisInfo_t infoU, cusparseMatDescr_t descrL, cusparseMatDescr_t descrU, int preconditioner); - int Solve_CUDA_BiCGStab(int *Ap, int *Ai, double *Ax, int *Ap_tild, int *Ai_tild, double *A_tild, double *b, double *x0, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, int nnz, int nnz_tild, int preconditioner, int max_iterations, int block); + int Solve_CUDA_BiCGStab(int *Ap, int *Ai, double *Ax, int *Ap_tild, int *Ai_tild, double *A_tild, double *b, double *x0, int n, int Size, double slowc_l, bool is_two_boundaries, int it_, int nnz, int nnz_tild, int preconditioner, int max_iterations, int block); #endif void Solve_Matlab_GMRES(mxArray *A_m, mxArray *b_m, int Size, double slowc, int block, bool is_two_boundaries, int it_, mxArray *x0_m); void Solve_Matlab_BiCGStab(mxArray *A_m, mxArray *b_m, int Size, double slowc, int block, bool is_two_boundaries, int it_, mxArray *x0_m, int precond); @@ -164,7 +164,7 @@ private: bool solve_linear(const int block_num, const int y_size, const int y_kmin, const int y_kmax, const int size, const int iter); void solve_non_linear(const int block_num, const int y_size, const int y_kmin, const int y_kmax, const int size); string preconditioner_print_out(string s, int preconditioner, bool ss); - bool compare(int *save_op, int *save_opa, int *save_opaa, int beg_t, int periods, long int nop4, int Size + bool compare(int *save_op, int *save_opa, int *save_opaa, int beg_t, int periods, long int nop4, int Size #ifdef PROFILER , long int *ndiv, long int *nsub #endif diff --git a/mex/sources/bytecode/bytecode.cc b/mex/sources/bytecode/bytecode.cc index 971d2704f..31efcd311 100644 --- a/mex/sources/bytecode/bytecode.cc +++ b/mex/sources/bytecode/bytecode.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2017 Dynare Team + * Copyright © 2007-2020 Dynare Team * * This file is part of Dynare. * @@ -21,37 +21,6 @@ #include "ErrorHandling.hh" #include #include -#ifdef DYN_MEX_FUNC_ERR_MSG_TXT -# undef DYN_MEX_FUNC_ERR_MSG_TXT -#endif // DYN_MEX_FUNC_ERR_MSG_TXT - -#define DYN_MEX_FUNC_ERR_MSG_TXT(str) \ - do { \ - mexPrintf("%s\n", str); \ - if (nlhs > 0) \ - { \ - plhs[0] = mxCreateDoubleScalar(1); \ - if (nlhs > 1) \ - { \ - double *pind; \ - plhs[1] = mxCreateDoubleMatrix(int (row_y), int (col_y), mxREAL); \ - pind = mxGetPr(plhs[1]); \ - if (evaluate) \ - { \ - for (unsigned int i = 0; i < row_y*col_y; i++) \ - pind[i] = 0; \ - } \ - else \ - { \ - for (unsigned int i = 0; i < row_y*col_y; i++) \ - pind[i] = yd[i]; \ - } \ - for (int i = 2; i < nlhs; i++) \ - plhs[i] = mxCreateDoubleScalar(1); \ - } \ - } \ - return; \ - } while (0) #ifdef DEBUG_EX @@ -208,7 +177,7 @@ GPU_Test_and_Info(cublasHandle_t *cublas_handle, cusparseHandle_t *cusparse_hand mexPrintf("> Driver version:\n"); int cuda_version; cuda_error = cudaDriverGetVersion(&cuda_version); - if (cuda_error != cudaSuccess) + if (cuda_error != cudaSuccess) { ostringstream tmp; tmp << " cudaGetVersion has failed\n"; @@ -297,7 +266,7 @@ Get_Arguments_and_global_variables(int nrhs, col_y = mxGetN(prhs[i]); break; case 1: - *xd = mxGetPr(prhs[i]); + *xd = mxGetPr(prhs[i]); row_x = mxGetM(prhs[i]); col_x = mxGetN(prhs[i]); break; @@ -349,7 +318,7 @@ Get_Arguments_and_global_variables(int nrhs, pos = pos1 + 1; else pos += 5; - block = atoi(Get_Argument(prhs[i]).substr(pos, string::npos).c_str())-1; + block = atoi(Get_Argument(prhs[i]).substr(pos, string::npos).c_str())-1; } else if (Get_Argument(prhs[i]).substr(0, 13) == "extended_path") { @@ -369,7 +338,7 @@ Get_Arguments_and_global_variables(int nrhs, pos = pos1 + 1; else pos += 6; - *pfplan_struct_name = deblank(Get_Argument(prhs[i]).substr(pos, string::npos)); + *pfplan_struct_name = deblank(Get_Argument(prhs[i]).substr(pos, string::npos)); } else if (Get_Argument(prhs[i]).substr(0, 4) == "plan") { @@ -378,7 +347,7 @@ Get_Arguments_and_global_variables(int nrhs, pos = pos1 + 1; else pos += 4; - *plan_struct_name = deblank(Get_Argument(prhs[i]).substr(pos, string::npos)); + *plan_struct_name = deblank(Get_Argument(prhs[i]).substr(pos, string::npos)); } else { @@ -492,13 +461,13 @@ main(int nrhs, const char *prhs[]) } catch (GeneralExceptionHandling &feh) { - DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str()); + mexErrMsgTxt(feh.GetErrorMsg().c_str()); } if (!count_array_argument) { int field = mxGetFieldNumber(M_, "params"); if (field < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("params is not a field of M_"); + mexErrMsgTxt("params is not a field of M_"); params = mxGetPr(mxGetFieldByNumber(M_, 0, field)); } @@ -510,14 +479,14 @@ main(int nrhs, const char *prhs[]) if (extended_path_struct == NULL) { string tmp = "The 'extended_path' option must be followed by the extended_path descriptor"; - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *date_str = mxGetField(extended_path_struct, 0, "date_str"); if (date_str == NULL) { string tmp = "date_str"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } int nb_periods = mxGetM(date_str) * mxGetN(date_str); @@ -526,28 +495,28 @@ main(int nrhs, const char *prhs[]) { string tmp = "constrained_vars_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *constrained_paths_ = mxGetField(extended_path_struct, 0, "constrained_paths_"); if (constrained_paths_ == NULL) { string tmp = "constrained_paths_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *constrained_int_date_ = mxGetField(extended_path_struct, 0, "constrained_int_date_"); if (constrained_int_date_ == NULL) { string tmp = "constrained_int_date_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *constrained_perfect_foresight_ = mxGetField(extended_path_struct, 0, "constrained_perfect_foresight_"); if (constrained_perfect_foresight_ == NULL) { string tmp = "constrained_perfect_foresight_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *shock_var_ = mxGetField(extended_path_struct, 0, "shock_vars_"); @@ -555,40 +524,40 @@ main(int nrhs, const char *prhs[]) { string tmp = "shock_vars_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *shock_paths_ = mxGetField(extended_path_struct, 0, "shock_paths_"); if (shock_paths_ == NULL) { string tmp = "shock_paths_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *shock_int_date_ = mxGetField(extended_path_struct, 0, "shock_int_date_"); if (shock_int_date_ == NULL) { string tmp = "shock_int_date_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } mxArray *shock_str_date_ = mxGetField(extended_path_struct, 0, "shock_str_date_"); if (shock_str_date_ == NULL) { string tmp = "shock_str_date_"; tmp.insert(0, "The extended_path description structure does not contain the member: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } int nb_constrained = mxGetM(constrained_vars_) * mxGetN(constrained_vars_); int nb_controlled = 0; mxArray *options_cond_fcst_ = mxGetField(extended_path_struct, 0, "options_cond_fcst_"); mxArray *controlled_varexo = NULL; - if (options_cond_fcst_ != NULL) + if (options_cond_fcst_ != NULL) { controlled_varexo = mxGetField(options_cond_fcst_, 0, "controlled_varexo"); nb_controlled = mxGetM(controlled_varexo) * mxGetN(controlled_varexo); if (nb_controlled != nb_constrained) { - DYN_MEX_FUNC_ERR_MSG_TXT("The number of exogenized variables and the number of exogenous controlled variables should be equal."); + mexErrMsgTxt("The number of exogenized variables and the number of exogenous controlled variables should be equal."); } } double *controlled_varexo_value = NULL; @@ -637,7 +606,7 @@ main(int nrhs, const char *prhs[]) string tmp1 = oss.str(); tmp.append(tmp1); tmp.append(")"); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } (sconditional_extended_path[i]).per_value.resize(nb_local_periods); (sconditional_extended_path[i]).value.resize(nb_periods); @@ -680,7 +649,7 @@ main(int nrhs, const char *prhs[]) string tmp1 = oss.str(); tmp.append(tmp1); tmp.append(")"); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } (sextended_path[i]).per_value.resize(nb_local_periods); (sextended_path[i]).value.resize(nb_periods); @@ -702,9 +671,9 @@ main(int nrhs, const char *prhs[]) if (info) { string tmp = "Can not allocated memory to store the date_str in the extended path descriptor"; - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } - dates.push_back(string(buf));//string(Dates[i]); + dates.push_back(string(buf)); //string(Dates[i]); mxFree(buf); } } @@ -715,7 +684,7 @@ main(int nrhs, const char *prhs[]) { string tmp = plan; tmp.insert(0, "Can't find the plan: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } size_t n_plan = mxGetN(plan_struct); splan.resize(n_plan); @@ -726,7 +695,7 @@ main(int nrhs, const char *prhs[]) mxArray *tmp = mxGetField(plan_struct, i, "exo"); if (tmp) { - char name [100]; + char name[100]; mxGetString(tmp, name, 100); splan[i].var = name; SymbolType variable_type = SymbolType::endogenous; @@ -738,13 +707,13 @@ main(int nrhs, const char *prhs[]) string tmp = name; tmp.insert(0, "the variable '"); tmp.append("' defined as var in plan is not an exogenous or a deterministic exogenous\n"); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } } tmp = mxGetField(plan_struct, i, "var"); if (tmp) { - char name [100]; + char name[100]; mxGetString(tmp, name, 100); splan[i].exo = name; SymbolType variable_type; @@ -756,7 +725,7 @@ main(int nrhs, const char *prhs[]) string tmp = name; tmp.insert(0, "the variable '"); tmp.append("' defined as exo in plan is not an endogenous variable\n"); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } } tmp = mxGetField(plan_struct, i, "per_value"); @@ -778,7 +747,7 @@ main(int nrhs, const char *prhs[]) mexPrintf(" plan fliping var=%s (%d) exo=%s (%d) for the following periods and with the following values:\n", it->var.c_str(), it->var_num, it->exo.c_str(), it->exo_num); else mexPrintf(" plan shocks on var=%s for the following periods and with the following values:\n", it->var.c_str()); - for (vector >::iterator it1 = it->per_value.begin(); it1 != it->per_value.end(); it1++) + for (vector>::iterator it1 = it->per_value.begin(); it1 != it->per_value.end(); it1++) { mexPrintf(" %3d %10.5f\n", it1->first, it1->second); } @@ -793,7 +762,7 @@ main(int nrhs, const char *prhs[]) { string tmp = pfplan; tmp.insert(0, "Can't find the pfplan: "); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } size_t n_plan = mxGetN(pfplan_struct); spfplan.resize(n_plan); @@ -804,7 +773,7 @@ main(int nrhs, const char *prhs[]) mxArray *tmp = mxGetField(pfplan_struct, i, "var"); if (tmp) { - char name [100]; + char name[100]; mxGetString(tmp, name, 100); spfplan[i].var = name; SymbolType variable_type = SymbolType::endogenous; @@ -816,13 +785,13 @@ main(int nrhs, const char *prhs[]) string tmp = name; tmp.insert(0, "the variable '"); tmp.append("' defined as var in pfplan is not an exogenous or a deterministic exogenous\n"); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } } tmp = mxGetField(pfplan_struct, i, "exo"); if (tmp) { - char name [100]; + char name[100]; mxGetString(tmp, name, 100); spfplan[i].exo = name; SymbolType variable_type; @@ -834,7 +803,7 @@ main(int nrhs, const char *prhs[]) string tmp = name; tmp.insert(0, "the variable '"); tmp.append("' defined as exo in pfplan is not an endogenous variable\n"); - DYN_MEX_FUNC_ERR_MSG_TXT(tmp.c_str()); + mexErrMsgTxt(tmp.c_str()); } } tmp = mxGetField(pfplan_struct, i, "per_value"); @@ -856,7 +825,7 @@ main(int nrhs, const char *prhs[]) mexPrintf(" plan flipping var=%s (%d) exo=%s (%d) for the following periods and with the following values:\n", it->var.c_str(), it->var_num, it->exo.c_str(), it->exo_num); else mexPrintf(" plan shocks on var=%s (%d) for the following periods and with the following values:\n", it->var.c_str(), it->var_num); - for (vector >::iterator it1 = it->per_value.begin(); it1 != it->per_value.end(); it1++) + for (vector>::iterator it1 = it->per_value.begin(); it1 != it->per_value.end(); it1++) { mexPrintf(" %3d %10.5f\n", it1->first, it1->second); } @@ -866,20 +835,20 @@ main(int nrhs, const char *prhs[]) int field_steady_state = mxGetFieldNumber(oo_, "steady_state"); if (field_steady_state < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("steady_state is not a field of oo_"); + mexErrMsgTxt("steady_state is not a field of oo_"); int field_exo_steady_state = mxGetFieldNumber(oo_, "exo_steady_state"); if (field_exo_steady_state < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("exo_steady_state is not a field of oo_"); + mexErrMsgTxt("exo_steady_state is not a field of oo_"); if (!steady_state) { int field_endo_simul = mxGetFieldNumber(oo_, "endo_simul"); if (field_endo_simul < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("endo_simul is not a field of oo_"); + mexErrMsgTxt("endo_simul is not a field of oo_"); int field_exo_simul = mxGetFieldNumber(oo_, "exo_simul"); if (field_exo_simul < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("exo_simul is not a field of oo_"); + mexErrMsgTxt("exo_simul is not a field of oo_"); if (!count_array_argument) { @@ -897,17 +866,17 @@ main(int nrhs, const char *prhs[]) if (field >= 0) y_kmin = int (floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, field))))); else - DYN_MEX_FUNC_ERR_MSG_TXT("maximum_lag is not a field of M_"); + mexErrMsgTxt("maximum_lag is not a field of M_"); field = mxGetFieldNumber(M_, "maximum_lead"); if (field >= 0) y_kmax = int (floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, field))))); else - DYN_MEX_FUNC_ERR_MSG_TXT("maximum_lead is not a field of M_"); + mexErrMsgTxt("maximum_lead is not a field of M_"); field = mxGetFieldNumber(M_, "maximum_endo_lag"); if (field >= 0) y_decal = max(0, y_kmin-int (floor(*(mxGetPr(mxGetFieldByNumber(M_, 0, field)))))); else - DYN_MEX_FUNC_ERR_MSG_TXT("maximum_endo_lag is not a field of M_"); + mexErrMsgTxt("maximum_endo_lag is not a field of M_"); if (!count_array_argument) { @@ -915,7 +884,7 @@ main(int nrhs, const char *prhs[]) if (field >= 0) periods = int (floor(*(mxGetPr(mxGetFieldByNumber(options_, 0, field))))); else - DYN_MEX_FUNC_ERR_MSG_TXT("options_ is not a field of options_"); + mexErrMsgTxt("options_ is not a field of options_"); } if (!steady_yd) @@ -948,7 +917,7 @@ main(int nrhs, const char *prhs[]) if (field >= 0) verbose = int (*mxGetPr((mxGetFieldByNumber(options_, 0, field)))); else - DYN_MEX_FUNC_ERR_MSG_TXT("verbosity is not a field of options_"); + mexErrMsgTxt("verbosity is not a field of options_"); if (verbose) print_it = true; if (!steady_state) @@ -961,34 +930,34 @@ main(int nrhs, const char *prhs[]) else { if (!steady_state) - DYN_MEX_FUNC_ERR_MSG_TXT("simul is not a field of options_"); + mexErrMsgTxt("simul is not a field of options_"); else - DYN_MEX_FUNC_ERR_MSG_TXT("steady is not a field of options_"); + mexErrMsgTxt("steady is not a field of options_"); } field = mxGetFieldNumber(temporaryfield, "maxit"); if (field < 0) { if (!steady_state) - DYN_MEX_FUNC_ERR_MSG_TXT("maxit is not a field of options_.simul"); + mexErrMsgTxt("maxit is not a field of options_.simul"); else - DYN_MEX_FUNC_ERR_MSG_TXT("maxit is not a field of options_.steady"); + mexErrMsgTxt("maxit is not a field of options_.steady"); } int maxit_ = int (floor(*(mxGetPr(mxGetFieldByNumber(temporaryfield, 0, field))))); field = mxGetFieldNumber(options_, "slowc"); if (field < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("slows is not a field of options_"); + mexErrMsgTxt("slows is not a field of options_"); double slowc = double (*(mxGetPr(mxGetFieldByNumber(options_, 0, field)))); field = mxGetFieldNumber(options_, "markowitz"); if (field < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("markowitz is not a field of options_"); + mexErrMsgTxt("markowitz is not a field of options_"); double markowitz_c = double (*(mxGetPr(mxGetFieldByNumber(options_, 0, field)))); field = mxGetFieldNumber(options_, "minimal_solving_periods"); if (field < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("minimal_solving_periods is not a field of options_"); + mexErrMsgTxt("minimal_solving_periods is not a field of options_"); int minimal_solving_periods = int (*(mxGetPr(mxGetFieldByNumber(options_, 0, field)))); field = mxGetFieldNumber(options_, "stack_solve_algo"); if (field < 0) - DYN_MEX_FUNC_ERR_MSG_TXT("stack_solve_algo is not a field of options_"); + mexErrMsgTxt("stack_solve_algo is not a field of options_"); int stack_solve_algo = int (*(mxGetPr(mxGetFieldByNumber(options_, 0, field)))); int solve_algo; double solve_tolf; @@ -999,12 +968,12 @@ main(int nrhs, const char *prhs[]) if (field >= 0) solve_algo = int (*(mxGetPr(mxGetFieldByNumber(options_, 0, field)))); else - DYN_MEX_FUNC_ERR_MSG_TXT("solve_algo is not a field of options_"); + mexErrMsgTxt("solve_algo is not a field of options_"); field = mxGetFieldNumber(options_, "solve_tolf"); if (field >= 0) solve_tolf = *(mxGetPr(mxGetFieldByNumber(options_, 0, field))); else - DYN_MEX_FUNC_ERR_MSG_TXT("solve_tolf is not a field of options_"); + mexErrMsgTxt("solve_tolf is not a field of options_"); } else { @@ -1014,19 +983,19 @@ main(int nrhs, const char *prhs[]) if (field >= 0) dynatol = mxGetFieldByNumber(options_, 0, field); else - DYN_MEX_FUNC_ERR_MSG_TXT("dynatol is not a field of options_"); + mexErrMsgTxt("dynatol is not a field of options_"); field = mxGetFieldNumber(dynatol, "f"); if (field >= 0) solve_tolf = *mxGetPr((mxGetFieldByNumber(dynatol, 0, field))); else - DYN_MEX_FUNC_ERR_MSG_TXT("f is not a field of options_.dynatol"); + mexErrMsgTxt("f is not a field of options_.dynatol"); } field = mxGetFieldNumber(M_, "fname"); mxArray *mxa; if (field >= 0) mxa = mxGetFieldByNumber(M_, 0, field); else - DYN_MEX_FUNC_ERR_MSG_TXT("fname is not a field of M_"); + mexErrMsgTxt("fname is not a field of M_"); size_t buflen = mxGetM(mxa) * mxGetN(mxa) + 1; char *fname; fname = static_cast(mxCalloc(buflen+1, sizeof(char))); @@ -1044,11 +1013,11 @@ main(int nrhs, const char *prhs[]) } catch (GeneralExceptionHandling &feh) { - DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str()); + mexErrMsgTxt(feh.GetErrorMsg().c_str()); } #else if (stack_solve_algo == 7 && !steady_state) - DYN_MEX_FUNC_ERR_MSG_TXT("bytecode has not been compiled with CUDA option. Bytecode Can't use options_.stack_solve_algo=7\n"); + mexErrMsgTxt("bytecode has not been compiled with CUDA option. Bytecode Can't use options_.stack_solve_algo=7\n"); #endif size_t size_of_direction = col_y*row_y*sizeof(double); double *y = static_cast(mxMalloc(size_of_direction)); @@ -1067,7 +1036,7 @@ main(int nrhs, const char *prhs[]) } for (i = 0; i < row_y*col_y; i++) { - y[i] = double (yd[i]); + y[i] = double (yd[i]); ya[i] = double (yd[i]); } size_t y_size = row_y; @@ -1085,7 +1054,6 @@ main(int nrhs, const char *prhs[]) mxFree(fname); int nb_blocks = 0; double *pind; - bool no_error = true; if (extended_path) { @@ -1095,7 +1063,7 @@ main(int nrhs, const char *prhs[]) } catch (GeneralExceptionHandling &feh) { - DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str()); + mexErrMsgTxt(feh.GetErrorMsg().c_str()); } } else @@ -1106,7 +1074,7 @@ main(int nrhs, const char *prhs[]) } catch (GeneralExceptionHandling &feh) { - DYN_MEX_FUNC_ERR_MSG_TXT(feh.GetErrorMsg().c_str()); + mexErrMsgTxt(feh.GetErrorMsg().c_str()); } } @@ -1116,42 +1084,21 @@ main(int nrhs, const char *prhs[]) #endif clock_t t1 = clock(); - if (!steady_state && !evaluate && no_error && print) + if (!steady_state && !evaluate && print) mexPrintf("Simulation Time=%f milliseconds\n", 1000.0*(double (t1)-double (t0))/double (CLOCKS_PER_SEC)); #ifndef DEBUG_EX bool dont_store_a_structure = false; if (nlhs > 0) { - plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); - pind = mxGetPr(plhs[0]); - if (no_error) - pind[0] = 0; - else - pind[0] = 1; - if (nlhs > 1) + if (block >= 0) { - if (block >= 0) + if (evaluate) { - if (evaluate) - { - vector residual = interprete.get_residual(); - plhs[1] = mxCreateDoubleMatrix(int (residual.size()/double (col_y)), int (col_y), mxREAL); - pind = mxGetPr(plhs[1]); - for (i = 0; i < residual.size(); i++) - pind[i] = residual[i]; - } - else - { - int out_periods; - if (extended_path) - out_periods = max_periods + y_kmin; - else - out_periods = row_y; - plhs[1] = mxCreateDoubleMatrix(out_periods, int (col_y), mxREAL); - pind = mxGetPr(plhs[1]); - for (i = 0; i < out_periods*col_y; i++) - pind[i] = y[i]; - } + vector residual = interprete.get_residual(); + plhs[0] = mxCreateDoubleMatrix(int (residual.size()/double (col_y)), int (col_y), mxREAL); + pind = mxGetPr(plhs[0]); + for (i = 0; i < residual.size(); i++) + pind[i] = residual[i]; } else { @@ -1159,99 +1106,111 @@ main(int nrhs, const char *prhs[]) if (extended_path) out_periods = max_periods + y_kmin; else - out_periods = col_y; - plhs[1] = mxCreateDoubleMatrix(int (row_y), out_periods, mxREAL); - pind = mxGetPr(plhs[1]); - if (evaluate) + out_periods = row_y; + plhs[0] = mxCreateDoubleMatrix(out_periods, int (col_y), mxREAL); + pind = mxGetPr(plhs[0]); + for (i = 0; i < out_periods*col_y; i++) + pind[i] = y[i]; + } + } + else + { + int out_periods; + if (extended_path) + out_periods = max_periods + y_kmin; + else + out_periods = col_y; + plhs[0] = mxCreateDoubleMatrix(int (row_y), out_periods, mxREAL); + pind = mxGetPr(plhs[0]); + if (evaluate) + { + vector residual = interprete.get_residual(); + for (i = 0; i < residual.size(); i++) + pind[i] = residual[i]; + } + else + for (i = 0; i < row_y*out_periods; i++) + pind[i] = y[i]; + } + if (nlhs > 1) + { + if (evaluate) + { + int jacob_field_number = 0, jacob_exo_field_number = 0, jacob_exo_det_field_number = 0, jacob_other_endo_field_number = 0; + if (!block_structur) { - vector residual = interprete.get_residual(); - for (i = 0; i < residual.size(); i++) - pind[i] = residual[i]; + const char *field_names[] = {"g1", "g1_x", "g1_xd", "g1_o"}; + jacob_field_number = 0; + jacob_exo_field_number = 1; + jacob_exo_det_field_number = 2; + jacob_other_endo_field_number = 3; + mwSize dims[1] = {static_cast(nb_blocks) }; + plhs[1] = mxCreateStructArray(1, dims, 4, field_names); + } + else if (!mxIsStruct(block_structur)) + { + plhs[1] = interprete.get_jacob(0); + //mexCallMATLAB(0,NULL, 1, &plhs[1], "disp"); + dont_store_a_structure = true; } else - for (i = 0; i < row_y*out_periods; i++) - pind[i] = y[i]; - } - if (nlhs > 2) - { - if (evaluate) { - int jacob_field_number = 0, jacob_exo_field_number = 0, jacob_exo_det_field_number = 0, jacob_other_endo_field_number = 0; - if (!block_structur) + plhs[1] = block_structur; + jacob_field_number = mxAddField(plhs[1], "g1"); + if (jacob_field_number == -1) + mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob to the structArray\n"); + jacob_exo_field_number = mxAddField(plhs[1], "g1_x"); + if (jacob_exo_field_number == -1) + mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_exo to the structArray\n"); + jacob_exo_det_field_number = mxAddField(plhs[1], "g1_xd"); + if (jacob_exo_det_field_number == -1) + mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_exo_det to the structArray\n"); + jacob_other_endo_field_number = mxAddField(plhs[1], "g1_o"); + if (jacob_other_endo_field_number == -1) + mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_other_endo to the structArray\n"); + } + if (!dont_store_a_structure) + { + for (int i = 0; i < nb_blocks; i++) { - const char *field_names[] = {"g1", "g1_x", "g1_xd", "g1_o"}; - jacob_field_number = 0; - jacob_exo_field_number = 1; - jacob_exo_det_field_number = 2; - jacob_other_endo_field_number = 3; - mwSize dims[1] = {static_cast(nb_blocks) }; - plhs[2] = mxCreateStructArray(1, dims, 4, field_names); - } - else if (!mxIsStruct(block_structur)) - { - plhs[2] = interprete.get_jacob(0); - //mexCallMATLAB(0,NULL, 1, &plhs[2], "disp"); - dont_store_a_structure = true; - } - else - { - plhs[2] = block_structur; - jacob_field_number = mxAddField(plhs[2], "g1"); - if (jacob_field_number == -1) - DYN_MEX_FUNC_ERR_MSG_TXT("Fatal error in bytecode: in main, cannot add extra field jacob to the structArray\n"); - jacob_exo_field_number = mxAddField(plhs[2], "g1_x"); - if (jacob_exo_field_number == -1) - DYN_MEX_FUNC_ERR_MSG_TXT("Fatal error in bytecode: in main, cannot add extra field jacob_exo to the structArray\n"); - jacob_exo_det_field_number = mxAddField(plhs[2], "g1_xd"); - if (jacob_exo_det_field_number == -1) - DYN_MEX_FUNC_ERR_MSG_TXT("Fatal error in bytecode: in main, cannot add extra field jacob_exo_det to the structArray\n"); - jacob_other_endo_field_number = mxAddField(plhs[2], "g1_o"); - if (jacob_other_endo_field_number == -1) - DYN_MEX_FUNC_ERR_MSG_TXT("Fatal error in bytecode: in main, cannot add extra field jacob_other_endo to the structArray\n"); - } - if (!dont_store_a_structure) - { - for (int i = 0; i < nb_blocks; i++) + mxSetFieldByNumber(plhs[1], i, jacob_field_number, interprete.get_jacob(i)); + if (!steady_state) { - mxSetFieldByNumber(plhs[2], i, jacob_field_number, interprete.get_jacob(i)); - if (!steady_state) - { - mxSetFieldByNumber(plhs[2], i, jacob_exo_field_number, interprete.get_jacob_exo(i)); - mxSetFieldByNumber(plhs[2], i, jacob_exo_det_field_number, interprete.get_jacob_exo_det(i)); - mxSetFieldByNumber(plhs[2], i, jacob_other_endo_field_number, interprete.get_jacob_other_endo(i)); - } + mxSetFieldByNumber(plhs[1], i, jacob_exo_field_number, interprete.get_jacob_exo(i)); + mxSetFieldByNumber(plhs[1], i, jacob_exo_det_field_number, interprete.get_jacob_exo_det(i)); + mxSetFieldByNumber(plhs[1], i, jacob_other_endo_field_number, interprete.get_jacob_other_endo(i)); } } } - else + } + else + { + plhs[1] = mxCreateDoubleMatrix(int (row_x), int (col_x), mxREAL); + pind = mxGetPr(plhs[1]); + for (i = 0; i < row_x*col_x; i++) { - plhs[2] = mxCreateDoubleMatrix(int (row_x), int (col_x), mxREAL); - pind = mxGetPr(plhs[2]); - for (i = 0; i < row_x*col_x; i++) - { - pind[i] = x[i]; - } - - } - if (nlhs > 3) - { - plhs[3] = mxCreateDoubleMatrix(int (row_y), int (col_y), mxREAL); - pind = mxGetPr(plhs[3]); - for (i = 0; i < row_y*col_y; i++) - pind[i] = y[i]; - if (nlhs > 4) - { - mxArray *GlobalTemporaryTerms = interprete.get_Temporary_Terms(); - size_t nb_temp_terms = mxGetM(GlobalTemporaryTerms); - plhs[4] = mxCreateDoubleMatrix(int (nb_temp_terms), 1, mxREAL); - pind = mxGetPr(plhs[4]); - double *tt = mxGetPr(GlobalTemporaryTerms); - for (i = 0; i < nb_temp_terms; i++) - pind[i] = tt[i]; - } + pind[i] = x[i]; } } + if (nlhs > 2) + { + plhs[2] = mxCreateDoubleMatrix(int (row_y), int (col_y), mxREAL); + pind = mxGetPr(plhs[2]); + for (i = 0; i < row_y*col_y; i++) + pind[i] = y[i]; + if (nlhs > 3) + { + mxArray *GlobalTemporaryTerms = interprete.get_Temporary_Terms(); + size_t nb_temp_terms = mxGetM(GlobalTemporaryTerms); + plhs[3] = mxCreateDoubleMatrix(int (nb_temp_terms), 1, mxREAL); + pind = mxGetPr(plhs[3]); + double *tt = mxGetPr(GlobalTemporaryTerms); + for (i = 0; i < nb_temp_terms; i++) + pind[i] = tt[i]; + } + } + } } #else diff --git a/mex/sources/bytecode/testing/mex_interface.cc b/mex/sources/bytecode/testing/mex_interface.cc index 2eac721fd..5094185a9 100644 --- a/mex/sources/bytecode/testing/mex_interface.cc +++ b/mex/sources/bytecode/testing/mex_interface.cc @@ -347,7 +347,7 @@ read_struct(FILE *fid) fscanf(fid, "%d", &size_2); vector fieldnames; vector v_Array; - vector > vv_Array; + vector> vv_Array; for (unsigned int j = 0; j < size_1 * size_2; j++) { for (unsigned int i = 0; i < nfields; i++) diff --git a/mex/sources/bytecode/testing/mex_interface.hh b/mex/sources/bytecode/testing/mex_interface.hh index ede5e63d7..b8b0dbfb0 100644 --- a/mex/sources/bytecode/testing/mex_interface.hh +++ b/mex/sources/bytecode/testing/mex_interface.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2017 Dynare Team + * Copyright © 2007-2020 Dynare Team * * This file is part of Dynare. * @@ -29,39 +29,32 @@ #include using namespace std; -#if !defined(DYN_MEX_FUNC_ERR_MSG_TXT) -# define DYN_MEX_FUNC_ERR_MSG_TXT(str) \ - do { \ - mexPrintf("%s\n", str); \ - } while (0) -#endif - typedef unsigned int mwIndex; typedef unsigned int mwSize; enum mxData_type { - mxREAL, - mxCOMPLEX + mxREAL, + mxCOMPLEX }; enum mxArray_type { - mxDOUBLE_CLASS = 0, - mxSINGLE_CLASS = 1, - mxLOGICAL_CLASS = 2, - mxCHAR_CLASS = 3, - mxSPARSE_CLASS = 4, - mxSTRUCT_CLASS = 5, - mxCELL_CLASS = 6, - mxFUNCTION_CLASS = 7, - mxUINT8_CLASS = 8, - mxINT16_CLASS = 9, - mxUINT16_CLASS = 10, - mxINT32_CLASS = 11, - mxUINT32_CLASS = 12, - mxINT64_CLASS = 13, - mxUINT64_CLASS = 14 + mxDOUBLE_CLASS = 0, + mxSINGLE_CLASS = 1, + mxLOGICAL_CLASS = 2, + mxCHAR_CLASS = 3, + mxSPARSE_CLASS = 4, + mxSTRUCT_CLASS = 5, + mxCELL_CLASS = 6, + mxFUNCTION_CLASS = 7, + mxUINT8_CLASS = 8, + mxINT16_CLASS = 9, + mxUINT16_CLASS = 10, + mxINT32_CLASS = 11, + mxUINT32_CLASS = 12, + mxINT64_CLASS = 13, + mxUINT64_CLASS = 14 }; class mxArray_tag @@ -73,7 +66,7 @@ public: double *data; mxArray_type type; vector field_name; - vector > field_array; + vector> field_array; mxArray_tag(); }; diff --git a/mex/sources/defines.F08 b/mex/sources/defines.F08 new file mode 100644 index 000000000..80d607f63 --- /dev/null +++ b/mex/sources/defines.F08 @@ -0,0 +1 @@ +#define MX_HAS_INTERLEAVED_COMPLEX (defined(MATLAB_MEX_FILE) && MATLAB_VERSION >= 0x0904) diff --git a/mex/sources/dynare_simul_/dynare_simul_.cc b/mex/sources/dynare_simul_/dynare_simul_.cc index 58a639609..faaf146b0 100644 --- a/mex/sources/dynare_simul_/dynare_simul_.cc +++ b/mex/sources/dynare_simul_/dynare_simul_.cc @@ -1,6 +1,6 @@ /* * Copyright © 2005-2011 Ondra Kamenik - * Copyright © 2019 Dynare Team + * Copyright © 2019-2020 Dynare Team * * This file is part of Dynare. * @@ -51,8 +51,8 @@ extern "C" { mexFunction(int nlhs, mxArray *plhs[], int nhrs, const mxArray *prhs[]) { - if (nhrs != 12 || nlhs != 2) - DYN_MEX_FUNC_ERR_MSG_TXT("dynare_simul_ must have at exactly 12 input parameters and 2 output arguments.\n"); + if (nhrs != 12 || nlhs != 1) + mexErrMsgTxt("dynare_simul_ must have at exactly 12 input parameters and 1 output argument."); int order = static_cast(mxGetScalar(prhs[0])); int nstat = static_cast(mxGetScalar(prhs[1])); @@ -74,22 +74,22 @@ extern "C" { int ny = nstat + npred + nboth + nforw; if (ny != static_cast(ystart_dim[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of rows.\n"); + mexErrMsgTxt("ystart has wrong number of rows.\n"); if (1 != ystart_dim[1]) - DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of cols.\n"); + mexErrMsgTxt("ystart has wrong number of cols.\n"); int nper = shocks_dim[1]; if (nexog != static_cast(shocks_dim[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("shocks has a wrong number of rows.\n"); + mexErrMsgTxt("shocks has a wrong number of rows.\n"); if (nexog != static_cast(vcov_dim[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of rows.\n"); + mexErrMsgTxt("vcov has a wrong number of rows.\n"); if (nexog != static_cast(vcov_dim[1])) - DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of cols.\n"); + mexErrMsgTxt("vcov has a wrong number of cols.\n"); if (ny != static_cast(ysteady_dim[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of rows.\n"); + mexErrMsgTxt("ysteady has wrong number of rows.\n"); if (1 != ysteady_dim[1]) - DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of cols.\n"); + mexErrMsgTxt("ysteady has wrong number of cols.\n"); - plhs[1] = mxCreateDoubleMatrix(ny, nper, mxREAL); + plhs[0] = mxCreateDoubleMatrix(ny, nper, mxREAL); try { @@ -102,13 +102,13 @@ extern "C" { { const mxArray *gk_m = mxGetField(dr, 0, ("g_" + std::to_string(dim)).c_str()); if (!gk_m) - DYN_MEX_FUNC_ERR_MSG_TXT(("Can't find field `g_" + std::to_string(dim) + "' in structured passed as last argument").c_str()); + mexErrMsgTxt(("Can't find field `g_" + std::to_string(dim) + "' in structured passed as last argument").c_str()); ConstTwoDMatrix gk(gk_m); FFSTensor ft(ny, npred+nboth+nexog, dim); if (ft.ncols() != gk.ncols()) - DYN_MEX_FUNC_ERR_MSG_TXT(("Wrong number of columns for folded tensor: got " + std::to_string(gk.ncols()) + " but i want " + std::to_string(ft.ncols()) + '\n').c_str()); + mexErrMsgTxt(("Wrong number of columns for folded tensor: got " + std::to_string(gk.ncols()) + " but i want " + std::to_string(ft.ncols()) + '\n').c_str()); if (ft.nrows() != gk.nrows()) - DYN_MEX_FUNC_ERR_MSG_TXT(("Wrong number of rows for folded tensor: got " + std::to_string(gk.nrows()) + " but i want " + std::to_string(ft.nrows()) + '\n').c_str()); + mexErrMsgTxt(("Wrong number of rows for folded tensor: got " + std::to_string(gk.nrows()) + " but i want " + std::to_string(ft.nrows()) + '\n').c_str()); ft.zeros(); ft.add(1.0, gk); pol.insert(std::make_unique(ft)); @@ -123,21 +123,20 @@ extern "C" { // simulate and copy the results TwoDMatrix res_mat{dr.simulate(DecisionRule::emethod::horner, nper, ConstVector{ystart}, sr)}; - TwoDMatrix res_tmp_mat{plhs[1]}; + TwoDMatrix res_tmp_mat{plhs[0]}; res_tmp_mat = const_cast(res_mat); } catch (const KordException &e) { - DYN_MEX_FUNC_ERR_MSG_TXT("Caught Kord exception."); + mexErrMsgTxt("Caught Kord exception."); } catch (const TLException &e) { - DYN_MEX_FUNC_ERR_MSG_TXT("Caught TL exception."); + mexErrMsgTxt("Caught TL exception."); } catch (SylvException &e) { - DYN_MEX_FUNC_ERR_MSG_TXT("Caught Sylv exception."); + mexErrMsgTxt("Caught Sylv exception."); } - plhs[0] = mxCreateDoubleScalar(0); } }; diff --git a/mex/sources/dynmex.h b/mex/sources/dynmex.h index 52a71bef5..4bb0ca739 100644 --- a/mex/sources/dynmex.h +++ b/mex/sources/dynmex.h @@ -1,5 +1,5 @@ /* - * Copyright © 2009-2019 Dynare Team + * Copyright © 2009-2020 Dynare Team * * This file is part of Dynare. * @@ -26,20 +26,6 @@ #include -/* - * Fix for trac ticket Ticket #137 - */ -#if !defined(DYN_MEX_FUNC_ERR_MSG_TXT) -# define DYN_MEX_FUNC_ERR_MSG_TXT(str) \ - do { \ - mexPrintf("%s\n", str); \ - int i; \ - for (i = 0; i < nlhs; i++) \ - plhs[i] = mxCreateDoubleScalar(1); \ - return; \ - } while (0) -#endif - #if defined(MATLAB_MEX_FILE) && MATLAB_VERSION < 0x0805 # define mxIsScalar(x) (mxGetM(x) == 1 && mxGetN(x) == 1) #endif diff --git a/mex/sources/gensylv/gensylv.cc b/mex/sources/gensylv/gensylv.cc index 15a980ce7..c71f295f9 100644 --- a/mex/sources/gensylv/gensylv.cc +++ b/mex/sources/gensylv/gensylv.cc @@ -1,6 +1,6 @@ /* * Copyright © 2005-2011 Ondra Kamenik - * Copyright © 2019 Dynare Team + * Copyright © 2019-2020 Dynare Team * * This file is part of Dynare. * @@ -51,8 +51,8 @@ extern "C" { mexFunction(int nlhs, mxArray *plhs[], int nhrs, const mxArray *prhs[]) { - if (nhrs != 5 || nlhs > 3 || nlhs < 2) - DYN_MEX_FUNC_ERR_MSG_TXT("Gensylv: Must have exactly 5 input args and either 2 or 3 output args."); + if (nhrs != 5 || nlhs > 2 || nlhs < 1) + mexErrMsgTxt("Gensylv: Must have exactly 5 input args and either 1 or 2 output args."); auto order = static_cast(mxGetScalar(prhs[0])); const mxArray *const A = prhs[1]; @@ -65,17 +65,17 @@ extern "C" { const mwSize *const Ddims = mxGetDimensions(D); if (Adims[0] != Adims[1]) - DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A must be a square matrix."); + mexErrMsgTxt("Matrix A must be a square matrix."); if (Adims[0] != Bdims[0]) - DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A and matrix B must have the same number of rows."); + mexErrMsgTxt("Matrix A and matrix B must have the same number of rows."); if (Adims[0] != Ddims[0]) - DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A and matrix B must have the same number of rows."); + mexErrMsgTxt("Matrix A and matrix B must have the same number of rows."); if (Cdims[0] != Cdims[1]) - DYN_MEX_FUNC_ERR_MSG_TXT("Matrix C must be square."); + mexErrMsgTxt("Matrix C must be square."); if (Bdims[0] < Bdims[1]) - DYN_MEX_FUNC_ERR_MSG_TXT("Matrix B must not have more columns than rows."); + mexErrMsgTxt("Matrix B must not have more columns than rows."); if (Ddims[1] != static_cast(power(Cdims[0], order))) - DYN_MEX_FUNC_ERR_MSG_TXT("Matrix D has wrong number of columns."); + mexErrMsgTxt("Matrix D has wrong number of columns."); auto n = static_cast(Adims[0]); auto m = static_cast(Cdims[0]); @@ -88,16 +88,15 @@ extern "C" { // solve (or solve and check) try { - if (nlhs == 2) + if (nlhs == 1) gen_sylv_solve(order, n, m, zero_cols, Avec, Bvec, Cvec, Xvec); - else if (nlhs == 3) - plhs[2] = gen_sylv_solve_and_check(order, n, m, zero_cols, Avec, Bvec, Cvec, Dvec, Xvec); + else if (nlhs == 2) + plhs[1] = gen_sylv_solve_and_check(order, n, m, zero_cols, Avec, Bvec, Cvec, Dvec, Xvec); } catch (const SylvException &e) { - DYN_MEX_FUNC_ERR_MSG_TXT(e.getMessage().c_str()); + mexErrMsgTxt(e.getMessage().c_str()); } - plhs[1] = X; - plhs[0] = mxCreateDoubleScalar(0); + plhs[0] = X; } }; diff --git a/mex/sources/k_order_perturbation/dynamic_abstract_class.hh b/mex/sources/k_order_perturbation/dynamic_abstract_class.hh index 901782670..e1f8c3709 100644 --- a/mex/sources/k_order_perturbation/dynamic_abstract_class.hh +++ b/mex/sources/k_order_perturbation/dynamic_abstract_class.hh @@ -29,7 +29,9 @@ class DynamicModelAC protected: int ntt; // Size of vector of temporary terms public: - DynamicModelAC(int ntt_arg) : ntt{ntt_arg} {}; + DynamicModelAC(int ntt_arg) : ntt{ntt_arg} + { + }; virtual ~DynamicModelAC() = default; virtual void eval(const Vector &y, const Vector &x, const Vector ¶ms, const Vector &ySteady, Vector &residual, std::vector &md) = 0; diff --git a/mex/sources/k_order_perturbation/dynamic_dll.hh b/mex/sources/k_order_perturbation/dynamic_dll.hh index 2e7d87195..693e8b2b9 100644 --- a/mex/sources/k_order_perturbation/dynamic_dll.hh +++ b/mex/sources/k_order_perturbation/dynamic_dll.hh @@ -35,7 +35,7 @@ #include "dynamic_abstract_class.hh" using dynamic_tt_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, double *T); -using dynamic_deriv_fct = void (*) (const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *deriv); +using dynamic_deriv_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *deriv); /** * creates pointer to Dynamic function inside _dynamic.dll @@ -47,7 +47,7 @@ private: std::vector dynamic_tt; std::vector dynamic_deriv; #if defined(_WIN32) || defined(__CYGWIN32__) - HINSTANCE dynamicHinstance; // DLL instance pointer in Windows + HINSTANCE dynamicHinstance; // DLL instance pointer in Windows #else void *dynamicHinstance; // and in Linux or Mac #endif diff --git a/mex/sources/k_order_perturbation/dynamic_m.cc b/mex/sources/k_order_perturbation/dynamic_m.cc index 04473cfe2..c0ff5c2ca 100644 --- a/mex/sources/k_order_perturbation/dynamic_m.cc +++ b/mex/sources/k_order_perturbation/dynamic_m.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2010-2019 Dynare Team + * Copyright © 2010-2020 Dynare Team * * This file is part of Dynare. * @@ -35,11 +35,13 @@ DynamicModelMFile::unpackSparseMatrixAndCopyIntoTwoDMatData(mxArray *sparseMat, { int totalCols = mxGetN(sparseMat); mwIndex *rowIdxVector = mxGetIr(sparseMat); - mwSize sizeRowIdxVector = mxGetNzmax(sparseMat); mwIndex *colIdxVector = mxGetJc(sparseMat); assert(tdm.ncols() == 3); - assert(tdm.nrows() == sizeRowIdxVector); + /* Under MATLAB, the following check always holds at equality; under Octave, + there may be an inequality, because Octave diminishes nzmax if one gives + zeros in the values vector when calling sparse(). */ + assert(tdm.nrows() >= mxGetNzmax(sparseMat)); double *ptr = mxGetPr(sparseMat); @@ -55,11 +57,11 @@ DynamicModelMFile::unpackSparseMatrixAndCopyIntoTwoDMatData(mxArray *sparseMat, output_row++; } - /* If there are less elements than Nzmax (that might happen if some + /* If there are less elements than expected (that might happen if some derivative is symbolically not zero but numerically zero at the evaluation point), then fill in the matrix with empty entries, that will be recognized as such by KordpDynare::populateDerivativesContainer() */ - while (output_row < static_cast(sizeRowIdxVector)) + while (output_row < tdm.nrows()) { tdm.get(output_row, 0) = 0; tdm.get(output_row, 1) = 0; diff --git a/mex/sources/k_order_perturbation/k_ord_dynare.cc b/mex/sources/k_order_perturbation/k_ord_dynare.cc index 80d05179c..5ccd442fb 100644 --- a/mex/sources/k_order_perturbation/k_ord_dynare.cc +++ b/mex/sources/k_order_perturbation/k_ord_dynare.cc @@ -236,4 +236,3 @@ DynareStateNameList::DynareStateNameList(const KordpDynare &dynare, const Dynare for (int i = 0; i < dynare.nexog(); i++) names.emplace_back(denl.getName(i)); } - diff --git a/mex/sources/k_order_perturbation/k_order_perturbation.cc b/mex/sources/k_order_perturbation/k_order_perturbation.cc index 03578a97a..4ae1151db 100644 --- a/mex/sources/k_order_perturbation/k_order_perturbation.cc +++ b/mex/sources/k_order_perturbation/k_order_perturbation.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2008-2019 Dynare Team + * Copyright © 2008-2020 Dynare Team * * This file is part of Dynare. * @@ -82,8 +82,8 @@ extern "C" { mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { - if (nrhs < 3 || nlhs < 2 || nlhs > 3) - DYN_MEX_FUNC_ERR_MSG_TXT("Must have at least 3 input parameters and takes 2 or 3 output parameters."); + if (nrhs < 3 || nlhs < 1 || nlhs > 2) + mexErrMsgTxt("Must have at least 3 input parameters and takes 1 or 2 output parameters."); // Give explicit names to input arguments const mxArray *dr_mx = prhs[0]; @@ -101,11 +101,11 @@ extern "C" { // Extract various fields from options_ const int kOrder = get_int_field(options_mx, "order"); if (kOrder < 1) - DYN_MEX_FUNC_ERR_MSG_TXT("options_.order must be at least 1"); + mexErrMsgTxt("options_.order must be at least 1"); const mxArray *use_dll_mx = mxGetField(options_mx, 0, "use_dll"); if (!(use_dll_mx && mxIsLogicalScalar(use_dll_mx))) - DYN_MEX_FUNC_ERR_MSG_TXT("options_.use_dll should be a logical scalar"); + mexErrMsgTxt("options_.use_dll should be a logical scalar"); bool use_dll = static_cast(mxGetScalar(use_dll_mx)); double qz_criterium = 1+1e-6; @@ -115,31 +115,31 @@ extern "C" { const mxArray *threads_mx = mxGetField(options_mx, 0, "threads"); if (!threads_mx) - DYN_MEX_FUNC_ERR_MSG_TXT("Can't find field options_.threads"); + mexErrMsgTxt("Can't find field options_.threads"); const mxArray *num_threads_mx = mxGetField(threads_mx, 0, "k_order_perturbation"); if (!(num_threads_mx && mxIsScalar(num_threads_mx) && mxIsNumeric(num_threads_mx))) - DYN_MEX_FUNC_ERR_MSG_TXT("options_.threads.k_order_perturbation be a numeric scalar"); + mexErrMsgTxt("options_.threads.k_order_perturbation be a numeric scalar"); int num_threads = static_cast(mxGetScalar(num_threads_mx)); // Extract various fields from M_ const mxArray *fname_mx = mxGetField(M_mx, 0, "fname"); if (!(fname_mx && mxIsChar(fname_mx) && mxGetM(fname_mx) == 1)) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.fname should be a character string"); + mexErrMsgTxt("M_.fname should be a character string"); std::string fname{mxArrayToString(fname_mx)}; const mxArray *params_mx = mxGetField(M_mx, 0, "params"); if (!(params_mx && mxIsDouble(params_mx))) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.params should be a double precision array"); + mexErrMsgTxt("M_.params should be a double precision array"); Vector modParams{ConstVector{params_mx}}; if (!modParams.isFinite()) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.params contains NaN or Inf"); + mexErrMsgTxt("M_.params contains NaN or Inf"); const mxArray *sigma_e_mx = mxGetField(M_mx, 0, "Sigma_e"); if (!(sigma_e_mx && mxIsDouble(sigma_e_mx) && mxGetM(sigma_e_mx) == mxGetN(sigma_e_mx))) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.Sigma_e should be a double precision square matrix"); + mexErrMsgTxt("M_.Sigma_e should be a double precision square matrix"); TwoDMatrix vCov{ConstTwoDMatrix{sigma_e_mx}}; if (!vCov.isFinite()) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.Sigma_e contains NaN or Inf"); + mexErrMsgTxt("M_.Sigma_e contains NaN or Inf"); const int nStat = get_int_field(M_mx, "nstatic"); const int nPred = get_int_field(M_mx, "npred"); @@ -153,42 +153,42 @@ extern "C" { const mxArray *lead_lag_incidence_mx = mxGetField(M_mx, 0, "lead_lag_incidence"); if (!(lead_lag_incidence_mx && mxIsDouble(lead_lag_incidence_mx) && mxGetM(lead_lag_incidence_mx) == 3 && mxGetN(lead_lag_incidence_mx) == static_cast(nEndo))) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.lead_lag_incidence should be a double precision matrix with 3 rows and M_.endo_nbr columns"); + mexErrMsgTxt("M_.lead_lag_incidence should be a double precision matrix with 3 rows and M_.endo_nbr columns"); ConstTwoDMatrix llincidence{lead_lag_incidence_mx}; const mxArray *nnzderivatives_mx = mxGetField(M_mx, 0, "NNZDerivatives"); if (!(nnzderivatives_mx && mxIsDouble(nnzderivatives_mx))) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.NNZDerivatives should be a double precision array"); + mexErrMsgTxt("M_.NNZDerivatives should be a double precision array"); ConstVector NNZD{nnzderivatives_mx}; if (NNZD.length() < kOrder || NNZD[kOrder-1] == -1) - DYN_MEX_FUNC_ERR_MSG_TXT("The derivatives were not computed for the required order. Make sure that you used the right order option inside the `stoch_simul' command"); + mexErrMsgTxt("The derivatives were not computed for the required order. Make sure that you used the right order option inside the `stoch_simul' command"); const mxArray *endo_names_mx = mxGetField(M_mx, 0, "endo_names"); if (!(endo_names_mx && mxIsCell(endo_names_mx) && mxGetNumberOfElements(endo_names_mx) == static_cast(nEndo))) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.endo_names should be a cell array of M_.endo_nbr elements"); + mexErrMsgTxt("M_.endo_names should be a cell array of M_.endo_nbr elements"); std::vector endoNames = DynareMxArrayToString(endo_names_mx); const mxArray *exo_names_mx = mxGetField(M_mx, 0, "exo_names"); if (!(exo_names_mx && mxIsCell(exo_names_mx) && mxGetNumberOfElements(exo_names_mx) == static_cast(nExog))) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.exo_names should be a cell array of M_.exo_nbr elements"); + mexErrMsgTxt("M_.exo_names should be a cell array of M_.exo_nbr elements"); std::vector exoNames = DynareMxArrayToString(exo_names_mx); const mxArray *dynamic_tmp_nbr_mx = mxGetField(M_mx, 0, "dynamic_tmp_nbr"); if (!(dynamic_tmp_nbr_mx && mxIsDouble(dynamic_tmp_nbr_mx) && mxGetNumberOfElements(dynamic_tmp_nbr_mx) >= static_cast(kOrder+1))) - DYN_MEX_FUNC_ERR_MSG_TXT("M_.dynamic_tmp_nbr should be a double precision array with strictly more elements than the order of derivation"); + mexErrMsgTxt("M_.dynamic_tmp_nbr should be a double precision array with strictly more elements than the order of derivation"); int ntt = std::accumulate(mxGetPr(dynamic_tmp_nbr_mx), mxGetPr(dynamic_tmp_nbr_mx)+kOrder+1, 0); // Extract various fields from dr - const mxArray *ys_mx = mxGetField(dr_mx, 0, "ys"); // and not in order of dr.order_var + const mxArray *ys_mx = mxGetField(dr_mx, 0, "ys"); // and not in order of dr.order_var if (!(ys_mx && mxIsDouble(ys_mx))) - DYN_MEX_FUNC_ERR_MSG_TXT("dr.ys should be a double precision array"); + mexErrMsgTxt("dr.ys should be a double precision array"); Vector ySteady{ConstVector{ys_mx}}; if (!ySteady.isFinite()) - DYN_MEX_FUNC_ERR_MSG_TXT("dr.ys contains NaN or Inf"); + mexErrMsgTxt("dr.ys contains NaN or Inf"); const mxArray *order_var_mx = mxGetField(dr_mx, 0, "order_var"); if (!(order_var_mx && mxIsDouble(order_var_mx) && mxGetNumberOfElements(order_var_mx) == static_cast(nEndo))) - DYN_MEX_FUNC_ERR_MSG_TXT("dr.order_var should be a double precision array of M_.endo_nbr elements"); + mexErrMsgTxt("dr.order_var should be a double precision array of M_.endo_nbr elements"); std::vector dr_order(nEndo); std::transform(mxGetPr(order_var_mx), mxGetPr(order_var_mx)+nEndo, dr_order.begin(), [](double x) { return static_cast(x)-1; }); @@ -241,7 +241,7 @@ extern "C" { const char *g_fieldnames_c[kOrder+1]; for (int i = 0; i <= kOrder; i++) g_fieldnames_c[i] = g_fieldnames[i].c_str(); - plhs[1] = mxCreateStructMatrix(1, 1, kOrder+1, g_fieldnames_c); + plhs[0] = mxCreateStructMatrix(1, 1, kOrder+1, g_fieldnames_c); // Fill that structure for (int i = 0; i <= kOrder; i++) @@ -251,10 +251,10 @@ extern "C" { const ConstVector &vec = t.getData(); assert(vec.skip() == 1); std::copy_n(vec.base(), vec.length(), mxGetPr(tmp)); - mxSetField(plhs[1], 0, ("g_" + std::to_string(i)).c_str(), tmp); + mxSetField(plhs[0], 0, ("g_" + std::to_string(i)).c_str(), tmp); } - if (nlhs > 2) + if (nlhs > 1) { /* Return as 3rd argument a struct containing derivatives in Dynare format (unfolded matrices, without Taylor coefficient) up to 3rd @@ -264,52 +264,50 @@ extern "C" { size_t nfields = (kOrder == 1 ? 2 : (kOrder == 2 ? 6 : 12)); const char *c_fieldnames[] = { "gy", "gu", "gyy", "gyu", "guu", "gss", "gyyy", "gyyu", "gyuu", "guuu", "gyss", "guss" }; - plhs[2] = mxCreateStructMatrix(1, 1, nfields, c_fieldnames); + plhs[1] = mxCreateStructMatrix(1, 1, nfields, c_fieldnames); - copy_derivatives(plhs[2], Symmetry{1, 0, 0, 0}, derivs, "gy"); - copy_derivatives(plhs[2], Symmetry{0, 1, 0, 0}, derivs, "gu"); + copy_derivatives(plhs[1], Symmetry{1, 0, 0, 0}, derivs, "gy"); + copy_derivatives(plhs[1], Symmetry{0, 1, 0, 0}, derivs, "gu"); if (kOrder >= 2) { - copy_derivatives(plhs[2], Symmetry{2, 0, 0, 0}, derivs, "gyy"); - copy_derivatives(plhs[2], Symmetry{0, 2, 0, 0}, derivs, "guu"); - copy_derivatives(plhs[2], Symmetry{1, 1, 0, 0}, derivs, "gyu"); - copy_derivatives(plhs[2], Symmetry{0, 0, 0, 2}, derivs, "gss"); + copy_derivatives(plhs[1], Symmetry{2, 0, 0, 0}, derivs, "gyy"); + copy_derivatives(plhs[1], Symmetry{0, 2, 0, 0}, derivs, "guu"); + copy_derivatives(plhs[1], Symmetry{1, 1, 0, 0}, derivs, "gyu"); + copy_derivatives(plhs[1], Symmetry{0, 0, 0, 2}, derivs, "gss"); } if (kOrder >= 3) { - copy_derivatives(plhs[2], Symmetry{3, 0, 0, 0}, derivs, "gyyy"); - copy_derivatives(plhs[2], Symmetry{0, 3, 0, 0}, derivs, "guuu"); - copy_derivatives(plhs[2], Symmetry{2, 1, 0, 0}, derivs, "gyyu"); - copy_derivatives(plhs[2], Symmetry{1, 2, 0, 0}, derivs, "gyuu"); - copy_derivatives(plhs[2], Symmetry{1, 0, 0, 2}, derivs, "gyss"); - copy_derivatives(plhs[2], Symmetry{0, 1, 0, 2}, derivs, "guss"); + copy_derivatives(plhs[1], Symmetry{3, 0, 0, 0}, derivs, "gyyy"); + copy_derivatives(plhs[1], Symmetry{0, 3, 0, 0}, derivs, "guuu"); + copy_derivatives(plhs[1], Symmetry{2, 1, 0, 0}, derivs, "gyyu"); + copy_derivatives(plhs[1], Symmetry{1, 2, 0, 0}, derivs, "gyuu"); + copy_derivatives(plhs[1], Symmetry{1, 0, 0, 2}, derivs, "gyss"); + copy_derivatives(plhs[1], Symmetry{0, 1, 0, 2}, derivs, "guss"); } } } catch (const KordException &e) { e.print(); - DYN_MEX_FUNC_ERR_MSG_TXT(("dynare:k_order_perturbation: Caught Kord exception: " + e.get_message()).c_str()); + mexErrMsgTxt(("dynare:k_order_perturbation: Caught Kord exception: " + e.get_message()).c_str()); } catch (const TLException &e) { e.print(); - DYN_MEX_FUNC_ERR_MSG_TXT("dynare:k_order_perturbation: Caught TL exception"); + mexErrMsgTxt("dynare:k_order_perturbation: Caught TL exception"); } catch (SylvException &e) { e.printMessage(); - DYN_MEX_FUNC_ERR_MSG_TXT("dynare:k_order_perturbation: Caught Sylv exception"); + mexErrMsgTxt("dynare:k_order_perturbation: Caught Sylv exception"); } catch (const DynareException &e) { - DYN_MEX_FUNC_ERR_MSG_TXT(("dynare:k_order_perturbation: Caught KordDynare exception: " + e.message()).c_str()); + mexErrMsgTxt(("dynare:k_order_perturbation: Caught KordDynare exception: " + e.message()).c_str()); } catch (const ogu::Exception &e) { - DYN_MEX_FUNC_ERR_MSG_TXT(("dynare:k_order_perturbation: Caught general exception: " + e.message()).c_str()); + mexErrMsgTxt(("dynare:k_order_perturbation: Caught general exception: " + e.message()).c_str()); } - plhs[0] = mxCreateDoubleScalar(0); } // end of mexFunction() } // end of extern C - diff --git a/mex/sources/k_order_perturbation/tests/k_order_test_main.cc b/mex/sources/k_order_perturbation/tests/k_order_test_main.cc index d924067ac..114e1e1e7 100644 --- a/mex/sources/k_order_perturbation/tests/k_order_test_main.cc +++ b/mex/sources/k_order_perturbation/tests/k_order_test_main.cc @@ -49,7 +49,7 @@ main(int argc, char *argv[]) 0.7000, 0.7870, 0.0200}; - Vector *modParams = new Vector(dparams, npar); + Vector *modParams = new Vector(dparams, npar); #ifdef DEBUG mexPrintf("k_ord_perturbation: nParams=%d .\n", npar); @@ -65,24 +65,24 @@ main(int argc, char *argv[]) #endif double d2Dparams[4] = { //(double *) mxGetData(mxFldp); - 0.1960e-3, 0.0, - 0.0, 0.0250e-3 + 0.1960e-3, 0.0, + 0.0, 0.0250e-3 }; npar = 2; //(int)mxGetN(mxFldp); - TwoDMatrix *vCov = new TwoDMatrix(npar, npar, (d2Dparams)); - double dYSparams [16] = { // 27 mxGetData(mxFldp); - // 1.0110, 2.2582, 5.8012, 0.5808, - 1.0110, 2.2582, 0.4477, 1.0000, - 4.5959, 1.0212, 5.8012, 0.8494, - 0.1872, 0.8604, 1.0030, 1.0080, - 0.5808, 1.0030, 2.2582, 0.4477 - //, 1.0110, 2.2582, 0.4477, 1.0000, 0.1872, 2.2582, 0.4477 + TwoDMatrix *vCov = new TwoDMatrix(npar, npar, (d2Dparams)); + double dYSparams[16] = { // 27 mxGetData(mxFldp); + // 1.0110, 2.2582, 5.8012, 0.5808, + 1.0110, 2.2582, 0.4477, 1.0000, + 4.5959, 1.0212, 5.8012, 0.8494, + 0.1872, 0.8604, 1.0030, 1.0080, + 0.5808, 1.0030, 2.2582, 0.4477 + //, 1.0110, 2.2582, 0.4477, 1.0000, 0.1872, 2.2582, 0.4477 }; const int nSteady = 16; //27 //31;//29, 16 (int)mxGetM(mxFldp); - Vector *ySteady = new Vector(dYSparams, nSteady); + Vector *ySteady = new Vector(dYSparams, nSteady); double nnzd[3] = { 77, 217, 0}; - const Vector *NNZD = new Vector(nnzd, 3); + const Vector *NNZD = new Vector(nnzd, 3); //mxFldp = mxGetField(dr, 0,"nstatic" ); const int nStat = 7; //(int)mxGetScalar(mxFldp); @@ -109,32 +109,32 @@ main(int argc, char *argv[]) int var_order[] //[18] = { - 5, 6, 8, 10, 11, 12, 14, 7, 13, 1, 2, 3, 4, 9, 15, 16 - // 5, 6, 8, 10, 11, 12, 16, 7, 13, 14, 15, 1, 2, 3, 4, 9, 17, 18 + 5, 6, 8, 10, 11, 12, 14, 7, 13, 1, 2, 3, 4, 9, 15, 16 + // 5, 6, 8, 10, 11, 12, 16, 7, 13, 14, 15, 1, 2, 3, 4, 9, 17, 18 }; //Vector * varOrder = new Vector(var_order, nEndo); vector *var_order_vp = new vector(nEndo); //nEndo)); for (int v = 0; v < nEndo; v++) (*var_order_vp)[v] = var_order[v]; - const double ll_incidence [] //[3][18] + const double ll_incidence[] //[3][18] = { - 1, 5, 21, - 2, 6, 22, - 0, 7, 23, - 0, 8, 24, - 0, 9, 0, - 0, 10, 0, - 3, 11, 0, - 0, 12, 0, - 0, 13, 25, - 0, 14, 0, - 0, 15, 0, - 0, 16, 0, - 4, 17, 0, - 0, 18, 0, - 0, 19, 26, - 0, 20, 27 + 1, 5, 21, + 2, 6, 22, + 0, 7, 23, + 0, 8, 24, + 0, 9, 0, + 0, 10, 0, + 3, 11, 0, + 0, 12, 0, + 0, 13, 25, + 0, 14, 0, + 0, 15, 0, + 0, 16, 0, + 4, 17, 0, + 0, 18, 0, + 0, 19, 26, + 0, 20, 27 }; TwoDMatrix *llincidence = new TwoDMatrix(3, nEndo, ll_incidence); @@ -166,7 +166,7 @@ main(int argc, char *argv[]) mexPrintf("k_ord_perturbation: ExoNameList[%d][0]= %s.\n", i, exoNamesMX[i]); } #endif - if ((nEndo != nendo) || (nExog != nexo)) //(nPar != npar) + if ((nEndo != nendo) || (nExog != nexo)) //(nPar != npar) { mexPrintf("Incorrect number of input parameters.\n"); return; @@ -220,7 +220,7 @@ main(int argc, char *argv[]) mexPrintf("k_order_perturbation: Calling dynare constructor.\n"); #endif // make KordpDynare object - KordpDynare dynare(endoNamesMX, nEndo, exoNamesMX, nExog, nPar, // paramNames, + KordpDynare dynare(endoNamesMX, nEndo, exoNamesMX, nExog, nPar, // paramNames, ySteady, vCov, modParams, nStat, nPred, nForw, nBoth, jcols, NNZD, nSteps, kOrder, journal, dynamicDLL, sstol, var_order_vp, //var_order llincidence, qz_criterium); @@ -314,7 +314,7 @@ main(int argc, char *argv[]) mexPrintf("k_order_perturbation: Filling MATLAB outputs.\n"); #endif - double *dgy, *dgu, *ysteady; + double *dgy, *dgu, *ysteady; int nb_row_x; ysteady = NULL; diff --git a/mex/sources/kalman_steady_state/kalman_steady_state.cc b/mex/sources/kalman_steady_state/kalman_steady_state.cc index 7e455e347..14b61015b 100644 --- a/mex/sources/kalman_steady_state/kalman_steady_state.cc +++ b/mex/sources/kalman_steady_state/kalman_steady_state.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2009-2019 Dynare Team. + * Copyright © 2009-2020 Dynare Team. * * This file is part of Dynare. * @@ -76,10 +76,10 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) // Check the number of arguments and set some flags. bool measurement_error_flag = true; if (nrhs < 3 || 4 < nrhs) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state accepts either 3 or 4 input arguments!"); + mexErrMsgTxt("kalman_steady_state accepts either 3 or 4 input arguments!"); - if (nlhs < 1 || 2 < nlhs) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state requires at least 1, but no more than 2, output arguments!"); + if (nlhs != 1) + mexErrMsgTxt("kalman_steady_state accepts exactly one output argument!"); if (nrhs == 3) measurement_error_flag = false; @@ -87,30 +87,30 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) // Check the type of the input arguments and get the size of the matrices. lapack_int n = mxGetM(prhs[0]); if (static_cast(n) != mxGetN(prhs[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The first input argument (T) must be a square matrix!"); + mexErrMsgTxt("kalman_steady_state: The first input argument (T) must be a square matrix!"); if (mxIsNumeric(prhs[0]) == 0 || mxIsComplex(prhs[0]) == 1) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The first input argument (T) must be a real matrix!"); + mexErrMsgTxt("kalman_steady_state: The first input argument (T) must be a real matrix!"); lapack_int q = mxGetM(prhs[1]); if (static_cast(q) != mxGetN(prhs[1])) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The second input argument (QQ) must be a square matrix!"); + mexErrMsgTxt("kalman_steady_state: The second input argument (QQ) must be a square matrix!"); if (mxIsNumeric(prhs[1]) == 0 || mxIsComplex(prhs[1]) == 1) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The second input argument (QQ) must be a real matrix!"); + mexErrMsgTxt("kalman_steady_state: The second input argument (QQ) must be a real matrix!"); if (q != n) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The size of the second input argument (QQ) must match the size of the first argument (T)!"); + mexErrMsgTxt("kalman_steady_state: The size of the second input argument (QQ) must match the size of the first argument (T)!"); lapack_int p = mxGetN(prhs[2]); if (mxGetM(prhs[2]) != static_cast(n)) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The number of rows of the third argument (Z) must match the number of rows of the first argument (T)!"); + mexErrMsgTxt("kalman_steady_state: The number of rows of the third argument (Z) must match the number of rows of the first argument (T)!"); if (mxIsNumeric(prhs[2]) == 0 || mxIsComplex(prhs[2]) == 1) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The third input argument (Z) must be a real matrix!"); + mexErrMsgTxt("kalman_steady_state: The third input argument (Z) must be a real matrix!"); if (measurement_error_flag) { if (mxGetM(prhs[3]) != mxGetN(prhs[3])) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The fourth input argument (H) must be a square matrix!"); + mexErrMsgTxt("kalman_steady_state: The fourth input argument (H) must be a square matrix!"); if (mxGetM(prhs[3]) != static_cast(p)) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The number of rows of the fourth input argument (H) must match the number of rows of the third input argument!"); + mexErrMsgTxt("kalman_steady_state: The number of rows of the fourth input argument (H) must match the number of rows of the third input argument!"); if (mxIsNumeric(prhs[3]) == 0 || mxIsComplex(prhs[3]) == 1) - DYN_MEX_FUNC_ERR_MSG_TXT("kalman_steady_state: The fifth input argument (H) must be a real matrix!"); + mexErrMsgTxt("kalman_steady_state: The fifth input argument (H) must be a real matrix!"); } // Get input matrices. const double *T = mxGetPr(prhs[0]); @@ -147,8 +147,8 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) auto DWORK = std::make_unique(LDWORK); auto BWORK = std::make_unique(nn); // Initialize the output of the mex file - plhs[1] = mxCreateDoubleMatrix(n, n, mxREAL); - double *P = mxGetPr(plhs[1]); + plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL); + double *P = mxGetPr(plhs[0]); // Call the slicot routine sb02od("D", // We want to solve a discrete Riccati equation. "B", // Matrices Z and H are given. @@ -164,25 +164,24 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) case 0: break; case 1: - DYN_MEX_FUNC_ERR_MSG_TXT("The computed extended matrix pencil is singular, possibly due to rounding errors.\n"); + mexErrMsgTxt("The computed extended matrix pencil is singular, possibly due to rounding errors."); break; case 2: - DYN_MEX_FUNC_ERR_MSG_TXT("The QZ (or QR) algorithm failed!\n"); + mexErrMsgTxt("The QZ (or QR) algorithm failed!"); break; case 3: - DYN_MEX_FUNC_ERR_MSG_TXT("The reordering of the (generalized) eigenvalues failed!\n"); + mexErrMsgTxt("The reordering of the (generalized) eigenvalues failed!"); break; case 4: - DYN_MEX_FUNC_ERR_MSG_TXT("After reordering, roundoff changed values of some complex eigenvalues so that leading eigenvalues\n in the (generalized) Schur form no longer satisfy the stability condition; this could also be caused due to scaling."); + mexErrMsgTxt("After reordering, roundoff changed values of some complex eigenvalues so that leading eigenvalues\n in the (generalized) Schur form no longer satisfy the stability condition; this could also be caused due to scaling."); break; case 5: - DYN_MEX_FUNC_ERR_MSG_TXT("The computed dimension of the solution does not equal n!\n"); + mexErrMsgTxt("The computed dimension of the solution does not equal n!"); break; case 6: - DYN_MEX_FUNC_ERR_MSG_TXT("A singular matrix was encountered during the computation of the solution matrix P!\n"); + mexErrMsgTxt("A singular matrix was encountered during the computation of the solution matrix P!"); break; default: - DYN_MEX_FUNC_ERR_MSG_TXT("Unknown problem!\n"); + mexErrMsgTxt("Unknown problem!"); } - plhs[0] = mxCreateDoubleScalar(0); } diff --git a/mex/sources/kronecker/A_times_B_kronecker_C.cc b/mex/sources/kronecker/A_times_B_kronecker_C.cc index 071122e3f..95d0f7268 100644 --- a/mex/sources/kronecker/A_times_B_kronecker_C.cc +++ b/mex/sources/kronecker/A_times_B_kronecker_C.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2019 Dynare Team + * Copyright © 2007-2020 Dynare Team * * This file is part of Dynare. * @@ -68,8 +68,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // Check input and output: - if (nrhs > 3 || nrhs < 2) - DYN_MEX_FUNC_ERR_MSG_TXT("A_times_B_kronecker_C takes 2 or 3 input arguments and provides 2 output arguments."); + if (nrhs > 3 || nrhs < 2 || nlhs != 1) + { + mexErrMsgTxt("A_times_B_kronecker_C takes 2 or 3 input arguments and provides 1 output argument."); + return; // Needed to shut up some GCC warnings + } // Get & Check dimensions (columns and rows): size_t mA = mxGetM(prhs[0]); @@ -82,12 +85,12 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mC = mxGetM(prhs[2]); nC = mxGetN(prhs[2]); if (mB*mC != nA) - DYN_MEX_FUNC_ERR_MSG_TXT("Input dimension error!"); + mexErrMsgTxt("Input dimension error!"); } else // A·(B⊗B) is to be computed. { if (mB*mB != nA) - DYN_MEX_FUNC_ERR_MSG_TXT("Input dimension error!"); + mexErrMsgTxt("Input dimension error!"); } // Get input matrices: const double *A = mxGetPr(prhs[0]); @@ -108,6 +111,4 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) full_A_times_kronecker_B_B(A, B, D, mA, nA, mB, nB); else full_A_times_kronecker_B_C(A, B, C, D, mA, nA, mB, nB, mC, nC); - - plhs[1] = mxCreateDoubleScalar(0); } diff --git a/mex/sources/kronecker/sparse_hessian_times_B_kronecker_C.cc b/mex/sources/kronecker/sparse_hessian_times_B_kronecker_C.cc index 93265998c..5eaa7eee5 100644 --- a/mex/sources/kronecker/sparse_hessian_times_B_kronecker_C.cc +++ b/mex/sources/kronecker/sparse_hessian_times_B_kronecker_C.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2007-2019 Dynare Team + * Copyright © 2007-2020 Dynare Team * * This file is part of Dynare. * @@ -135,11 +135,14 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // Check input and output: - if (nrhs > 4 || nrhs < 3) - DYN_MEX_FUNC_ERR_MSG_TXT("sparse_hessian_times_B_kronecker_C takes 3 or 4 input arguments and provides 2 output arguments."); + if (nrhs > 4 || nrhs < 3 || nlhs != 1) + { + mexErrMsgTxt("sparse_hessian_times_B_kronecker_C takes 3 or 4 input arguments and provides 1 output argument."); + return; // Needed to shut up some GCC warnings + } if (!mxIsSparse(prhs[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("sparse_hessian_times_B_kronecker_C: First input must be a sparse (dynare) hessian matrix."); + mexErrMsgTxt("sparse_hessian_times_B_kronecker_C: First input must be a sparse (dynare) hessian matrix."); // Get & Check dimensions (columns and rows): size_t mA = mxGetM(prhs[0]); @@ -152,12 +155,12 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mC = mxGetM(prhs[2]); nC = mxGetN(prhs[2]); if (mB*mC != nA) - DYN_MEX_FUNC_ERR_MSG_TXT("Input dimension error!"); + mexErrMsgTxt("Input dimension error!"); } else // A·(B⊗B) is to be computed. { if (mB*mB != nA) - DYN_MEX_FUNC_ERR_MSG_TXT("Input dimension error!"); + mexErrMsgTxt("Input dimension error!"); } // Get input matrices: int numthreads; @@ -185,6 +188,4 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) sparse_hessian_times_B_kronecker_B(isparseA, jsparseA, vsparseA, B, D, mA, nA, mB, nB, numthreads); else sparse_hessian_times_B_kronecker_C(isparseA, jsparseA, vsparseA, B, C, D, mA, nA, mB, nB, mC, nC, numthreads); - - plhs[1] = mxCreateDoubleScalar(0); } diff --git a/mex/sources/local_state_space_iterations/local_state_space_iteration_2.cc b/mex/sources/local_state_space_iterations/local_state_space_iteration_2.cc index 15b422771..d0dc82e16 100644 --- a/mex/sources/local_state_space_iterations/local_state_space_iteration_2.cc +++ b/mex/sources/local_state_space_iterations/local_state_space_iteration_2.cc @@ -31,7 +31,7 @@ #include -#define FIRST_ORDER_LOOP 1// Comment out this line to use mkl-blas instead of loops when computing ghx*yhat and ghu*epsilon +#define FIRST_ORDER_LOOP 1 // Comment out this line to use mkl-blas instead of loops when computing ghx*yhat and ghu*epsilon std::tuple, std::vector, std::vector> set_vector_of_indices(int n, int r) @@ -216,7 +216,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) prhs[7] ghxu [double] m×nq array, second order reduced form. prhs[8] yhat_ [double] [OPTIONAL] n×s array, time t particles (pruning additional latent variables). prhs[9] ss [double] [OPTIONAL] m×1 array, steady state for the union of the states and the observed variables (needed for the pruning mode). - + prhs[9 or 11] [double] num of threads plhs[0] y [double] n×s array, time t+1 particles. @@ -231,14 +231,14 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Too many output arguments."); // Get dimensions. - size_t n = mxGetM(prhs[0]);// Number of states. - size_t s = mxGetN(prhs[0]);// Number of particles. - size_t q = mxGetM(prhs[1]);// Number of innovations. - size_t m = mxGetM(prhs[2]);// Number of elements in the union of states and observed variables. + size_t n = mxGetM(prhs[0]); // Number of states. + size_t s = mxGetN(prhs[0]); // Number of particles. + size_t q = mxGetM(prhs[1]); // Number of innovations. + size_t m = mxGetM(prhs[2]); // Number of elements in the union of states and observed variables. //mexPrintf("\n s (the number of column of yhat) is equal to %d.", s); //mexPrintf("\n The number of column of epsilon is %d.", mxGetN(prhs[1])); // Check the dimensions. - if (s != mxGetN(prhs[1]) // Number of columns for epsilon + if (s != mxGetN(prhs[1]) // Number of columns for epsilon || n != mxGetN(prhs[2]) // Number of columns for ghx || m != mxGetM(prhs[3]) // Number of rows for ghu || q != mxGetN(prhs[3]) // Number of columns for ghu @@ -248,12 +248,12 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) || m != mxGetM(prhs[6]) // Number of rows for ghuu || q*q != mxGetN(prhs[6]) // Number of columns for ghuu || m != mxGetM(prhs[7]) // Number of rows for ghxu - || n*q != mxGetN(prhs[7])) // Number of rows for ghxu + || n*q != mxGetN(prhs[7])) // Number of rows for ghxu mexErrMsgTxt("Input dimension mismatch!."); if (nrhs > 9) - if (n != mxGetM(prhs[8]) // Number of rows for yhat_ - || s != mxGetN(prhs[8]) // Number of columns for yhat_ - || m != mxGetM(prhs[9])) // Number of rows for ss + if (n != mxGetM(prhs[8]) // Number of rows for yhat_ + || s != mxGetN(prhs[8]) // Number of columns for yhat_ + || m != mxGetM(prhs[9])) // Number of rows for ss mexErrMsgTxt("Input dimension mismatch!."); // Get Input arrays. diff --git a/mex/sources/local_state_space_iterations/local_state_space_iteration_k.cc b/mex/sources/local_state_space_iterations/local_state_space_iteration_k.cc new file mode 100644 index 000000000..43e9a4779 --- /dev/null +++ b/mex/sources/local_state_space_iterations/local_state_space_iteration_k.cc @@ -0,0 +1,179 @@ +/* + * Copyright © 2019 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 . + */ + +#include +#include +#include + +#include + +#include "tl_static.hh" +#include "decision_rule.hh" +#include "sthread.hh" + +/* The class that does the real job. It computes the next iteration for a given + range of particles. There will be as many instances as there are parallel + threads. + + Note that we can’t use OpenMP since it is incompatible with MKL, which is + used internally by Dynare++ routines under MATLAB. Hence we fall back to + the Dynare++ multithreading abstraction. */ +struct ParticleWorker : public sthread::detach_thread +{ + const int npred_both, exo_nbr; + const std::pair particle_range; + const ConstGeneralMatrix &yhat, ε + const Vector &ys_reordered; + const UnfoldDecisionRule &dr; + GeneralMatrix &ynext; + + ParticleWorker(int npred_both_arg, int exo_nbr_arg, std::pair particle_range_arg, + const ConstGeneralMatrix &yhat_arg, const ConstGeneralMatrix &epsilon_arg, + const Vector &ys_reordered_arg, const UnfoldDecisionRule &dr_arg, + GeneralMatrix &ynext_arg) + : npred_both{npred_both_arg}, exo_nbr{exo_nbr_arg}, particle_range{std::move(particle_range_arg)}, + yhat{yhat_arg}, epsilon{epsilon_arg}, ys_reordered{ys_reordered_arg}, dr{dr_arg}, + ynext{ynext_arg} + { + } + void + operator()(std::mutex &mut) override + { + Vector dyu(npred_both+exo_nbr); + Vector dy(dyu, 0, npred_both); + Vector u(dyu, npred_both, exo_nbr); + + for (size_t i = particle_range.first; i < particle_range.second; i++) + { + dy = yhat.getCol(i); + u = epsilon.getCol(i); + Vector ynext_col{ynext.getCol(i)}; + + dr.eval(DecisionRule::emethod::horner, ynext_col, dyu); + + ynext_col.add(1.0, ys_reordered); + } + } +}; + +void +mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + if (nrhs != 5 || nlhs != 1) + mexErrMsgTxt("Must have 5 input arguments and 1 output argument"); + + // Give explicit names to input arguments + const mxArray *yhat_mx = prhs[0]; + const mxArray *epsilon_mx = prhs[1]; + const mxArray *dr_mx = prhs[2]; + const mxArray *M_mx = prhs[3]; + const mxArray *options_mx = prhs[4]; + + auto get_int_field = [](const mxArray *struct_mx, const std::string &fieldname) + { + mxArray *field_mx = mxGetField(struct_mx, 0, fieldname.c_str()); + if (!(field_mx && mxIsScalar(field_mx) && mxIsNumeric(field_mx))) + mexErrMsgTxt(("Field `" + fieldname + "' should be a numeric scalar").c_str()); + return static_cast(mxGetScalar(field_mx)); + }; + + int nstatic = get_int_field(M_mx, "nstatic"); + int npred = get_int_field(M_mx, "npred"); + int nboth = get_int_field(M_mx, "nboth"); + int nfwrd = get_int_field(M_mx, "nfwrd"); + int endo_nbr = nstatic + npred + nboth + nfwrd; + int exo_nbr = get_int_field(M_mx, "exo_nbr"); + int order = get_int_field(options_mx, "order"); + + const mxArray *order_var_mx = mxGetField(dr_mx, 0, "order_var"); + if (!(order_var_mx && mxIsDouble(order_var_mx) && mxGetNumberOfElements(order_var_mx) == static_cast(endo_nbr))) + mexErrMsgTxt("Field dr.order_var should be a double precision vector with endo_nbr elements"); + const mxArray *ys_mx = mxGetField(dr_mx, 0, "ys"); + if (!ys_mx || !mxIsDouble(ys_mx) || mxGetNumberOfElements(ys_mx) != static_cast(endo_nbr)) + mexErrMsgTxt("Field dr.ys should be a double precision vector with endo_nbr elements"); + + size_t nparticles = mxGetN(yhat_mx); + if (mxGetN(epsilon_mx) != nparticles) + mexErrMsgTxt("epsilon and yhat don't have the same number of columns"); + if (!(mxIsDouble(yhat_mx) && mxGetM(yhat_mx) == static_cast(npred + nboth))) + mexErrMsgTxt("yhat should be a double precision matrix with npred+nboth rows"); + if (!(mxIsDouble(epsilon_mx) && mxGetM(epsilon_mx) == static_cast(exo_nbr))) + mexErrMsgTxt("epsilon should be a double precision matrix with exo_nbr rows"); + + const mxArray *threads_mx = mxGetField(options_mx, 0, "threads"); + if (!threads_mx) + mexErrMsgTxt("Can't find field `threads' in options_"); + int num_threads = get_int_field(threads_mx, "local_state_space_iteration_k"); + + ConstGeneralMatrix yhat{yhat_mx}; + ConstGeneralMatrix epsilon{epsilon_mx}; + ConstVector ys{ys_mx}; + const double *order_var = mxGetPr(order_var_mx); + + try + { + TLStatic::init(order, npred+nboth+exo_nbr); + } + catch (TLException &e) + { + mexErrMsgTxt(("Dynare++ error: " + e.message).c_str()); + } + + // Form the polynomial (copied from dynare_simul_.cc) + UTensorPolynomial pol(endo_nbr, npred+nboth+exo_nbr); + for (int dim = 0; dim <= order; dim++) + { + const mxArray *gk_m = mxGetField(dr_mx, 0, ("g_" + std::to_string(dim)).c_str()); + if (!gk_m) + mexErrMsgTxt(("Can't find field `g_" + std::to_string(dim) + "' in dr structure").c_str()); + ConstTwoDMatrix gk{gk_m}; + FFSTensor ft{endo_nbr, npred+nboth+exo_nbr, dim}; + if (ft.ncols() != gk.ncols()) + mexErrMsgTxt(("Wrong number of columns for folded tensor: got " + std::to_string(gk.ncols()) + " but i want " + std::to_string(ft.ncols()) + '\n').c_str()); + if (ft.nrows() != gk.nrows()) + mexErrMsgTxt(("Wrong number of rows for folded tensor: got " + std::to_string(gk.nrows()) + " but i want " + std::to_string(ft.nrows()) + '\n').c_str()); + ft.zeros(); + ft.add(1.0, gk); + pol.insert(std::make_unique(ft)); + } + + // Construct the reordered steady state (dr.ys(dr.order_var)) + Vector ys_reordered(endo_nbr); + for (int i = 0; i < endo_nbr; i++) + ys_reordered[i] = ys[static_cast(order_var[i])-1]; + + // Form the decision rule + UnfoldDecisionRule dr(pol, PartitionY(nstatic, npred, nboth, nfwrd), + exo_nbr, ys_reordered); + + // Create the result matrix + plhs[0] = mxCreateDoubleMatrix(endo_nbr, nparticles, mxREAL); + GeneralMatrix ynext{plhs[0]}; + + // Run the real job in parallel + sthread::detach_thread_group::max_parallel_threads = num_threads; + sthread::detach_thread_group group; + // The following is equivalent to ceil(nparticles/num_threads), but with integer arithmetic + int part_by_thread = nparticles / num_threads + (nparticles % num_threads > 0); + for (size_t i = 0; i < nparticles; i += part_by_thread) + group.insert(std::make_unique(npred+nboth, exo_nbr, + std::make_pair(i, std::min(i+part_by_thread, nparticles)), + yhat, epsilon, ys_reordered, dr, ynext)); + group.run(); +} diff --git a/mex/sources/matlab_mex.F08 b/mex/sources/matlab_mex.F08 index 1fbbf8ba9..7a853f710 100644 --- a/mex/sources/matlab_mex.F08 +++ b/mex/sources/matlab_mex.F08 @@ -52,7 +52,7 @@ # define API_VER2 "" #endif -#define MX_HAS_INTERLEAVED_COMPLEX (defined(MATLAB_MEX_FILE) && MATLAB_VERSION >= 0x0904) +#include "defines.F08" !!! C Matrix API !!! Listed in same order as https://fr.mathworks.com/help/matlab/cc-mx-matrix-library.html diff --git a/mex/sources/mjdgges/mjdgges.F08 b/mex/sources/mjdgges/mjdgges.F08 new file mode 100644 index 000000000..5209c01d1 --- /dev/null +++ b/mex/sources/mjdgges/mjdgges.F08 @@ -0,0 +1,165 @@ +! Copyright © 2006-2020 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 . + +#include "defines.F08" + +module select_fct_mod + use iso_fortran_env + implicit none + + real(real64) :: criterium +contains + logical(bllog) function select_fct(alpha_r, alpha_i, beta) + use blas + + real(real64), intent(in) :: alpha_r, alpha_i, beta + + select_fct = alpha_r**2 + alpha_i**2 < criterium**2 * beta**2 + end function select_fct +end module select_fct_mod + +subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction') + use iso_fortran_env + use iso_c_binding + use select_fct_mod + use matlab_mex + use lapack + implicit none + + type(c_ptr), dimension(*), intent(in), target :: prhs + type(c_ptr), dimension(*), intent(out) :: plhs + integer(c_int), intent(in), value :: nlhs, nrhs + + integer(c_size_t) :: m1, n1, m2, n2 + real(real64) :: zhreshold + integer(blint) :: n_bl, lwork, info_bl, sdim_bl + real(real64), dimension(:), allocatable :: alpha_r, alpha_i, beta, work + logical(bllog), dimension(:), allocatable :: bwork + real(real64), dimension(:), pointer :: s, t, z, info, sdim, vsl +#if MX_HAS_INTERLEAVED_COMPLEX + complex(real64), dimension(:), pointer :: gev +#else + real(real64), dimension(:), pointer :: gev_r, gev_i +#endif +#if defined(MATLAB_MEX_FILE) && MATLAB_VERSION < 0x0904 + ! Workaround for MKL bug, see below + real(real64), dimension(:), allocatable, target :: vsl_target +#endif + + if (nrhs < 2 .or. nrhs > 4 .or. nlhs /= 6) then + call mexErrMsgTxt("MJDGGES: takes 2, 3 or 4 input arguments and exactly 6 output arguments.") + return + end if + + m1 = mxGetM(prhs(1)) + n1 = mxGetN(prhs(1)) + m2 = mxGetM(prhs(2)) + n2 = mxGetN(prhs(2)) + + if (.not. mxIsDouble(prhs(1)) .or. mxIsComplex(prhs(1)) & + .or. .not. mxIsDouble(prhs(2)) .or. mxIsComplex(prhs(2)) & + .or. m1 /= n1 .or. m2 /= n1 .or. m2 /= n2) then + call mexErrMsgTxt("MJDGGES requires two square real matrices of the same dimension.") + return + end if + + ! Set criterium for stable eigenvalues + if (nrhs >= 3 .and. mxGetM(prhs(3)) > 0) then + associate (crit_arg => mxGetPr(prhs(3))) + criterium = crit_arg(1) + end associate + else + criterium = 1_real64 + 1e-6_real64 + end if + + ! set criterium for 0/0 generalized eigenvalues */ + if (nrhs == 4 .and. mxGetM(prhs(4)) > 0) then + associate (zhresh_arg => mxGetPr(prhs(4))) + zhreshold = zhresh_arg(1) + end associate + else + zhreshold = 1e-6_real64 + end if + + plhs(1) = mxCreateDoubleMatrix(n1, n1, mxREAL) + plhs(2) = mxCreateDoubleMatrix(n1, n1, mxREAL) + plhs(3) = mxCreateDoubleMatrix(n1, n1, mxREAL) + plhs(4) = mxCreateDoubleMatrix(1_mwSize, 1_mwSize, mxREAL) + plhs(5) = mxCreateDoubleMatrix(n1, 1_mwSize, mxCOMPLEX) + plhs(6) = mxCreateDoubleMatrix(1_mwSize, 1_mwSize, mxREAL) + + s => mxGetPr(plhs(1)) + t => mxGetPr(plhs(2)) + sdim => mxGetPr(plhs(4)) +#if MX_HAS_INTERLEAVED_COMPLEX + gev => mxGetComplexDoubles(plhs(5)) +#else + gev_r => mxGetPr(plhs(5)) + gev_i => mxGetPi(plhs(5)) +#endif + info => mxGetPr(plhs(6)) + z => mxGetPr(plhs(3)) +#if defined(MATLAB_MEX_FILE) && MATLAB_VERSION < 0x0904 + ! The left Schur vectors (VSL) are normally not computed, since JOBVSL="N". + ! But old MKL versions (at least the one shipped with MATLAB R2009b/7.9, + ! which is MKL 10.1) are buggy, and passing nullptr for VSL leads to a crash. + ! Hence we need to allocate space for it. + ! The bug seems to be fixed in MATLAB R2010a/7.10 (MKL 10.2), but we use the + ! workaround for all versions < R2018a/9.4, since those share the same + ! ABI and hence the same executables. + allocate(vsl_target(n1*n1)) + vsl => vsl_target +#else + vsl => null() +#endif + + ! Copy input matrices, since we can’t modify them + associate (a => mxGetPr(prhs(1)), b => mxGetPr(prhs(2))) + s = a + t = b + end associate + + n_bl = int(n1, blint) + lwork = 16*n_bl + 16 + allocate(alpha_r(n_bl), alpha_i(n_bl), beta(n_bl), bwork(n_bl), work(lwork)) + + call dgges("N", "V", "S", select_fct, n_bl, s, n_bl, t, n_bl, sdim_bl, & + alpha_r, alpha_i, beta, vsl, n_bl, z, n_bl, work, lwork, bwork, info_bl) + + info = info_bl + sdim = sdim_bl + +#if MX_HAS_INTERLEAVED_COMPLEX + where (alpha_i == 0_real64 .and. beta == 0_real64) + gev = alpha_r / beta + elsewhere + gev = cmplx(alpha_r, alpha_i, real64) / beta + end where +#else + gev_r = alpha_r / beta + where (alpha_i == 0_real64 .and. beta == 0_real64) + gev_i = 0_real64 + elsewhere + gev_i = alpha_i / beta + end where +#endif + + ! If the ratio of some eigenvalue is too close to 0/0, return specific + ! error number (only if no other error) + if (any(abs(alpha_r) <= zhreshold .and. abs(beta) <= zhreshold) .and. info_bl == 0) & + info = 30 +end subroutine mexFunction diff --git a/mex/sources/mjdgges/mjdgges.cc b/mex/sources/mjdgges/mjdgges.cc deleted file mode 100644 index b3873a90a..000000000 --- a/mex/sources/mjdgges/mjdgges.cc +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright © 2006-2019 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 . - */ - -#include -#include -#include - -#include -#include - -double criterium; - -lapack_int -my_criteria(const double *alpha_r, const double *alpha_i, const double *beta) -{ - return *alpha_r * *alpha_r + *alpha_i * *alpha_i < criterium * criterium * *beta * *beta; -} - -/* MATLAB interface */ -void -mexFunction(int nlhs, mxArray *plhs[], - int nrhs, const mxArray *prhs[]) -{ - /* Check for proper number of arguments */ - if (nrhs < 2 || nrhs > 4 || nlhs == 0 || nlhs > 7) - DYN_MEX_FUNC_ERR_MSG_TXT("MJDGGES: takes 2, 3 or 4 input arguments and between 1 and 7 output arguments."); - - /* Check that A and B are real matrices of the same dimension.*/ - size_t m1 = mxGetM(prhs[0]); - size_t n1 = mxGetN(prhs[0]); - size_t m2 = mxGetM(prhs[1]); - size_t n2 = mxGetN(prhs[1]); - if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) - || !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) - || m1 != n1 || m2 != n1 || m2 != n2) - DYN_MEX_FUNC_ERR_MSG_TXT("MJDGGES requires two square real matrices of the same dimension."); - - /* Create a matrix for the return argument */ - plhs[1] = mxCreateDoubleMatrix(n1, n1, mxREAL); - plhs[2] = mxCreateDoubleMatrix(n1, n1, mxREAL); - plhs[3] = mxCreateDoubleMatrix(n1, n1, mxREAL); - plhs[4] = mxCreateDoubleMatrix(1, 1, mxREAL); - plhs[5] = mxCreateDoubleMatrix(n1, 1, mxCOMPLEX); - plhs[6] = mxCreateDoubleMatrix(1, 1, mxREAL); - - /* Assign pointers to the various parameters */ - double *s = mxGetPr(plhs[1]); - double *t = mxGetPr(plhs[2]); - double *z = mxGetPr(plhs[3]); - double *sdim = mxGetPr(plhs[4]); -#if MX_HAS_INTERLEAVED_COMPLEX - mxComplexDouble *gev = mxGetComplexDoubles(plhs[5]); -#else - double *gev_r = mxGetPr(plhs[5]); - double *gev_i = mxGetPi(plhs[5]); -#endif - double *info = mxGetPr(plhs[6]); - - const double *a = mxGetPr(prhs[0]); - const double *b = mxGetPr(prhs[1]); - - /* set criterium for stable eigenvalues */ - if (nrhs >= 3 && mxGetM(prhs[2]) > 0) - criterium = *mxGetPr(prhs[2]); - else - criterium = 1+1e-6; - - /* set criterium for 0/0 generalized eigenvalues */ - double zhreshold; - if (nrhs == 4 && mxGetM(prhs[3]) > 0) - zhreshold = *mxGetPr(prhs[3]); - else - zhreshold = 1e-6; - - /* keep a and b intact */ - std::copy_n(a, n1*n1, s); - std::copy_n(b, n1*n1, t); - - lapack_int i_n = static_cast(n1); - auto alpha_r = std::make_unique(n1); - auto alpha_i = std::make_unique(n1); - auto beta = std::make_unique(n1); - lapack_int lwork = 16*i_n+16; - auto work = std::make_unique(lwork); - auto bwork = std::make_unique(i_n); - lapack_int i_info, i_sdim; -#if defined(MATLAB_MEX_FILE) && MATLAB_VERSION < 0x0904 - /* The left Schur vectors (VSL) are normally not computed, since JOBVSL="N". - But old MKL versions (at least the one shipped with MATLAB R2009b/7.9, which - is MKL 10.1) are - buggy, and passing nullptr for VSL leads to a crash. Hence we need to - allocate space for it. - The bug seems to be fixed in MATLAB R2010a/7.10 (MKL 10.2), but we use the - workaround for all versions < R2018a/9.4, since those share the same - ABI and hence the same executables. */ - auto vsl = std::make_unique(n1*n1); -#endif - - dgges("N", "V", "S", my_criteria, &i_n, s, &i_n, t, &i_n, &i_sdim, alpha_r.get(), alpha_i.get(), - beta.get(), -#if defined(MATLAB_MEX_FILE) && MATLAB_VERSION < 0x0904 - vsl.get(), -#else - nullptr, -#endif - &i_n, z, &i_n, work.get(), &lwork, bwork.get(), &i_info); - - *sdim = static_cast(i_sdim); - *info = static_cast(i_info); - - for (size_t i = 0; i < n1; i++) - { - if (std::abs(alpha_r[i]) > zhreshold || std::abs(beta[i]) > zhreshold) -#if MX_HAS_INTERLEAVED_COMPLEX - gev[i].real = alpha_r[i] / beta[i]; -#else - gev_r[i] = alpha_r[i] / beta[i]; -#endif - else - { - /* the ratio is too close to 0/0; - returns specific error number only if no other error */ - if (*info == 0) - *info = -30; - } - if (alpha_i[i] == 0.0 && beta[i] == 0.0) -#if MX_HAS_INTERLEAVED_COMPLEX - gev[i].imag = 0.0; -#else - gev_i[i] = 0.0; -#endif - else -#if MX_HAS_INTERLEAVED_COMPLEX - gev[i].imag = alpha_i[i] / beta[i]; -#else - gev_i[i] = alpha_i[i] / beta[i]; -#endif - } - - plhs[0] = mxCreateDoubleScalar(0); -} diff --git a/mex/sources/ms-sbvar/mex_top_level.cc b/mex/sources/ms-sbvar/mex_top_level.cc index 7c2f6d56b..5022d9501 100644 --- a/mex/sources/ms-sbvar/mex_top_level.cc +++ b/mex/sources/ms-sbvar/mex_top_level.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2010-2017 Dynare Team + * Copyright © 2010-2020 Dynare Team * * This file is part of Dynare. * @@ -17,9 +17,9 @@ * along with Dynare. If not, see . */ -#include -#include -#include +#include +#include +#include #include #include "modify_for_mex.h" @@ -31,45 +31,39 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int nargs = 0; - int n = 0; - int maxnargs = 0; - const char *mainarg = "./a.out"; - char *argument = NULL; - char *beginarg = NULL; - char **args = NULL; /* * Check args */ - if (nrhs != 1 || !mxIsChar(prhs[0]) || nlhs != 1) - DYN_MEX_FUNC_ERR_MSG_TXT("Error in MS-SBVAR MEX file: this function takes 1 string input argument and returns 1 output argument."); + if (nrhs != 1 || !mxIsChar(prhs[0]) || nlhs != 0) + mexErrMsgTxt("Error in MS-SBVAR MEX file: this function takes 1 string input argument and returns no output argument."); /* * Allocate memory */ - maxnargs = static_cast (mxGetN(prhs[0])/2+1); - argument = static_cast (mxCalloc(mxGetN(prhs[0])+1, sizeof(char))); - args = static_cast (mxCalloc(maxnargs, sizeof(char *))); - if (argument == NULL || args == NULL) - DYN_MEX_FUNC_ERR_MSG_TXT("Error in MS-SBVAR MEX file: could not allocate memory. (1)"); + int maxnargs = static_cast(mxGetN(prhs[0])/2+1); + char *argument = static_cast(mxCalloc(mxGetN(prhs[0])+1, sizeof(char))); + char **args = static_cast(mxCalloc(maxnargs, sizeof(char *))); + if (!argument || !args) + mexErrMsgTxt("Error in MS-SBVAR MEX file: could not allocate memory. (1)"); /* * Create argument string from prhs and parse to create args / nargs */ - if (!(args[nargs] = static_cast (mxCalloc(strlen(mainarg)+1, sizeof(char))))) - DYN_MEX_FUNC_ERR_MSG_TXT("Error in MS-SBVAR MEX file: could not allocate memory. (2)"); + if (!(args[nargs] = static_cast(mxCalloc(strlen(mainarg)+1, sizeof(char))))) + mexErrMsgTxt("Error in MS-SBVAR MEX file: could not allocate memory. (2)"); - strncpy(args[nargs++], mainarg, strlen(mainarg)); + strcpy(args[nargs++], mainarg); if (mxGetString(prhs[0], argument, mxGetN(prhs[0])+1)) - DYN_MEX_FUNC_ERR_MSG_TXT("Error in MS-SBVAR MEX file: error using mxGetString.\n"); + mexErrMsgTxt("Error in MS-SBVAR MEX file: error using mxGetString.\n"); - beginarg = &argument[0]; - while ((n = strcspn(beginarg, " "))) + char *beginarg = argument; + while (int n = strcspn(beginarg, " ")) { - if (!(args[nargs] = static_cast (mxCalloc(n+1, sizeof(char))))) - DYN_MEX_FUNC_ERR_MSG_TXT("Error in MS-SBVAR MEX file: could not allocate memory. (3)"); + if (!(args[nargs] = static_cast(mxCalloc(n+1, sizeof(char))))) + mexErrMsgTxt("Error in MS-SBVAR MEX file: could not allocate memory. (3)"); strncpy(args[nargs++], beginarg, n); beginarg += (isspace(beginarg[n]) || isblank(beginarg[n]) ? ++n : n); @@ -85,15 +79,13 @@ mexFunction(int nlhs, mxArray *plhs[], } catch (const char *str) { - DYN_MEX_FUNC_ERR_MSG_TXT(str); + mexErrMsgTxt(str); } /* * free memory */ - for (n = 0; n < nargs; n++) + for (int n = 0; n < nargs; n++) mxFree(args[n]); mxFree(args); - - plhs[0] = mxCreateDoubleScalar(0); } diff --git a/mex/sources/ms-sbvar/mex_write_to_matlab.c b/mex/sources/ms-sbvar/mex_write_to_matlab.c deleted file mode 100644 index 84af6c6a5..000000000 --- a/mex/sources/ms-sbvar/mex_write_to_matlab.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright © 2011-2017 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 . - */ - -#include -#include - -#include "modify_for_mex.h" - -void -mex_write_to_matlab_matfile(double *data, int rows, int cols, const char *varname, const char *filename) -{ - mxArray *toWrite; - toWrite = getMxArray(data, rows, cols); - MATFile *matfile = matOpen(filename, "w"); - if (matfile == NULL) - mexErrMsgTxt("Error encountered in mex when opening a .mat file"); - - if (matPutVariable(matfile, varname, toWrite) != 0 - || ferror(matGetFp(matfile)) > 0 - || feof(matGetFp(matfile)) > 0) - mexErrMsgTxt("Error encountered in mex when writing a .mat file"); - - if (matClose(matfile) != 0) - mexErrMsgTxt("Error encountered in mex when closing a .mat file"); -} - -void -mex_write_to_matlab_global_struct(double *data, int rows, int cols, const char *varname) -{ - mxArray *toWrite; - toWrite = getMxArray(data, rows, cols); - - int fieldnumber = mxAddField(globalMatlabStruct, varname); - if (fieldnumber < 0) - mexErrMsgTxt("Error encountered in mex when assigining to global structure"); - mxSetFieldByNumber(globalMatlabStruct, 0, fieldnumber, toWrite); -} - -mxArray * -getMxArray(double *data, int rows, int cols) -{ - mxArray *mat; - double *pind; - int i; - - if (rows == 1 && cols == 1) - mat = mxCreateDoubleScalar(data[0]); - else - { - mat = mxCreateDoubleMatrix(rows, cols, mxREAL); - if (mat != NULL) - { - pind = mxGetPr(mat); - for (i = 0; i < rows*cols; i++) - pind[i] = data[i]; - } - } - if (mat == NULL) - mexErrMsgTxt("Error encountered in mex: not enough heap space to allocate memory for mxArray"); - return mat; -} diff --git a/mex/sources/ms-sbvar/modify_for_mex.cc b/mex/sources/ms-sbvar/modify_for_mex.cc index 42bbe64fa..bdcf2a85d 100644 --- a/mex/sources/ms-sbvar/modify_for_mex.cc +++ b/mex/sources/ms-sbvar/modify_for_mex.cc @@ -19,12 +19,12 @@ #if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE) -#include +# include -#ifdef __cplusplus +# ifdef __cplusplus extern "C" { -#endif +# endif int constant_seed; @@ -34,7 +34,7 @@ extern "C" throw "Error in MS-SBVAR MEX file.\n"; } -#ifdef __cplusplus +# ifdef __cplusplus } -#endif +# endif #endif diff --git a/mex/sources/ms-sbvar/modify_for_mex.h b/mex/sources/ms-sbvar/modify_for_mex.h index 19ad4f112..351692e0d 100644 --- a/mex/sources/ms-sbvar/modify_for_mex.h +++ b/mex/sources/ms-sbvar/modify_for_mex.h @@ -1,5 +1,5 @@ /* - * Copyright © 2010-2017 Dynare Team + * Copyright © 2010-2020 Dynare Team * * This file is part of Dynare. * @@ -42,11 +42,5 @@ extern bool utIsInterruptPending(); void msExit(int status); extern int constant_seed; -/* Write Matlab Output - mxArray *globalMatlabStruct;*/ -void mex_write_to_matlab_matfile(double *, int, int, const char *, const char *); -void mex_write_to_matlab_global_struct(double *, int, int, const char *); -mxArray *getMxArray(double *, int, int); - #endif #endif diff --git a/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh b/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh index 4dd1d02c8..abfc019f1 100644 --- a/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh +++ b/mex/sources/perfect_foresight_problem/DynamicModelCaller.hh @@ -39,7 +39,9 @@ public: // Used to store error messages (as exceptions cannot cross the OpenMP boundary) static std::string error_msg; - DynamicModelCaller(bool linear_arg, bool compute_jacobian_arg) : linear{linear_arg}, compute_jacobian{compute_jacobian_arg} {}; + DynamicModelCaller(bool linear_arg, bool compute_jacobian_arg) : linear{linear_arg}, compute_jacobian{compute_jacobian_arg} + { + }; virtual ~DynamicModelCaller() = default; virtual double &y(size_t i) const = 0; virtual double jacobian(size_t i) const = 0; @@ -55,7 +57,7 @@ private: static void *dynamic_mex; #endif using dynamic_tt_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, double *T); - using dynamic_deriv_fct = void (*) (const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *deriv); + using dynamic_deriv_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *deriv); static dynamic_tt_fct residual_tt_fct, g1_tt_fct; static dynamic_deriv_fct residual_fct, g1_fct; size_t nb_row_x; @@ -65,8 +67,16 @@ private: public: DynamicModelDllCaller(size_t ntt, mwIndex nx, mwIndex ny, size_t ndynvars, const double *x_arg, size_t nb_row_x_arg, const double *params_arg, const double *steady_state_arg, bool linear_arg, bool compute_jacobian_arg); virtual ~DynamicModelDllCaller() = default; - double &y(size_t i) const override { return y_p[i]; }; - double jacobian(size_t i) const override { return jacobian_p[i]; }; + double & + y(size_t i) const override + { + return y_p[i]; + }; + double + jacobian(size_t i) const override + { + return jacobian_p[i]; + }; void eval(int it, double *resid) override; static void load_dll(const std::string &basename); static void unload_dll(); @@ -85,13 +95,23 @@ private: public: DynamicModelMatlabCaller(std::string basename_arg, size_t ntt, size_t ndynvars, const mxArray *x_mx_arg, const mxArray *params_mx_arg, const mxArray *steady_state_mx_arg, bool linear_arg, bool compute_jacobian_arg); ~DynamicModelMatlabCaller() override; - double &y(size_t i) const override { return mxGetPr(y_mx)[i]; }; - double jacobian(size_t i) const override { return jacobian_mx ? mxGetPr(jacobian_mx)[i] : std::numeric_limits::quiet_NaN(); }; + double & + y(size_t i) const override + { + return mxGetPr(y_mx)[i]; + }; + double + jacobian(size_t i) const override + { + return jacobian_mx ? mxGetPr(jacobian_mx)[i] : std::numeric_limits::quiet_NaN(); + }; void eval(int it, double *resid) override; - class Exception { + class Exception + { public: const std::string msg; - Exception(std::string msg_arg) : msg{std::move(msg_arg)} {}; + Exception(std::string msg_arg) : msg{std::move(msg_arg)} + { + }; }; }; - diff --git a/mex/sources/sobol/gaussian.hh b/mex/sources/sobol/gaussian.hh index ea5377cb9..a259c66a9 100644 --- a/mex/sources/sobol/gaussian.hh +++ b/mex/sources/sobol/gaussian.hh @@ -45,36 +45,36 @@ icdf(const T uniform) { static T A[6] = { - -3.969683028665376e+01, - 2.209460984245205e+02, - -2.759285104469687e+02, - 1.383577518672690e+02, - -3.066479806614716e+01, - 2.506628277459239e+00 + -3.969683028665376e+01, + 2.209460984245205e+02, + -2.759285104469687e+02, + 1.383577518672690e+02, + -3.066479806614716e+01, + 2.506628277459239e+00 }; static T B[5] = { - -5.447609879822406e+01, - 1.615858368580409e+02, - -1.556989798598866e+02, - 6.680131188771972e+01, - -1.328068155288572e+01 + -5.447609879822406e+01, + 1.615858368580409e+02, + -1.556989798598866e+02, + 6.680131188771972e+01, + -1.328068155288572e+01 }; static T C[6] = { - -7.784894002430293e-03, - -3.223964580411365e-01, - -2.400758277161838e+00, - -2.549732539343734e+00, - 4.374664141464968e+00, - 2.938163982698783e+00 + -7.784894002430293e-03, + -3.223964580411365e-01, + -2.400758277161838e+00, + -2.549732539343734e+00, + 4.374664141464968e+00, + 2.938163982698783e+00 }; static T D[4] = { - 7.784695709041462e-03, - 3.224671290700398e-01, - 2.445134137142996e+00, - 3.754408661907416e+00 + 7.784695709041462e-03, + 3.224671290700398e-01, + 2.445134137142996e+00, + 3.754408661907416e+00 }; T gaussian = static_cast(0.0); if (0 < uniform && uniform < lb) @@ -148,15 +148,15 @@ usphere(int d, int n, T *U) { icdfm(n*d, U); #pragma omp parallel for - for (int j = 0; j < n; j++)// sequence index. + for (int j = 0; j < n; j++) // sequence index. { int k = j*d; double norm = 0.0; - for (int i = 0; i < d; i++)// dimension index. + for (int i = 0; i < d; i++) // dimension index. norm = norm + U[k+i]*U[k+i]; norm = sqrt(norm); - for (int i = 0; i < d; i++)// dimension index. + for (int i = 0; i < d; i++) // dimension index. U[k+i] = U[k+i]/norm; } } @@ -167,15 +167,15 @@ usphereRadius(int d, int n, double radius, T *U) { icdfm(n*d, U); #pragma omp parallel for - for (int j = 0; j < n; j++)// sequence index. + for (int j = 0; j < n; j++) // sequence index. { int k = j*d; double norm = 0.0; - for (int i = 0; i < d; i++)// dimension index. + for (int i = 0; i < d; i++) // dimension index. norm = norm + U[k+i]*U[k+i]; norm = sqrt(norm); - for (int i = 0; i < d; i++)// dimension index. + for (int i = 0; i < d; i++) // dimension index. U[k+i] = radius*U[k+i]/norm; } } diff --git a/mex/sources/sobol/qmc_sequence.cc b/mex/sources/sobol/qmc_sequence.cc index 51b19b2e0..21a03dc1f 100644 --- a/mex/sources/sobol/qmc_sequence.cc +++ b/mex/sources/sobol/qmc_sequence.cc @@ -1,7 +1,7 @@ /* ** Computes Quasi Monte-Carlo sequence. ** -** Copyright © 2010-2017 Dynare Team +** Copyright © 2010-2020 Dynare Team ** ** This file is part of Dynare (can be used outside Dynare). ** @@ -52,23 +52,23 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) ** Check the number of input and output arguments. */ if (nrhs < 3 || nrhs > 5) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: Five, four or three input arguments are required!"); + mexErrMsgTxt("qmc_sequence:: Five, four or three input arguments are required!"); if (nlhs == 0) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: At least one output argument is required!"); + mexErrMsgTxt("qmc_sequence:: At least one output argument is required!"); /* ** Test the first input argument and assign it to dimension. */ if (!mxIsNumeric(prhs[0])) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: First input (dimension) has to be a positive integer!"); + mexErrMsgTxt("qmc_sequence:: First input (dimension) has to be a positive integer!"); int dimension = static_cast(mxGetScalar(prhs[0])); /* ** Test the second input argument and assign it to seed. */ if (!(mxIsNumeric(prhs[1]) && mxIsClass(prhs[1], "int64"))) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: Second input (seed) has to be an integer [int64]!"); + mexErrMsgTxt("qmc_sequence:: Second input (seed) has to be an integer [int64]!"); int64_T seed = static_cast(mxGetScalar(prhs[1])); /* @@ -83,22 +83,22 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) error_flag_3 = 1; if (error_flag_3 == 1) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: Third input (type of QMC sequence) has to be an integer equal to 0, 1 or 2!"); + mexErrMsgTxt("qmc_sequence:: Third input (type of QMC sequence) has to be an integer equal to 0, 1 or 2!"); /* ** Test dimension ≥ 2 when type==2 */ if (type == 2 && dimension < 2) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: First input (dimension) has to be greater than 1 for a uniform QMC on an hypershere!"); + mexErrMsgTxt("qmc_sequence:: First input (dimension) has to be greater than 1 for a uniform QMC on an hypershere!"); else if (dimension > DIM_MAX) - DYN_MEX_FUNC_ERR_MSG_TXT(("qmc_sequence:: First input (dimension) has to be smaller than " + to_string(DIM_MAX) + " !").c_str()); + mexErrMsgTxt(("qmc_sequence:: First input (dimension) has to be smaller than " + to_string(DIM_MAX) + " !").c_str()); /* ** Test the optional fourth input argument and assign it to sequence_size. */ if (nrhs > 3 && !mxIsNumeric(prhs[3])) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: Fourth input (qmc sequence size) has to be a positive integer!"); + mexErrMsgTxt("qmc_sequence:: Fourth input (qmc sequence size) has to be a positive integer!"); int sequence_size; if (nrhs > 3) @@ -110,17 +110,17 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) ** Test the optional fifth input argument and assign it to lower_and_upper_bounds. */ if (nrhs > 4 && type == 0 && mxGetN(prhs[4]) != 2) // Sequence of uniformly distributed numbers in an hypercube - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: The fifth input argument must be an array with two columns!"); + mexErrMsgTxt("qmc_sequence:: The fifth input argument must be an array with two columns!"); if (nrhs > 4 && type == 0 && static_cast(mxGetM(prhs[4])) != dimension) - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: The fourth input argument must be an array with a number of lines equal to dimension (first input argument)!"); + mexErrMsgTxt("qmc_sequence:: The fourth input argument must be an array with a number of lines equal to dimension (first input argument)!"); if (nrhs > 4 && type == 1 && !(static_cast(mxGetN(prhs[4])) == dimension && static_cast(mxGetM(prhs[4])) == dimension)) // Sequence of normally distributed numbers - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: The fifth input argument must be a squared matrix (whose dimension is given by the first input argument)!"); + mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a squared matrix (whose dimension is given by the first input argument)!"); if (nrhs > 4 && type == 2 && !(mxGetN(prhs[4]) == 1 && mxGetM(prhs[4]) == 1)) // Sequence of uniformly distributed numbers on a hypershere - DYN_MEX_FUNC_ERR_MSG_TXT("qmc_sequence:: The fifth input argument must be a positive scalar!"); + mexErrMsgTxt("qmc_sequence:: The fifth input argument must be a positive scalar!"); const double *lower_bounds = nullptr, *upper_bounds = nullptr; int unit_hypercube_flag = 1; diff --git a/mex/sources/sobol/sobol.hh b/mex/sources/sobol/sobol.hh index 1e80d6be1..a6f29d9f7 100644 --- a/mex/sources/sobol/sobol.hh +++ b/mex/sources/sobol/sobol.hh @@ -251,118 +251,118 @@ next_sobol(int dim_num, T1 *seed, T2 *quasi) T1 l = 0; static T1 poly[DIM_MAX] = { - 1, 3, 7, 11, 13, 19, 25, 37, 59, 47, - 61, 55, 41, 67, 97, 91, 109, 103, 115, 131, - 193, 137, 145, 143, 241, 157, 185, 167, 229, 171, - 213, 191, 253, 203, 211, 239, 247, 285, 369, 299, - 301, 333, 351, 355, 357, 361, 391, 397, 425, 451, - 463, 487, 501, 529, 539, 545, 557, 563, 601, 607, - 617, 623, 631, 637, 647, 661, 675, 677, 687, 695, - 701, 719, 721, 731, 757, 761, 787, 789, 799, 803, - 817, 827, 847, 859, 865, 875, 877, 883, 895, 901, - 911, 949, 953, 967, 971, 973, 981, 985, 995, 1001, - 1019, 1033, 1051, 1063, 1069, 1125, 1135, 1153, 1163, 1221, - 1239, 1255, 1267, 1279, 1293, 1305, 1315, 1329, 1341, 1347, - 1367, 1387, 1413, 1423, 1431, 1441, 1479, 1509, 1527, 1531, - 1555, 1557, 1573, 1591, 1603, 1615, 1627, 1657, 1663, 1673, - 1717, 1729, 1747, 1759, 1789, 1815, 1821, 1825, 1849, 1863, - 1869, 1877, 1881, 1891, 1917, 1933, 1939, 1969, 2011, 2035, - 2041, 2053, 2071, 2091, 2093, 2119, 2147, 2149, 2161, 2171, - 2189, 2197, 2207, 2217, 2225, 2255, 2257, 2273, 2279, 2283, - 2293, 2317, 2323, 2341, 2345, 2363, 2365, 2373, 2377, 2385, - 2395, 2419, 2421, 2431, 2435, 2447, 2475, 2477, 2489, 2503, - 2521, 2533, 2551, 2561, 2567, 2579, 2581, 2601, 2633, 2657, - 2669, 2681, 2687, 2693, 2705, 2717, 2727, 2731, 2739, 2741, - 2773, 2783, 2793, 2799, 2801, 2811, 2819, 2825, 2833, 2867, - 2879, 2881, 2891, 2905, 2911, 2917, 2927, 2941, 2951, 2955, - 2963, 2965, 2991, 2999, 3005, 3017, 3035, 3037, 3047, 3053, - 3083, 3085, 3097, 3103, 3159, 3169, 3179, 3187, 3205, 3209, - 3223, 3227, 3229, 3251, 3263, 3271, 3277, 3283, 3285, 3299, - 3305, 3319, 3331, 3343, 3357, 3367, 3373, 3393, 3399, 3413, - 3417, 3427, 3439, 3441, 3475, 3487, 3497, 3515, 3517, 3529, - 3543, 3547, 3553, 3559, 3573, 3589, 3613, 3617, 3623, 3627, - 3635, 3641, 3655, 3659, 3669, 3679, 3697, 3707, 3709, 3713, - 3731, 3743, 3747, 3771, 3791, 3805, 3827, 3833, 3851, 3865, - 3889, 3895, 3933, 3947, 3949, 3957, 3971, 3985, 3991, 3995, - 4007, 4013, 4021, 4045, 4051, 4069, 4073, 4179, 4201, 4219, - 4221, 4249, 4305, 4331, 4359, 4383, 4387, 4411, 4431, 4439, - 4449, 4459, 4485, 4531, 4569, 4575, 4621, 4663, 4669, 4711, - 4723, 4735, 4793, 4801, 4811, 4879, 4893, 4897, 4921, 4927, - 4941, 4977, 5017, 5027, 5033, 5127, 5169, 5175, 5199, 5213, - 5223, 5237, 5287, 5293, 5331, 5391, 5405, 5453, 5523, 5573, - 5591, 5597, 5611, 5641, 5703, 5717, 5721, 5797, 5821, 5909, - 5913, 5955, 5957, 6005, 6025, 6061, 6067, 6079, 6081, 6231, - 6237, 6289, 6295, 6329, 6383, 6427, 6453, 6465, 6501, 6523, - 6539, 6577, 6589, 6601, 6607, 6631, 6683, 6699, 6707, 6761, - 6795, 6865, 6881, 6901, 6923, 6931, 6943, 6999, 7057, 7079, - 7103, 7105, 7123, 7173, 7185, 7191, 7207, 7245, 7303, 7327, - 7333, 7355, 7365, 7369, 7375, 7411, 7431, 7459, 7491, 7505, - 7515, 7541, 7557, 7561, 7701, 7705, 7727, 7749, 7761, 7783, - 7795, 7823, 7907, 7953, 7963, 7975, 8049, 8089, 8123, 8125, - 8137, 8219, 8231, 8245, 8275, 8293, 8303, 8331, 8333, 8351, - 8357, 8367, 8379, 8381, 8387, 8393, 8417, 8435, 8461, 8469, - 8489, 8495, 8507, 8515, 8551, 8555, 8569, 8585, 8599, 8605, - 8639, 8641, 8647, 8653, 8671, 8675, 8689, 8699, 8729, 8741, - 8759, 8765, 8771, 8795, 8797, 8825, 8831, 8841, 8855, 8859, - 8883, 8895, 8909, 8943, 8951, 8955, 8965, 8999, 9003, 9031, - 9045, 9049, 9071, 9073, 9085, 9095, 9101, 9109, 9123, 9129, - 9137, 9143, 9147, 9185, 9197, 9209, 9227, 9235, 9247, 9253, - 9257, 9277, 9297, 9303, 9313, 9325, 9343, 9347, 9371, 9373, - 9397, 9407, 9409, 9415, 9419, 9443, 9481, 9495, 9501, 9505, - 9517, 9529, 9555, 9557, 9571, 9585, 9591, 9607, 9611, 9621, - 9625, 9631, 9647, 9661, 9669, 9679, 9687, 9707, 9731, 9733, - 9745, 9773, 9791, 9803, 9811, 9817, 9833, 9847, 9851, 9863, - 9875, 9881, 9905, 9911, 9917, 9923, 9963, 9973, 10003, 10025, - 10043, 10063, 10071, 10077, 10091, 10099, 10105, 10115, 10129, 10145, - 10169, 10183, 10187, 10207, 10223, 10225, 10247, 10265, 10271, 10275, - 10289, 10299, 10301, 10309, 10343, 10357, 10373, 10411, 10413, 10431, - 10445, 10453, 10463, 10467, 10473, 10491, 10505, 10511, 10513, 10523, - 10539, 10549, 10559, 10561, 10571, 10581, 10615, 10621, 10625, 10643, - 10655, 10671, 10679, 10685, 10691, 10711, 10739, 10741, 10755, 10767, - 10781, 10785, 10803, 10805, 10829, 10857, 10863, 10865, 10875, 10877, - 10917, 10921, 10929, 10949, 10967, 10971, 10987, 10995, 11009, 11029, - 11043, 11045, 11055, 11063, 11075, 11081, 11117, 11135, 11141, 11159, - 11163, 11181, 11187, 11225, 11237, 11261, 11279, 11297, 11307, 11309, - 11327, 11329, 11341, 11377, 11403, 11405, 11413, 11427, 11439, 11453, - 11461, 11473, 11479, 11489, 11495, 11499, 11533, 11545, 11561, 11567, - 11575, 11579, 11589, 11611, 11623, 11637, 11657, 11663, 11687, 11691, - 11701, 11747, 11761, 11773, 11783, 11795, 11797, 11817, 11849, 11855, - 11867, 11869, 11873, 11883, 11919, 11921, 11927, 11933, 11947, 11955, - 11961, 11999, 12027, 12029, 12037, 12041, 12049, 12055, 12095, 12097, - 12107, 12109, 12121, 12127, 12133, 12137, 12181, 12197, 12207, 12209, - 12239, 12253, 12263, 12269, 12277, 12287, 12295, 12309, 12313, 12335, - 12361, 12367, 12391, 12409, 12415, 12433, 12449, 12469, 12479, 12481, - 12499, 12505, 12517, 12527, 12549, 12559, 12597, 12615, 12621, 12639, - 12643, 12657, 12667, 12707, 12713, 12727, 12741, 12745, 12763, 12769, - 12779, 12781, 12787, 12799, 12809, 12815, 12829, 12839, 12857, 12875, - 12883, 12889, 12901, 12929, 12947, 12953, 12959, 12969, 12983, 12987, - 12995, 13015, 13019, 13031, 13063, 13077, 13103, 13137, 13149, 13173, - 13207, 13211, 13227, 13241, 13249, 13255, 13269, 13283, 13285, 13303, - 13307, 13321, 13339, 13351, 13377, 13389, 13407, 13417, 13431, 13435, - 13447, 13459, 13465, 13477, 13501, 13513, 13531, 13543, 13561, 13581, - 13599, 13605, 13617, 13623, 13637, 13647, 13661, 13677, 13683, 13695, - 13725, 13729, 13753, 13773, 13781, 13785, 13795, 13801, 13807, 13825, - 13835, 13855, 13861, 13871, 13883, 13897, 13905, 13915, 13939, 13941, - 13969, 13979, 13981, 13997, 14027, 14035, 14037, 14051, 14063, 14085, - 14095, 14107, 14113, 14125, 14137, 14145, 14151, 14163, 14193, 14199, - 14219, 14229, 14233, 14243, 14277, 14287, 14289, 14295, 14301, 14305, - 14323, 14339, 14341, 14359, 14365, 14375, 14387, 14411, 14425, 14441, - 14449, 14499, 14513, 14523, 14537, 14543, 14561, 14579, 14585, 14593, - 14599, 14603, 14611, 14641, 14671, 14695, 14701, 14723, 14725, 14743, - 14753, 14759, 14765, 14795, 14797, 14803, 14831, 14839, 14845, 14855, - 14889, 14895, 14909, 14929, 14941, 14945, 14951, 14963, 14965, 14985, - 15033, 15039, 15053, 15059, 15061, 15071, 15077, 15081, 15099, 15121, - 15147, 15149, 15157, 15167, 15187, 15193, 15203, 15205, 15215, 15217, - 15223, 15243, 15257, 15269, 15273, 15287, 15291, 15313, 15335, 15347, - 15359, 15373, 15379, 15381, 15391, 15395, 15397, 15419, 15439, 15453, - 15469, 15491, 15503, 15517, 15527, 15531, 15545, 15559, 15593, 15611, - 15613, 15619, 15639, 15643, 15649, 15661, 15667, 15669, 15681, 15693, - 15717, 15721, 15741, 15745, 15765, 15793, 15799, 15811, 15825, 15835, - 15847, 15851, 15865, 15877, 15881, 15887, 15899, 15915, 15935, 15937, - 15955, 15973, 15977, 16011, 16035, 16061, 16069, 16087, 16093, 16097, - 16121, 16141, 16153, 16159, 16165, 16183, 16189, 16195, 16197, 16201, - 16209, 16215, 16225, 16259, 16265, 16273, 16299, 16309, 16355, 16375, - 16381 + 1, 3, 7, 11, 13, 19, 25, 37, 59, 47, + 61, 55, 41, 67, 97, 91, 109, 103, 115, 131, + 193, 137, 145, 143, 241, 157, 185, 167, 229, 171, + 213, 191, 253, 203, 211, 239, 247, 285, 369, 299, + 301, 333, 351, 355, 357, 361, 391, 397, 425, 451, + 463, 487, 501, 529, 539, 545, 557, 563, 601, 607, + 617, 623, 631, 637, 647, 661, 675, 677, 687, 695, + 701, 719, 721, 731, 757, 761, 787, 789, 799, 803, + 817, 827, 847, 859, 865, 875, 877, 883, 895, 901, + 911, 949, 953, 967, 971, 973, 981, 985, 995, 1001, + 1019, 1033, 1051, 1063, 1069, 1125, 1135, 1153, 1163, 1221, + 1239, 1255, 1267, 1279, 1293, 1305, 1315, 1329, 1341, 1347, + 1367, 1387, 1413, 1423, 1431, 1441, 1479, 1509, 1527, 1531, + 1555, 1557, 1573, 1591, 1603, 1615, 1627, 1657, 1663, 1673, + 1717, 1729, 1747, 1759, 1789, 1815, 1821, 1825, 1849, 1863, + 1869, 1877, 1881, 1891, 1917, 1933, 1939, 1969, 2011, 2035, + 2041, 2053, 2071, 2091, 2093, 2119, 2147, 2149, 2161, 2171, + 2189, 2197, 2207, 2217, 2225, 2255, 2257, 2273, 2279, 2283, + 2293, 2317, 2323, 2341, 2345, 2363, 2365, 2373, 2377, 2385, + 2395, 2419, 2421, 2431, 2435, 2447, 2475, 2477, 2489, 2503, + 2521, 2533, 2551, 2561, 2567, 2579, 2581, 2601, 2633, 2657, + 2669, 2681, 2687, 2693, 2705, 2717, 2727, 2731, 2739, 2741, + 2773, 2783, 2793, 2799, 2801, 2811, 2819, 2825, 2833, 2867, + 2879, 2881, 2891, 2905, 2911, 2917, 2927, 2941, 2951, 2955, + 2963, 2965, 2991, 2999, 3005, 3017, 3035, 3037, 3047, 3053, + 3083, 3085, 3097, 3103, 3159, 3169, 3179, 3187, 3205, 3209, + 3223, 3227, 3229, 3251, 3263, 3271, 3277, 3283, 3285, 3299, + 3305, 3319, 3331, 3343, 3357, 3367, 3373, 3393, 3399, 3413, + 3417, 3427, 3439, 3441, 3475, 3487, 3497, 3515, 3517, 3529, + 3543, 3547, 3553, 3559, 3573, 3589, 3613, 3617, 3623, 3627, + 3635, 3641, 3655, 3659, 3669, 3679, 3697, 3707, 3709, 3713, + 3731, 3743, 3747, 3771, 3791, 3805, 3827, 3833, 3851, 3865, + 3889, 3895, 3933, 3947, 3949, 3957, 3971, 3985, 3991, 3995, + 4007, 4013, 4021, 4045, 4051, 4069, 4073, 4179, 4201, 4219, + 4221, 4249, 4305, 4331, 4359, 4383, 4387, 4411, 4431, 4439, + 4449, 4459, 4485, 4531, 4569, 4575, 4621, 4663, 4669, 4711, + 4723, 4735, 4793, 4801, 4811, 4879, 4893, 4897, 4921, 4927, + 4941, 4977, 5017, 5027, 5033, 5127, 5169, 5175, 5199, 5213, + 5223, 5237, 5287, 5293, 5331, 5391, 5405, 5453, 5523, 5573, + 5591, 5597, 5611, 5641, 5703, 5717, 5721, 5797, 5821, 5909, + 5913, 5955, 5957, 6005, 6025, 6061, 6067, 6079, 6081, 6231, + 6237, 6289, 6295, 6329, 6383, 6427, 6453, 6465, 6501, 6523, + 6539, 6577, 6589, 6601, 6607, 6631, 6683, 6699, 6707, 6761, + 6795, 6865, 6881, 6901, 6923, 6931, 6943, 6999, 7057, 7079, + 7103, 7105, 7123, 7173, 7185, 7191, 7207, 7245, 7303, 7327, + 7333, 7355, 7365, 7369, 7375, 7411, 7431, 7459, 7491, 7505, + 7515, 7541, 7557, 7561, 7701, 7705, 7727, 7749, 7761, 7783, + 7795, 7823, 7907, 7953, 7963, 7975, 8049, 8089, 8123, 8125, + 8137, 8219, 8231, 8245, 8275, 8293, 8303, 8331, 8333, 8351, + 8357, 8367, 8379, 8381, 8387, 8393, 8417, 8435, 8461, 8469, + 8489, 8495, 8507, 8515, 8551, 8555, 8569, 8585, 8599, 8605, + 8639, 8641, 8647, 8653, 8671, 8675, 8689, 8699, 8729, 8741, + 8759, 8765, 8771, 8795, 8797, 8825, 8831, 8841, 8855, 8859, + 8883, 8895, 8909, 8943, 8951, 8955, 8965, 8999, 9003, 9031, + 9045, 9049, 9071, 9073, 9085, 9095, 9101, 9109, 9123, 9129, + 9137, 9143, 9147, 9185, 9197, 9209, 9227, 9235, 9247, 9253, + 9257, 9277, 9297, 9303, 9313, 9325, 9343, 9347, 9371, 9373, + 9397, 9407, 9409, 9415, 9419, 9443, 9481, 9495, 9501, 9505, + 9517, 9529, 9555, 9557, 9571, 9585, 9591, 9607, 9611, 9621, + 9625, 9631, 9647, 9661, 9669, 9679, 9687, 9707, 9731, 9733, + 9745, 9773, 9791, 9803, 9811, 9817, 9833, 9847, 9851, 9863, + 9875, 9881, 9905, 9911, 9917, 9923, 9963, 9973, 10003, 10025, + 10043, 10063, 10071, 10077, 10091, 10099, 10105, 10115, 10129, 10145, + 10169, 10183, 10187, 10207, 10223, 10225, 10247, 10265, 10271, 10275, + 10289, 10299, 10301, 10309, 10343, 10357, 10373, 10411, 10413, 10431, + 10445, 10453, 10463, 10467, 10473, 10491, 10505, 10511, 10513, 10523, + 10539, 10549, 10559, 10561, 10571, 10581, 10615, 10621, 10625, 10643, + 10655, 10671, 10679, 10685, 10691, 10711, 10739, 10741, 10755, 10767, + 10781, 10785, 10803, 10805, 10829, 10857, 10863, 10865, 10875, 10877, + 10917, 10921, 10929, 10949, 10967, 10971, 10987, 10995, 11009, 11029, + 11043, 11045, 11055, 11063, 11075, 11081, 11117, 11135, 11141, 11159, + 11163, 11181, 11187, 11225, 11237, 11261, 11279, 11297, 11307, 11309, + 11327, 11329, 11341, 11377, 11403, 11405, 11413, 11427, 11439, 11453, + 11461, 11473, 11479, 11489, 11495, 11499, 11533, 11545, 11561, 11567, + 11575, 11579, 11589, 11611, 11623, 11637, 11657, 11663, 11687, 11691, + 11701, 11747, 11761, 11773, 11783, 11795, 11797, 11817, 11849, 11855, + 11867, 11869, 11873, 11883, 11919, 11921, 11927, 11933, 11947, 11955, + 11961, 11999, 12027, 12029, 12037, 12041, 12049, 12055, 12095, 12097, + 12107, 12109, 12121, 12127, 12133, 12137, 12181, 12197, 12207, 12209, + 12239, 12253, 12263, 12269, 12277, 12287, 12295, 12309, 12313, 12335, + 12361, 12367, 12391, 12409, 12415, 12433, 12449, 12469, 12479, 12481, + 12499, 12505, 12517, 12527, 12549, 12559, 12597, 12615, 12621, 12639, + 12643, 12657, 12667, 12707, 12713, 12727, 12741, 12745, 12763, 12769, + 12779, 12781, 12787, 12799, 12809, 12815, 12829, 12839, 12857, 12875, + 12883, 12889, 12901, 12929, 12947, 12953, 12959, 12969, 12983, 12987, + 12995, 13015, 13019, 13031, 13063, 13077, 13103, 13137, 13149, 13173, + 13207, 13211, 13227, 13241, 13249, 13255, 13269, 13283, 13285, 13303, + 13307, 13321, 13339, 13351, 13377, 13389, 13407, 13417, 13431, 13435, + 13447, 13459, 13465, 13477, 13501, 13513, 13531, 13543, 13561, 13581, + 13599, 13605, 13617, 13623, 13637, 13647, 13661, 13677, 13683, 13695, + 13725, 13729, 13753, 13773, 13781, 13785, 13795, 13801, 13807, 13825, + 13835, 13855, 13861, 13871, 13883, 13897, 13905, 13915, 13939, 13941, + 13969, 13979, 13981, 13997, 14027, 14035, 14037, 14051, 14063, 14085, + 14095, 14107, 14113, 14125, 14137, 14145, 14151, 14163, 14193, 14199, + 14219, 14229, 14233, 14243, 14277, 14287, 14289, 14295, 14301, 14305, + 14323, 14339, 14341, 14359, 14365, 14375, 14387, 14411, 14425, 14441, + 14449, 14499, 14513, 14523, 14537, 14543, 14561, 14579, 14585, 14593, + 14599, 14603, 14611, 14641, 14671, 14695, 14701, 14723, 14725, 14743, + 14753, 14759, 14765, 14795, 14797, 14803, 14831, 14839, 14845, 14855, + 14889, 14895, 14909, 14929, 14941, 14945, 14951, 14963, 14965, 14985, + 15033, 15039, 15053, 15059, 15061, 15071, 15077, 15081, 15099, 15121, + 15147, 15149, 15157, 15167, 15187, 15193, 15203, 15205, 15215, 15217, + 15223, 15243, 15257, 15269, 15273, 15287, 15291, 15313, 15335, 15347, + 15359, 15373, 15379, 15381, 15391, 15395, 15397, 15419, 15439, 15453, + 15469, 15491, 15503, 15517, 15527, 15531, 15545, 15559, 15593, 15611, + 15613, 15619, 15639, 15643, 15649, 15661, 15667, 15669, 15681, 15693, + 15717, 15721, 15741, 15745, 15765, 15793, 15799, 15811, 15825, 15835, + 15847, 15851, 15865, 15877, 15881, 15887, 15899, 15915, 15935, 15937, + 15955, 15973, 15977, 16011, 16035, 16061, 16069, 16087, 16093, 16097, + 16121, 16141, 16153, 16159, 16165, 16183, 16189, 16195, 16197, 16201, + 16209, 16215, 16225, 16259, 16265, 16273, 16299, 16309, 16355, 16375, + 16381 }; static T2 recipd; static T1 seed_save = -1; diff --git a/preprocessor b/preprocessor index 126020f75..50776a766 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit 126020f7522fa656ac02e7a9a616f9c84acecd50 +Subproject commit 50776a766afb2f323e601916f33d2466dd40c761 diff --git a/scripts/dynare.el b/scripts/dynare.el index 9a505c6f1..9b04dc7e2 100644 --- a/scripts/dynare.el +++ b/scripts/dynare.el @@ -64,10 +64,12 @@ "write_latex_steady_state_model" "steady" "check" "simul" "stoch_simul" "var_model" "trend_component_model" "var_expectation_model" "pac_model" "dsample" "Sigma_e" "planner_objective" "ramsey_model" "ramsey_policy" + "evaluate_planner_objective" "discretionary_policy" "identification" "bvar_density" "bvar_forecast" "dynare_sensitivity" "initval_file" "histval_file" "forecast" "shock_decomposition" "realtime_shock_decomposition" - "plot_shock_decomposition" "initial_condition_decomposition" "sbvar" + "plot_shock_decomposition" "initial_condition_decomposition" + "squeeze_shock_decomposition" "sbvar" "ms_estimation" "ms_simulation" "ms_compute_mdd" "ms_compute_probabilities" "ms_forecast" "ms_irf" "ms_variance_decomposition" "conditional_forecast" "plot_conditional_forecast" "gmm_estimation" "smm_estimation" @@ -86,15 +88,18 @@ ;; Those keywords that makes the lexer enter the DYNARE_BLOCK start condition ;; Also include "verbatim" in this list -(defvar dynare-blocks - '("model" "steady_state_model" "initval" "endval" "histval" "shocks" - "shock_groups" "init2shocks" "mshocks" "estimated_params" "epilogue" "priors" - "estimated_param_init" "estimated_params_bounds" "osr_params_bounds" - "observation_trends" "optim_weights" "homotopy_setup" - "conditional_forecast_paths" "svar_identification" "moment_calibration" - "irf_calibration" "ramsey_constraints" "restrictions" "generate_irfs" - "verbatim") - "Dynare block keywords.") +;; Needs to be enclosed within eval-when-compile, because this variable is +;; referenced in another eval-when-compile statement in dynare-calculate-indentation +(eval-when-compile + (defvar dynare-blocks + '("model" "steady_state_model" "initval" "endval" "histval" "shocks" + "shock_groups" "init2shocks" "mshocks" "estimated_params" "epilogue" "priors" + "estimated_params_init" "estimated_params_bounds" "osr_params_bounds" + "observation_trends" "optim_weights" "homotopy_setup" + "conditional_forecast_paths" "svar_identification" "moment_calibration" + "irf_calibration" "ramsey_constraints" "restrictions" "generate_irfs" + "verbatim") + "Dynare block keywords.")) ;; Mathematical functions and operators used in model equations (see "hand_side" in Bison file) (defvar dynare-functions @@ -227,3 +232,6 @@ (add-to-list 'auto-mode-alist '("\\.mod$" . dynare-mode)) (provide 'dynare) + +;; The following line is for ELPA compatibility (in particular needed for Debian) +;;; dynare.el ends here diff --git a/scripts/indent-c++ b/scripts/indent-c++ index db299d518..5da21f39a 100755 --- a/scripts/indent-c++ +++ b/scripts/indent-c++ @@ -1,15 +1,21 @@ -#!/bin/sh +#!/bin/bash -# Reindents the C++ source code file given in argument. +# Reindents the C++ source code files given in argument -if [ -z "$1" ]; then - echo "Give a filename in argument" - exit 1 -fi +[[ -n $1 ]] || { echo "Give filename(s) in argument" 2>&1; exit 1; } -SCRIPTS_DIR=$(pwd)/$(dirname $0) +pushd "$(dirname "$0")" > /dev/null +SCRIPTS_DIR=$(pwd) +popd > /dev/null -uncrustify -l CPP --replace -c ${SCRIPTS_DIR}/uncrustify.cfg $1 +for f in "$@"; do + echo "*** Indenting $f…" -cd $(dirname $1) -emacs -batch $(basename $1) -l ${SCRIPTS_DIR}/indent-c++.el + uncrustify -l CPP --replace -c "${SCRIPTS_DIR}"/uncrustify.cfg "$f" + + pushd "$(dirname "$f")" > /dev/null + emacs -batch "$(basename "$f")" -l "${SCRIPTS_DIR}"/indent-c++.el + popd > /dev/null + + echo +done diff --git a/scripts/indent-matlab b/scripts/indent-matlab index 77772bd9a..908e0f075 100755 --- a/scripts/indent-matlab +++ b/scripts/indent-matlab @@ -1,13 +1,19 @@ -#!/bin/sh +#!/bin/bash -# Reindents the MATLAB source code file given in argument. +# Reindents the MATLAB source code files given in argument -if [ -z "$1" ]; then - echo "Give a filename in argument" - exit 1 -fi +[[ -n $1 ]] || { echo "Give filename(s) in argument" 2>&1; exit 1; } -SCRIPTS_DIR=$(pwd)/$(dirname $0) +pushd "$(dirname "$0")" > /dev/null +SCRIPTS_DIR=$(pwd) +popd > /dev/null -cd $(dirname $1) -emacs -batch $(basename $1) -l ${SCRIPTS_DIR}/indent-matlab.el +for f in "$@"; do + echo "*** Indenting $f…" + + pushd "$(dirname "$f")" > /dev/null + emacs -batch "$(basename "$f")" -l "${SCRIPTS_DIR}"/indent-matlab.el + popd > /dev/null + + echo +done diff --git a/scripts/uncrustify.cfg b/scripts/uncrustify.cfg index 1dd820aea..395548d2b 100644 --- a/scripts/uncrustify.cfg +++ b/scripts/uncrustify.cfg @@ -1,1277 +1,1538 @@ -# Uncrustify 0.64 +# Uncrustify-0.68_f # # General options # -# The type of line endings. Default=Auto -newlines = lf # auto/lf/crlf/cr +# The type of line endings. +# +# Default: auto +newlines = lf # lf/crlf/cr/auto -# The original size of tabs in the input. Default=8 -input_tab_size = 8 # number +# The original size of tabs in the input. +# +# Default: 8 +input_tab_size = 8 # unsigned number -# The size of tabs in the output (only used if align_with_tabs=true). Default=8 -output_tab_size = 8 # number +# The size of tabs in the output (only used if align_with_tabs=true). +# +# Default: 8 +output_tab_size = 8 # unsigned number -# The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) -string_escape_char = 92 # number +# The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^). +# +# Default: 92 +string_escape_char = 92 # unsigned number -# Alternate string escape char for Pawn. Only works right before the quote char. -string_escape_char2 = 0 # number +# Alternate string escape char (usually only used for Pawn). +# Only works right before the quote char. +string_escape_char2 = 0 # unsigned number -# Replace tab characters found in string literals with the escape sequence \t instead. -string_replace_tab_chars = false # false/true +# Replace tab characters found in string literals with the escape sequence \t +# instead. +string_replace_tab_chars = false # true/false -# Allow interpreting '>=' and '>>=' as part of a template in 'void f(list>=val);'. -# If true, 'assert(x<0 && y>=3)' will be broken. Default=False +# Allow interpreting '>=' and '>>=' as part of a template in code like +# 'void f(list>=val);'. If true, 'assert(x<0 && y>=3)' will be broken. # Improvements to template detection may make this option obsolete. -tok_split_gte = false # false/true +tok_split_gte = false # true/false -# Override the default ' *INDENT-OFF*' in comments for disabling processing of part of the file. -disable_processing_cmt = "" # string +# Specify the marker used in comments to disable processing of part of the +# file. +# +# Default: *INDENT-OFF* +disable_processing_cmt = " *INDENT-OFF*" # string -# Override the default ' *INDENT-ON*' in comments for enabling processing of part of the file. -enable_processing_cmt = "" # string +# Specify the marker used in comments to (re)enable processing in a file. +# +# Default: *INDENT-ON* +enable_processing_cmt = " *INDENT-ON*" # string -# Enable parsing of digraphs. Default=False -enable_digraphs = false # false/true +# Enable parsing of digraphs. +enable_digraphs = false # true/false -# Control what to do with the UTF-8 BOM (recommend 'remove') +# Add or remove the UTF-8 BOM (recommend 'remove'). utf8_bom = ignore # ignore/add/remove/force -# If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8 -utf8_byte = false # false/true +# If the file contains bytes with values between 128 and 255, but is not +# UTF-8, then output as UTF-8. +utf8_byte = false # true/false -# Force the output encoding to UTF-8 -utf8_force = false # false/true - -# -# Indenting -# - -# The number of columns to indent per level. -# Usually 2, 3, 4, or 8. Default=8 -indent_columns = 2 # number - -# The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. -# For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level -indent_continue = 0 # number - -# How to use tabs when indenting code -# 0=spaces only -# 1=indent with tabs to brace level, align with spaces (default) -# 2=indent and align with tabs, using spaces when not on a tabstop -indent_with_tabs = 0 # number - -# Comments that are not a brace level are indented with tabs on a tabstop. -# Requires indent_with_tabs=2. If false, will use spaces. -indent_cmt_with_tabs = false # false/true - -# Whether to indent strings broken by '\' so that they line up -indent_align_string = false # false/true - -# The number of spaces to indent multi-line XML strings. -# Requires indent_align_string=True -indent_xml_string = 0 # number - -# Spaces to indent '{' from level -indent_brace = 2 # number - -# Whether braces are indented to the body level -indent_braces = false # false/true - -# Disabled indenting function braces if indent_braces is true -indent_braces_no_func = false # false/true - -# Disabled indenting class braces if indent_braces is true -indent_braces_no_class = false # false/true - -# Disabled indenting struct braces if indent_braces is true -indent_braces_no_struct = false # false/true - -# Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. -indent_brace_parent = false # false/true - -# Indent based on the paren open instead of the brace open in '({\n', default is to indent by brace. -indent_paren_open_brace = false # false/true - -# indent a C# delegate by another level, default is to not indent by another level. -indent_cs_delegate_brace = false # false/true - -# Whether the 'namespace' body is indented -indent_namespace = true # false/true - -# Only indent one namespace and no sub-namespaces. -# Requires indent_namespace=true. -indent_namespace_single_indent = false # false/true - -# The number of spaces to indent a namespace block -indent_namespace_level = 0 # number - -# If the body of the namespace is longer than this number, it won't be indented. -# Requires indent_namespace=true. Default=0 (no limit) -indent_namespace_limit = 0 # number - -# Whether the 'extern "C"' body is indented -indent_extern = true # false/true - -# Whether the 'class' body is indented -indent_class = true # false/true - -# Whether to indent the stuff after a leading base class colon -indent_class_colon = false # false/true - -# Indent based on a class colon instead of the stuff after the colon. -# Requires indent_class_colon=true. Default=False -indent_class_on_colon = false # false/true - -# Whether to indent the stuff after a leading class initializer colon -indent_constr_colon = false # false/true - -# Virtual indent from the ':' for member initializers. Default=2 -indent_ctor_init_leading = 2 # number - -# Additional indenting for constructor initializer list -indent_ctor_init = 0 # number - -# False=treat 'else\nif' as 'else if' for indenting purposes -# True=indent the 'if' one level -indent_else_if = false # false/true - -# Amount to indent variable declarations after a open brace. neg=relative, pos=absolute -indent_var_def_blk = 0 # number - -# Indent continued variable declarations instead of aligning. -indent_var_def_cont = false # false/true - -# Indent continued shift expressions ('<<' and '>>') instead of aligning. -# Turn align_left_shift off when enabling this. -indent_shift = false # false/true - -# True: force indentation of function definition to start in column 1 -# False: use the default behavior -indent_func_def_force_col1 = false # false/true - -# True: indent continued function call parameters one indent level -# False: align parameters under the open paren -indent_func_call_param = false # false/true - -# Same as indent_func_call_param, but for function defs -indent_func_def_param = false # false/true - -# Same as indent_func_call_param, but for function protos -indent_func_proto_param = false # false/true - -# Same as indent_func_call_param, but for class declarations -indent_func_class_param = false # false/true - -# Same as indent_func_call_param, but for class variable constructors -indent_func_ctor_var_param = false # false/true - -# Same as indent_func_call_param, but for templates -indent_template_param = false # false/true - -# Double the indent for indent_func_xxx_param options -indent_func_param_double = false # false/true - -# Indentation column for standalone 'const' function decl/proto qualifier -indent_func_const = 0 # number - -# Indentation column for standalone 'throw' function decl/proto qualifier -indent_func_throw = 0 # number - -# The number of spaces to indent a continued '->' or '.' -# Usually set to 0, 1, or indent_columns. -indent_member = 0 # number - -# Spaces to indent single line ('//') comments on lines before code -indent_sing_line_comments = 0 # number - -# If set, will indent trailing single line ('//') comments relative -# to the code instead of trying to keep the same absolute column -indent_relative_single_line_comments = true # false/true - -# Spaces to indent 'case' from 'switch' -# Usually 0 or indent_columns. -indent_switch_case = 0 # number - -# Spaces to shift the 'case' line, without affecting any other lines -# Usually 0. -indent_case_shift = 0 # number - -# Spaces to indent '{' from 'case'. -# By default, the brace will appear under the 'c' in case. -# Usually set to 0 or indent_columns. -indent_case_brace = 0 # number - -# Whether to indent comments found in first column -indent_col1_comment = false # false/true - -# How to indent goto labels -# >0: absolute column where 1 is the leftmost column -# <=0: subtract from brace indent -# Default=1 -indent_label = -2 # number - -# Same as indent_label, but for access specifiers that are followed by a colon. Default=1 -indent_access_spec = -2 # number - -# Indent the code after an access specifier by one level. -# If set, this option forces 'indent_access_spec=0' -indent_access_spec_body = false # false/true - -# If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) -indent_paren_nl = false # false/true - -# Controls the indent of a close paren after a newline. -# 0: Indent to body level -# 1: Align under the open paren -# 2: Indent to the brace level -indent_paren_close = 0 # number - -# Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren -indent_comma_paren = false # false/true - -# Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren -indent_bool_paren = false # false/true - -# If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones -indent_first_bool_expr = false # false/true - -# If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) -indent_square_nl = false # false/true - -# Don't change the relative indent of ESQL/C 'EXEC SQL' bodies -indent_preserve_sql = false # false/true - -# Align continued statements at the '='. Default=True -# If FALSE or the '=' is followed by a newline, the next line is indent one tab. -indent_align_assign = true # false/true - -# Indent OC blocks at brace level instead of usual rules. -indent_oc_block = false # false/true - -# Indent OC blocks in a message relative to the parameter name. -# 0=use indent_oc_block rules, 1+=spaces to indent -indent_oc_block_msg = 0 # number - -# Minimum indent for subsequent parameters -indent_oc_msg_colon = 0 # number - -# If true, prioritize aligning with initial colon (and stripping spaces from lines, if necessary). -# Default=True. -indent_oc_msg_prioritize_first_colon = true # false/true - -# If indent_oc_block_msg and this option are on, blocks will be indented the way that Xcode does by default (from keyword if the parameter is on its own line; otherwise, from the previous indentation level). -indent_oc_block_msg_xcode_style = false # false/true - -# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg keyword. -indent_oc_block_msg_from_keyword = false # false/true - -# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg colon. -indent_oc_block_msg_from_colon = false # false/true - -# If indent_oc_block_msg and this option are on, blocks will be indented from where the block caret is. -indent_oc_block_msg_from_caret = false # false/true - -# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is. -indent_oc_block_msg_from_brace = false # false/true - -# When identing after virtual brace open and newline add further spaces to reach this min. indent. -indent_min_vbrace_open = 0 # number - -# TRUE: When identing after virtual brace open and newline add further spaces after regular indent to reach next tabstop. -indent_vbrace_open_on_tabstop = false # false/true - -# If true, a brace followed by another token (not a newline) will indent all contained lines to match the token.Default=True. -indent_token_after_brace = true # false/true - -# If true, cpp lambda body will be indentedDefault=False. -indent_cpp_lambda_body = false # false/true +# Force the output encoding to UTF-8. +utf8_force = true # true/false # # Spacing options # -# Add or remove space around arithmetic operator '+', '-', '/', '*', etc -# also '>>>' '<<' '>>' '%' '|' +# Add or remove space around non-assignment symbolic operators ('+', '/', '%', +# '<<', and so forth). sp_arith = ignore # ignore/add/remove/force -# Add or remove space around assignment operator '=', '+=', etc -sp_assign = add # ignore/add/remove/force +# Add or remove space around arithmetic operators '+' and '-'. +# +# Overrides sp_arith. +sp_arith_additive = ignore # ignore/add/remove/force -# Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign -sp_cpp_lambda_assign = ignore # ignore/add/remove/force +# Add or remove space around assignment operator '=', '+=', etc. +sp_assign = force # ignore/add/remove/force + +# Add or remove space around '=' in C++11 lambda capture specifications. +# +# Overrides sp_assign. +sp_cpp_lambda_assign = remove # ignore/add/remove/force # Add or remove space after the capture specification in C++11 lambda. -sp_cpp_lambda_paren = ignore # ignore/add/remove/force +sp_cpp_lambda_paren = remove # ignore/add/remove/force -# Add or remove space around assignment operator '=' in a prototype -sp_assign_default = ignore # ignore/add/remove/force +# Add or remove space around assignment operator '=' in a prototype. +sp_assign_default = force # ignore/add/remove/force -# Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. +# Add or remove space before assignment operator '=', '+=', etc. +# +# Overrides sp_assign. sp_before_assign = ignore # ignore/add/remove/force -# Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. +# Add or remove space after assignment operator '=', '+=', etc. +# +# Overrides sp_assign. sp_after_assign = ignore # ignore/add/remove/force -# Add or remove space in 'NS_ENUM (' +# Add or remove space in 'NS_ENUM ('. sp_enum_paren = ignore # ignore/add/remove/force -# Add or remove space around assignment '=' in enum -sp_enum_assign = add # ignore/add/remove/force +# Add or remove space around assignment '=' in enum. +sp_enum_assign = force # ignore/add/remove/force -# Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. +# Add or remove space before assignment '=' in enum. +# +# Overrides sp_enum_assign. sp_enum_before_assign = ignore # ignore/add/remove/force -# Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. +# Add or remove space after assignment '=' in enum. +# +# Overrides sp_enum_assign. sp_enum_after_assign = ignore # ignore/add/remove/force -# Add or remove space around preprocessor '##' concatenation operator. Default=Add -sp_pp_concat = add # ignore/add/remove/force +# Add or remove space around assignment ':' in enum. +sp_enum_colon = ignore # ignore/add/remove/force -# Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator. +# Add or remove space around preprocessor '##' concatenation operator. +# +# Default: add +sp_pp_concat = force # ignore/add/remove/force + +# Add or remove space after preprocessor '#' stringify operator. +# Also affects the '#@' charizing operator. sp_pp_stringify = ignore # ignore/add/remove/force -# Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'. +# Add or remove space before preprocessor '#' stringify operator +# as in '#define x(y) L#y'. sp_before_pp_stringify = ignore # ignore/add/remove/force -# Add or remove space around boolean operators '&&' and '||' -sp_bool = add # ignore/add/remove/force +# Add or remove space around boolean operators '&&' and '||'. +sp_bool = force # ignore/add/remove/force -# Add or remove space around compare operator '<', '>', '==', etc -sp_compare = add # ignore/add/remove/force +# Add or remove space around compare operator '<', '>', '==', etc. +sp_compare = force # ignore/add/remove/force -# Add or remove space inside '(' and ')' +# Add or remove space inside '(' and ')'. sp_inside_paren = remove # ignore/add/remove/force -# Add or remove space between nested parens: '((' vs ') )' +# Add or remove space between nested parentheses, i.e. '((' vs. ') )'. sp_paren_paren = remove # ignore/add/remove/force -# Add or remove space between back-to-back parens: ')(' vs ') (' +# Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. sp_cparen_oparen = ignore # ignore/add/remove/force -# Whether to balance spaces inside nested parens -sp_balance_nested_parens = false # false/true +# Whether to balance spaces inside nested parentheses. +sp_balance_nested_parens = false # true/false -# Add or remove space between ')' and '{' +# Add or remove space between ')' and '{'. sp_paren_brace = ignore # ignore/add/remove/force -# Add or remove space before pointer star '*' -sp_before_ptr_star = add # ignore/add/remove/force +# Add or remove space between nested braces, i.e. '{{' vs '{ {'. +sp_brace_brace = ignore # ignore/add/remove/force -# Add or remove space before pointer star '*' that isn't followed by a variable name -# If set to 'ignore', sp_before_ptr_star is used instead. -sp_before_unnamed_ptr_star = add # ignore/add/remove/force +# Add or remove space before pointer star '*'. +sp_before_ptr_star = force # ignore/add/remove/force -# Add or remove space between pointer stars '*' +# Add or remove space before pointer star '*' that isn't followed by a +# variable name. If set to 'ignore', sp_before_ptr_star is used instead. +sp_before_unnamed_ptr_star = force # ignore/add/remove/force + +# Add or remove space between pointer stars '*'. sp_between_ptr_star = remove # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. sp_after_ptr_star = remove # ignore/add/remove/force +# Add or remove space after pointer caret '^', if followed by a word. +sp_after_ptr_block_caret = ignore # ignore/add/remove/force + # Add or remove space after pointer star '*', if followed by a qualifier. sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force -# Add or remove space after a pointer star '*', if followed by a func proto/def. +# Add or remove space after a pointer star '*', if followed by a function +# prototype or function definition. sp_after_ptr_star_func = remove # ignore/add/remove/force -# Add or remove space after a pointer star '*', if followed by an open paren (function types). +# Add or remove space after a pointer star '*', if followed by an open +# parenthesis, as in 'void* (*)(). sp_ptr_star_paren = ignore # ignore/add/remove/force -# Add or remove space before a pointer star '*', if followed by a func proto/def. -sp_before_ptr_star_func = add # ignore/add/remove/force +# Add or remove space before a pointer star '*', if followed by a function +# prototype or function definition. +sp_before_ptr_star_func = force # ignore/add/remove/force -# Add or remove space before a reference sign '&' -sp_before_byref = add # ignore/add/remove/force +# Add or remove space before a reference sign '&'. +sp_before_byref = force # ignore/add/remove/force -# Add or remove space before a reference sign '&' that isn't followed by a variable name -# If set to 'ignore', sp_before_byref is used instead. -sp_before_unnamed_byref = add # ignore/add/remove/force +# Add or remove space before a reference sign '&' that isn't followed by a +# variable name. If set to 'ignore', sp_before_byref is used instead. +sp_before_unnamed_byref = force # ignore/add/remove/force # Add or remove space after reference sign '&', if followed by a word. sp_after_byref = remove # ignore/add/remove/force -# Add or remove space after a reference sign '&', if followed by a func proto/def. +# Add or remove space after a reference sign '&', if followed by a function +# prototype or function definition. sp_after_byref_func = remove # ignore/add/remove/force -# Add or remove space before a reference sign '&', if followed by a func proto/def. -sp_before_byref_func = remove # ignore/add/remove/force +# Add or remove space before a reference sign '&', if followed by a function +# prototype or function definition. +sp_before_byref_func = force # ignore/add/remove/force -# Add or remove space between type and word. Default=Force -sp_after_type = add # ignore/add/remove/force +# Add or remove space between type and word. +# +# Default: force +sp_after_type = force # ignore/add/remove/force -# Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('. +# Add or remove space between 'decltype(...)' and word. +sp_after_decltype = force # ignore/add/remove/force + +# (D) Add or remove space before the parenthesis in the D constructs +# 'template Foo(' and 'class Foo('. sp_before_template_paren = ignore # ignore/add/remove/force -# Add or remove space in 'template <' vs 'template<'. +# Add or remove space between 'template' and '<'. # If set to ignore, sp_before_angle is used. -sp_template_angle = ignore # ignore/add/remove/force +sp_template_angle = remove # ignore/add/remove/force -# Add or remove space before '<>' +# Add or remove space before '<'. sp_before_angle = ignore # ignore/add/remove/force -# Add or remove space inside '<' and '>' +# Add or remove space inside '<' and '>'. sp_inside_angle = ignore # ignore/add/remove/force -# Add or remove space after '<>' +# Add or remove space between '>' and ':'. +sp_angle_colon = ignore # ignore/add/remove/force + +# Add or remove space after '<>'. sp_after_angle = ignore # ignore/add/remove/force -# Add or remove space between '<>' and '(' as found in 'new List(foo);' +# Add or remove space between '>' and '(' as found in 'new List(foo);'. sp_angle_paren = remove # ignore/add/remove/force -# Add or remove space between '<>' and '()' as found in 'new List();' -sp_angle_paren_empty = ignore # ignore/add/remove/force +# Add or remove space between '>' and '()' as found in 'new List();'. +sp_angle_paren_empty = remove # ignore/add/remove/force -# Add or remove space between '<>' and a word as in 'List m;' or 'template static ...' -sp_angle_word = add # ignore/add/remove/force +# Add or remove space between '>' and a word as in 'List m;' or +# 'template static ...'. +sp_angle_word = force # ignore/add/remove/force -# Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add -sp_angle_shift = add # ignore/add/remove/force +# Add or remove space between '>' and '>' in '>>' (template stuff). +# +# Default: add +sp_angle_shift = remove # ignore/add/remove/force -# Permit removal of the space between '>>' in 'foo >' (C++11 only). Default=False -# sp_angle_shift cannot remove the space without this option. -sp_permit_cpp11_shift = false # false/true +# (C++11) Permit removal of the space between '>>' in 'foo >'. Note +# that sp_angle_shift cannot remove the space without this option. +sp_permit_cpp11_shift = true # true/false -# Add or remove space before '(' of 'if', 'for', 'switch', 'while', etc. -sp_before_sparen = add # ignore/add/remove/force +# Add or remove space before '(' of control statements ('if', 'for', 'switch', +# 'while', etc.). +sp_before_sparen = force # ignore/add/remove/force -# Add or remove space inside if-condition '(' and ')' +# Add or remove space inside '(' and ')' of control statements. sp_inside_sparen = remove # ignore/add/remove/force -# Add or remove space before if-condition ')'. Overrides sp_inside_sparen. -sp_inside_sparen_close = ignore # ignore/add/remove/force - -# Add or remove space after if-condition '('. Overrides sp_inside_sparen. +# Add or remove space after '(' of control statements. +# +# Overrides sp_inside_sparen. sp_inside_sparen_open = ignore # ignore/add/remove/force -# Add or remove space after ')' of 'if', 'for', 'switch', and 'while', etc. -sp_after_sparen = ignore # ignore/add/remove/force +# Add or remove space before ')' of control statements. +# +# Overrides sp_inside_sparen. +sp_inside_sparen_close = ignore # ignore/add/remove/force -# Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while', etc. -sp_sparen_brace = ignore # ignore/add/remove/force +# Add or remove space after ')' of control statements. +sp_after_sparen = force # ignore/add/remove/force -# Add or remove space between 'invariant' and '(' in the D language. +# Add or remove space between ')' and '{' of of control statements. +sp_sparen_brace = force # ignore/add/remove/force + +# (D) Add or remove space between 'invariant' and '('. sp_invariant_paren = ignore # ignore/add/remove/force -# Add or remove space after the ')' in 'invariant (C) c' in the D language. +# (D) Add or remove space after the ')' in 'invariant (C) c'. sp_after_invariant_paren = ignore # ignore/add/remove/force -# Add or remove space before empty statement ';' on 'if', 'for' and 'while' +# Add or remove space before empty statement ';' on 'if', 'for' and 'while'. sp_special_semi = ignore # ignore/add/remove/force -# Add or remove space before ';'. Default=Remove +# Add or remove space before ';'. +# +# Default: remove sp_before_semi = remove # ignore/add/remove/force -# Add or remove space before ';' in non-empty 'for' statements +# Add or remove space before ';' in non-empty 'for' statements. sp_before_semi_for = remove # ignore/add/remove/force # Add or remove space before a semicolon of an empty part of a for statement. sp_before_semi_for_empty = remove # ignore/add/remove/force -# Add or remove space after ';', except when followed by a comment. Default=Add +# Add or remove space after ';', except when followed by a comment. +# +# Default: add sp_after_semi = add # ignore/add/remove/force -# Add or remove space after ';' in non-empty 'for' statements. Default=Force +# Add or remove space after ';' in non-empty 'for' statements. +# +# Default: force sp_after_semi_for = force # ignore/add/remove/force -# Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). +# Add or remove space after the final semicolon of an empty part of a for +# statement, as in 'for ( ; ; )'. sp_after_semi_for_empty = remove # ignore/add/remove/force -# Add or remove space before '[' (except '[]') -sp_before_square = ignore # ignore/add/remove/force +# Add or remove space before '[' (except '[]'). +sp_before_square = remove # ignore/add/remove/force -# Add or remove space before '[]' -sp_before_squares = ignore # ignore/add/remove/force +# Add or remove space before '[]'. +sp_before_squares = remove # ignore/add/remove/force -# Add or remove space inside a non-empty '[' and ']' -sp_inside_square = ignore # ignore/add/remove/force +# Add or remove space before C++17 structured bindings. +sp_cpp_before_struct_binding = force # ignore/add/remove/force -# Add or remove space after ',' -sp_after_comma = add # ignore/add/remove/force +# Add or remove space inside a non-empty '[' and ']'. +sp_inside_square = remove # ignore/add/remove/force -# Add or remove space before ','. Default=Remove +# (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and +# ']'. If set to ignore, sp_inside_square is used. +sp_inside_square_oc_array = ignore # ignore/add/remove/force + +# Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. +sp_after_comma = force # ignore/add/remove/force + +# Add or remove space before ','. +# +# Default: remove sp_before_comma = remove # ignore/add/remove/force -# Add or remove space between ',' and ']' in multidimensional array type 'int[,,]' +# (C#) Add or remove space between ',' and ']' in multidimensional array type +# like 'int[,,]'. sp_after_mdatype_commas = ignore # ignore/add/remove/force -# Add or remove space between '[' and ',' in multidimensional array type 'int[,,]' +# (C#) Add or remove space between '[' and ',' in multidimensional array type +# like 'int[,,]'. sp_before_mdatype_commas = ignore # ignore/add/remove/force -# Add or remove space between ',' in multidimensional array type 'int[,,]' +# (C#) Add or remove space between ',' in multidimensional array type +# like 'int[,,]'. sp_between_mdatype_commas = ignore # ignore/add/remove/force -# Add or remove space between an open paren and comma: '(,' vs '( ,'. Default=Force +# Add or remove space between an open parenthesis and comma, +# i.e. '(,' vs. '( ,'. +# +# Default: force sp_paren_comma = force # ignore/add/remove/force -# Add or remove space before the variadic '...' when preceded by a non-punctuator +# Add or remove space before the variadic '...' when preceded by a +# non-punctuator. sp_before_ellipsis = ignore # ignore/add/remove/force -# Add or remove space after class ':' -sp_after_class_colon = add # ignore/add/remove/force +# Add or remove space between a type and '...'. +sp_type_ellipsis = ignore # ignore/add/remove/force -# Add or remove space before class ':' -sp_before_class_colon = add # ignore/add/remove/force +# Add or remove space between ')' and '...'. +sp_paren_ellipsis = ignore # ignore/add/remove/force -# Add or remove space after class constructor ':' -sp_after_constr_colon = ignore # ignore/add/remove/force +# Add or remove space after class ':'. +sp_after_class_colon = force # ignore/add/remove/force -# Add or remove space before class constructor ':' -sp_before_constr_colon = ignore # ignore/add/remove/force +# Add or remove space before class ':'. +sp_before_class_colon = force # ignore/add/remove/force -# Add or remove space before case ':'. Default=Remove +# Add or remove space after class constructor ':'. +sp_after_constr_colon = force # ignore/add/remove/force + +# Add or remove space before class constructor ':'. +sp_before_constr_colon = force # ignore/add/remove/force + +# Add or remove space before case ':'. +# +# Default: remove sp_before_case_colon = remove # ignore/add/remove/force -# Add or remove space between 'operator' and operator sign +# Add or remove space between 'operator' and operator sign. sp_after_operator = remove # ignore/add/remove/force -# Add or remove space between the operator symbol and the open paren, as in 'operator ++(' +# Add or remove space between the operator symbol and the open parenthesis, as +# in 'operator ++('. sp_after_operator_sym = remove # ignore/add/remove/force -# Add or remove space between the operator symbol and the open paren when the operator has no arguments, as in 'operator *()' +# Overrides sp_after_operator_sym when the operator has no arguments, as in +# 'operator *()'. sp_after_operator_sym_empty = ignore # ignore/add/remove/force -# Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' -sp_after_cast = add # ignore/add/remove/force +# Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or +# '(int)a' vs. '(int) a'. +sp_after_cast = force # ignore/add/remove/force -# Add or remove spaces inside cast parens +# Add or remove spaces inside cast parentheses. sp_inside_paren_cast = remove # ignore/add/remove/force -# Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' -sp_cpp_cast_paren = add # ignore/add/remove/force +# Add or remove space between the type and open parenthesis in a C++ cast, +# i.e. 'int(exp)' vs. 'int (exp)'. +sp_cpp_cast_paren = ignore # ignore/add/remove/force -# Add or remove space between 'sizeof' and '(' +# Add or remove space between 'sizeof' and '('. sp_sizeof_paren = remove # ignore/add/remove/force -# Add or remove space after the tag keyword (Pawn) +# Add or remove space between 'sizeof' and '...'. +sp_sizeof_ellipsis = ignore # ignore/add/remove/force + +# Add or remove space between 'sizeof...' and '('. +sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force + +# Add or remove space between 'decltype' and '('. +sp_decltype_paren = remove # ignore/add/remove/force + +# (Pawn) Add or remove space after the tag keyword. sp_after_tag = ignore # ignore/add/remove/force -# Add or remove space inside enum '{' and '}' -sp_inside_braces_enum = ignore # ignore/add/remove/force +# Add or remove space inside enum '{' and '}'. +sp_inside_braces_enum = force # ignore/add/remove/force -# Add or remove space inside struct/union '{' and '}' -sp_inside_braces_struct = ignore # ignore/add/remove/force +# Add or remove space inside struct/union '{' and '}'. +sp_inside_braces_struct = force # ignore/add/remove/force -# Add or remove space inside '{' and '}' +# (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}' +sp_inside_braces_oc_dict = ignore # ignore/add/remove/force + +# Add or remove space after open brace in an unnamed temporary +# direct-list-initialization. +sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force + +# Add or remove space before close brace in an unnamed temporary +# direct-list-initialization. +sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force + +# Add or remove space inside an unnamed temporary direct-list-initialization. +sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force + +# Add or remove space inside '{' and '}'. sp_inside_braces = ignore # ignore/add/remove/force -# Add or remove space inside '{}' -sp_inside_braces_empty = ignore # ignore/add/remove/force +# Add or remove space inside '{}'. +sp_inside_braces_empty = remove # ignore/add/remove/force -# Add or remove space between return type and function name -# A minimum of 1 is forced except for pointer return types. +# Add or remove space between return type and function name. A minimum of 1 +# is forced except for pointer return types. sp_type_func = ignore # ignore/add/remove/force -# Add or remove space between function name and '(' on function declaration +# Add or remove space between type and open brace of an unnamed temporary +# direct-list-initialization. +sp_type_brace_init_lst = remove # ignore/add/remove/force + +# Add or remove space between function name and '(' on function declaration. sp_func_proto_paren = remove # ignore/add/remove/force -# Add or remove space between function name and '()' on function declaration without parameters -sp_func_proto_paren_empty = ignore # ignore/add/remove/force +# Add or remove space between function name and '()' on function declaration +# without parameters. +sp_func_proto_paren_empty = remove # ignore/add/remove/force -# Add or remove space between function name and '(' on function definition +# Add or remove space between function name and '(' on function definition. sp_func_def_paren = remove # ignore/add/remove/force -# Add or remove space between function name and '()' on function definition without parameters -sp_func_def_paren_empty = ignore # ignore/add/remove/force +# Add or remove space between function name and '()' on function definition +# without parameters. +sp_func_def_paren_empty = remove # ignore/add/remove/force -# Add or remove space inside empty function '()' +# Add or remove space inside empty function '()'. sp_inside_fparens = remove # ignore/add/remove/force -# Add or remove space inside function '(' and ')' +# Add or remove space inside function '(' and ')'. sp_inside_fparen = remove # ignore/add/remove/force -# Add or remove space inside the first parens in the function type: 'void (*x)(...)' -sp_inside_tparen = ignore # ignore/add/remove/force +# Add or remove space inside the first parentheses in a function type, as in +# 'void (*x)(...)'. +sp_inside_tparen = remove # ignore/add/remove/force -# Add or remove between the parens in the function type: 'void (*x)(...)' -sp_after_tparen_close = ignore # ignore/add/remove/force +# Add or remove space between the ')' and '(' in a function type, as in +# 'void (*x)(...)'. +sp_after_tparen_close = remove # ignore/add/remove/force # Add or remove space between ']' and '(' when part of a function call. sp_square_fparen = remove # ignore/add/remove/force -# Add or remove space between ')' and '{' of function -sp_fparen_brace = ignore # ignore/add/remove/force +# Add or remove space between ')' and '{' of function. +sp_fparen_brace = force # ignore/add/remove/force -# Java: Add or remove space between ')' and '{{' of double brace initializer. +# Add or remove space between ')' and '{' of s function call in object +# initialization. +# +# Overrides sp_fparen_brace. +sp_fparen_brace_initializer = ignore # ignore/add/remove/force + +# (Java) Add or remove space between ')' and '{{' of double brace initializer. sp_fparen_dbrace = ignore # ignore/add/remove/force -# Add or remove space between function name and '(' on function calls +# Add or remove space between function name and '(' on function calls. sp_func_call_paren = remove # ignore/add/remove/force -# Add or remove space between function name and '()' on function calls without parameters. -# If set to 'ignore' (the default), sp_func_call_paren is used. +# Add or remove space between function name and '()' on function calls without +# parameters. If set to 'ignore' (the default), sp_func_call_paren is used. sp_func_call_paren_empty = ignore # ignore/add/remove/force -# Add or remove space between the user function name and '(' on function calls -# You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. +# Add or remove space between the user function name and '(' on function +# calls. You need to set a keyword to be a user function in the config file, +# like: +# set func_call_user tr _ i18n sp_func_call_user_paren = ignore # ignore/add/remove/force -# Add or remove space between a constructor/destructor and the open paren +# Add or remove space inside user function '(' and ')'. +sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force + +# Add or remove space between nested parentheses with user functions, +# i.e. '((' vs. '( ('. +sp_func_call_user_paren_paren = ignore # ignore/add/remove/force + +# Add or remove space between a constructor/destructor and the open +# parenthesis. sp_func_class_paren = remove # ignore/add/remove/force -# Add or remove space between a constructor without parameters or destructor and '()' -sp_func_class_paren_empty = ignore # ignore/add/remove/force +# Add or remove space between a constructor without parameters or destructor +# and '()'. +sp_func_class_paren_empty = remove # ignore/add/remove/force -# Add or remove space between 'return' and '(' -sp_return_paren = add # ignore/add/remove/force +# Add or remove space between 'return' and '('. +sp_return_paren = force # ignore/add/remove/force -# Add or remove space between '__attribute__' and '(' +# Add or remove space between 'return' and '{'. +sp_return_brace = force # ignore/add/remove/force + +# Add or remove space between '__attribute__' and '('. sp_attribute_paren = ignore # ignore/add/remove/force -# Add or remove space between 'defined' and '(' in '#if defined (FOO)' +# Add or remove space between 'defined' and '(' in '#if defined (FOO)'. sp_defined_paren = remove # ignore/add/remove/force -# Add or remove space between 'throw' and '(' in 'throw (something)' -sp_throw_paren = add # ignore/add/remove/force +# Add or remove space between 'throw' and '(' in 'throw (something)'. +sp_throw_paren = force # ignore/add/remove/force -# Add or remove space between 'throw' and anything other than '(' as in '@throw [...];' +# Add or remove space between 'throw' and anything other than '(' as in +# '@throw [...];'. sp_after_throw = ignore # ignore/add/remove/force -# Add or remove space between 'catch' and '(' in 'catch (something) { }' +# Add or remove space between 'catch' and '(' in 'catch (something) { }'. # If set to ignore, sp_before_sparen is used. -sp_catch_paren = ignore # ignore/add/remove/force +sp_catch_paren = force # ignore/add/remove/force -# Add or remove space between 'version' and '(' in 'version (something) { }' (D language) -# If set to ignore, sp_before_sparen is used. +# (OC) Add or remove space between '@catch' and '(' +# in '@catch (something) { }'. If set to ignore, sp_catch_paren is used. +sp_oc_catch_paren = ignore # ignore/add/remove/force + +# (D) Add or remove space between 'version' and '(' +# in 'version (something) { }'. If set to ignore, sp_before_sparen is used. sp_version_paren = ignore # ignore/add/remove/force -# Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language) -# If set to ignore, sp_before_sparen is used. +# (D) Add or remove space between 'scope' and '(' +# in 'scope (something) { }'. If set to ignore, sp_before_sparen is used. sp_scope_paren = ignore # ignore/add/remove/force -# Add or remove space between 'super' and '(' in 'super (something)'. Default=Remove +# Add or remove space between 'super' and '(' in 'super (something)'. +# +# Default: remove sp_super_paren = remove # ignore/add/remove/force -# Add or remove space between 'this' and '(' in 'this (something)'. Default=Remove +# Add or remove space between 'this' and '(' in 'this (something)'. +# +# Default: remove sp_this_paren = remove # ignore/add/remove/force -# Add or remove space between macro and value -sp_macro = ignore # ignore/add/remove/force +# Add or remove space between a macro name and its definition. +sp_macro = force # ignore/add/remove/force -# Add or remove space between macro function ')' and value -sp_macro_func = ignore # ignore/add/remove/force +# Add or remove space between a macro function ')' and its definition. +sp_macro_func = force # ignore/add/remove/force -# Add or remove space between 'else' and '{' if on the same line -sp_else_brace = ignore # ignore/add/remove/force +# Add or remove space between 'else' and '{' if on the same line. +sp_else_brace = force # ignore/add/remove/force -# Add or remove space between '}' and 'else' if on the same line -sp_brace_else = ignore # ignore/add/remove/force +# Add or remove space between '}' and 'else' if on the same line. +sp_brace_else = force # ignore/add/remove/force -# Add or remove space between '}' and the name of a typedef on the same line -sp_brace_typedef = add # ignore/add/remove/force +# Add or remove space between '}' and the name of a typedef on the same line. +sp_brace_typedef = force # ignore/add/remove/force -# Add or remove space between 'catch' and '{' if on the same line -sp_catch_brace = ignore # ignore/add/remove/force +# Add or remove space before the '{' of a 'catch' statement, if the '{' and +# 'catch' are on the same line, as in 'catch (decl) {'. +sp_catch_brace = force # ignore/add/remove/force -# Add or remove space between '}' and 'catch' if on the same line -sp_brace_catch = ignore # ignore/add/remove/force +# (OC) Add or remove space before the '{' of a '@catch' statement, if the '{' +# and '@catch' are on the same line, as in '@catch (decl) {'. +# If set to ignore, sp_catch_brace is used. +sp_oc_catch_brace = ignore # ignore/add/remove/force -# Add or remove space between 'finally' and '{' if on the same line -sp_finally_brace = ignore # ignore/add/remove/force +# Add or remove space between '}' and 'catch' if on the same line. +sp_brace_catch = force # ignore/add/remove/force -# Add or remove space between '}' and 'finally' if on the same line -sp_brace_finally = ignore # ignore/add/remove/force +# (OC) Add or remove space between '}' and '@catch' if on the same line. +# If set to ignore, sp_brace_catch is used. +sp_oc_brace_catch = ignore # ignore/add/remove/force -# Add or remove space between 'try' and '{' if on the same line -sp_try_brace = ignore # ignore/add/remove/force +# Add or remove space between 'finally' and '{' if on the same line. +sp_finally_brace = force # ignore/add/remove/force -# Add or remove space between get/set and '{' if on the same line +# Add or remove space between '}' and 'finally' if on the same line. +sp_brace_finally = force # ignore/add/remove/force + +# Add or remove space between 'try' and '{' if on the same line. +sp_try_brace = force # ignore/add/remove/force + +# Add or remove space between get/set and '{' if on the same line. sp_getset_brace = ignore # ignore/add/remove/force -# Add or remove space between a variable and '{' for C++ uniform initialization. Default=Add +# Add or remove space between a variable and '{' for C++ uniform +# initialization. +# +# Default: add sp_word_brace = add # ignore/add/remove/force -# Add or remove space between a variable and '{' for a namespace. Default=Add +# Add or remove space between a variable and '{' for a namespace. +# +# Default: add sp_word_brace_ns = add # ignore/add/remove/force -# Add or remove space before the '::' operator +# Add or remove space before the '::' operator. sp_before_dc = remove # ignore/add/remove/force -# Add or remove space after the '::' operator +# Add or remove space after the '::' operator. sp_after_dc = remove # ignore/add/remove/force -# Add or remove around the D named array initializer ':' operator +# (D) Add or remove around the D named array initializer ':' operator. sp_d_array_colon = ignore # ignore/add/remove/force -# Add or remove space after the '!' (not) operator. Default=Remove +# Add or remove space after the '!' (not) unary operator. +# +# Default: remove sp_not = remove # ignore/add/remove/force -# Add or remove space after the '~' (invert) operator. Default=Remove +# Add or remove space after the '~' (invert) unary operator. +# +# Default: remove sp_inv = remove # ignore/add/remove/force -# Add or remove space after the '&' (address-of) operator. Default=Remove -# This does not affect the spacing after a '&' that is part of a type. +# Add or remove space after the '&' (address-of) unary operator. This does not +# affect the spacing after a '&' that is part of a type. +# +# Default: remove sp_addr = remove # ignore/add/remove/force -# Add or remove space around the '.' or '->' operators. Default=Remove +# Add or remove space around the '.' or '->' operators. +# +# Default: remove sp_member = remove # ignore/add/remove/force -# Add or remove space after the '*' (dereference) operator. Default=Remove -# This does not affect the spacing after a '*' that is part of a type. +# Add or remove space after the '*' (dereference) unary operator. This does +# not affect the spacing after a '*' that is part of a type. +# +# Default: remove sp_deref = remove # ignore/add/remove/force -# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove +# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. +# +# Default: remove sp_sign = remove # ignore/add/remove/force -# Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove +# Add or remove space between '++' and '--' the word to which it is being +# applied, as in '(--x)' or 'y++;'. +# +# Default: remove sp_incdec = remove # ignore/add/remove/force -# Add or remove space before a backslash-newline at the end of a line. Default=Add +# Add or remove space before a backslash-newline at the end of a line. +# +# Default: add sp_before_nl_cont = add # ignore/add/remove/force -# Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' +# (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;' +# or '+(int) bar;'. sp_after_oc_scope = ignore # ignore/add/remove/force -# Add or remove space after the colon in message specs -# '-(int) f:(int) x;' vs '-(int) f: (int) x;' +# (OC) Add or remove space after the colon in message specs, +# i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'. sp_after_oc_colon = ignore # ignore/add/remove/force -# Add or remove space before the colon in message specs -# '-(int) f: (int) x;' vs '-(int) f : (int) x;' +# (OC) Add or remove space before the colon in message specs, +# i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'. sp_before_oc_colon = ignore # ignore/add/remove/force -# Add or remove space after the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};' +# (OC) Add or remove space after the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. sp_after_oc_dict_colon = ignore # ignore/add/remove/force -# Add or remove space before the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};' +# (OC) Add or remove space before the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. sp_before_oc_dict_colon = ignore # ignore/add/remove/force -# Add or remove space after the colon in message specs -# '[object setValue:1];' vs '[object setValue: 1];' +# (OC) Add or remove space after the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue: 1];'. sp_after_send_oc_colon = ignore # ignore/add/remove/force -# Add or remove space before the colon in message specs -# '[object setValue:1];' vs '[object setValue :1];' +# (OC) Add or remove space before the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue :1];'. sp_before_send_oc_colon = ignore # ignore/add/remove/force -# Add or remove space after the (type) in message specs -# '-(int)f: (int) x;' vs '-(int)f: (int)x;' +# (OC) Add or remove space after the (type) in message specs, +# i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'. sp_after_oc_type = ignore # ignore/add/remove/force -# Add or remove space after the first (type) in message specs -# '-(int) f:(int)x;' vs '-(int)f:(int)x;' +# (OC) Add or remove space after the first (type) in message specs, +# i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'. sp_after_oc_return_type = ignore # ignore/add/remove/force -# Add or remove space between '@selector' and '(' -# '@selector(msgName)' vs '@selector (msgName)' -# Also applies to @protocol() constructs +# (OC) Add or remove space between '@selector' and '(', +# i.e. '@selector(msgName)' vs. '@selector (msgName)'. +# Also applies to '@protocol()' constructs. sp_after_oc_at_sel = ignore # ignore/add/remove/force -# Add or remove space between '@selector(x)' and the following word -# '@selector(foo) a:' vs '@selector(foo)a:' +# (OC) Add or remove space between '@selector(x)' and the following word, +# i.e. '@selector(foo) a:' vs. '@selector(foo)a:'. sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force -# Add or remove space inside '@selector' parens -# '@selector(foo)' vs '@selector( foo )' -# Also applies to @protocol() constructs +# (OC) Add or remove space inside '@selector' parentheses, +# i.e. '@selector(foo)' vs. '@selector( foo )'. +# Also applies to '@protocol()' constructs. sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force -# Add or remove space before a block pointer caret -# '^int (int arg){...}' vs. ' ^int (int arg){...}' +# (OC) Add or remove space before a block pointer caret, +# i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'. sp_before_oc_block_caret = ignore # ignore/add/remove/force -# Add or remove space after a block pointer caret -# '^int (int arg){...}' vs. '^ int (int arg){...}' +# (OC) Add or remove space after a block pointer caret, +# i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'. sp_after_oc_block_caret = ignore # ignore/add/remove/force -# Add or remove space between the receiver and selector in a message. -# '[receiver selector ...]' +# (OC) Add or remove space between the receiver and selector in a message, +# as in '[receiver selector ...]'. sp_after_oc_msg_receiver = ignore # ignore/add/remove/force -# Add or remove space after @property. +# (OC) Add or remove space after '@property'. sp_after_oc_property = ignore # ignore/add/remove/force -# Add or remove space around the ':' in 'b ? t : f' -sp_cond_colon = add # ignore/add/remove/force +# (OC) Add or remove space between '@synchronized' and the open parenthesis, +# i.e. '@synchronized(foo)' vs. '@synchronized (foo)'. +sp_after_oc_synchronized = ignore # ignore/add/remove/force -# Add or remove space before the ':' in 'b ? t : f'. Overrides sp_cond_colon. +# Add or remove space around the ':' in 'b ? t : f'. +sp_cond_colon = force # ignore/add/remove/force + +# Add or remove space before the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. sp_cond_colon_before = ignore # ignore/add/remove/force -# Add or remove space after the ':' in 'b ? t : f'. Overrides sp_cond_colon. +# Add or remove space after the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. sp_cond_colon_after = ignore # ignore/add/remove/force -# Add or remove space around the '?' in 'b ? t : f' -sp_cond_question = add # ignore/add/remove/force +# Add or remove space around the '?' in 'b ? t : f'. +sp_cond_question = force # ignore/add/remove/force -# Add or remove space before the '?' in 'b ? t : f'. Overrides sp_cond_question. +# Add or remove space before the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. sp_cond_question_before = ignore # ignore/add/remove/force -# Add or remove space after the '?' in 'b ? t : f'. Overrides sp_cond_question. +# Add or remove space after the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. sp_cond_question_after = ignore # ignore/add/remove/force -# In the abbreviated ternary form (a ?: b), add/remove space between ? and :.'. Overrides all other sp_cond_* options. +# In the abbreviated ternary form '(a ?: b)', add or remove space between '?' +# and ':'. +# +# Overrides all other sp_cond_* options. sp_cond_ternary_short = ignore # ignore/add/remove/force -# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. -sp_case_label = ignore # ignore/add/remove/force +# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make +# sense here. +sp_case_label = force # ignore/add/remove/force -# Control the space around the D '..' operator. +# (D) Add or remove space around the D '..' operator. sp_range = ignore # ignore/add/remove/force -# Control the spacing after ':' in 'for (TYPE VAR : EXPR)' -sp_after_for_colon = ignore # ignore/add/remove/force +# Add or remove space after ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var : expr)'. +sp_after_for_colon = force # ignore/add/remove/force -# Control the spacing before ':' in 'for (TYPE VAR : EXPR)' -sp_before_for_colon = ignore # ignore/add/remove/force +# Add or remove space before ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var : expr)'. +sp_before_for_colon = force # ignore/add/remove/force -# Control the spacing in 'extern (C)' (D) +# (D) Add or remove space between 'extern' and '(' as in 'extern (C)'. sp_extern_paren = ignore # ignore/add/remove/force -# Control the space after the opening of a C++ comment '// A' vs '//A' +# Add or remove space after the opening of a C++ comment, +# i.e. '// A' vs. '//A'. sp_cmt_cpp_start = ignore # ignore/add/remove/force -# TRUE: If space is added with sp_cmt_cpp_start, do it after doxygen sequences like '///', '///<', '//!' and '//!<'. -sp_cmt_cpp_doxygen = false # false/true +# If true, space is added with sp_cmt_cpp_start will be added after doxygen +# sequences like '///', '///<', '//!' and '//!<'. +sp_cmt_cpp_doxygen = true # true/false -# TRUE: If space is added with sp_cmt_cpp_start, do it after Qt translator or meta-data comments like '//:', '//=', and '//~'. -sp_cmt_cpp_qttr = false # false/true +# If true, space is added with sp_cmt_cpp_start will be added after Qt +# translator or meta-data comments like '//:', '//=', and '//~'. +sp_cmt_cpp_qttr = false # true/false -# Controls the spaces between #else or #endif and a trailing comment +# Add or remove space between #else or #endif and a trailing comment. sp_endif_cmt = ignore # ignore/add/remove/force -# Controls the spaces after 'new', 'delete' and 'delete[]' -sp_after_new = ignore # ignore/add/remove/force +# Add or remove space after 'new', 'delete' and 'delete[]'. +sp_after_new = force # ignore/add/remove/force -# Controls the spaces between new and '(' in 'new()' +# Add or remove space between 'new' and '(' in 'new()'. sp_between_new_paren = ignore # ignore/add/remove/force -# Controls the spaces before a trailing or embedded comment -sp_before_tr_emb_cmt = ignore # ignore/add/remove/force +# Add or remove space between ')' and type in 'new(foo) BAR'. +sp_after_newop_paren = ignore # ignore/add/remove/force -# Number of spaces before a trailing or embedded comment -sp_num_before_tr_emb_cmt = 0 # number +# Add or remove space inside parenthesis of the new operator +# as in 'new(foo) BAR'. +sp_inside_newop_paren = ignore # ignore/add/remove/force -# Control space between a Java annotation and the open paren. +# Add or remove space after the open parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_open = ignore # ignore/add/remove/force + +# Add or remove space before the close parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_close = ignore # ignore/add/remove/force + +# Add or remove space before a trailing or embedded comment. +sp_before_tr_emb_cmt = force # ignore/add/remove/force + +# Number of spaces before a trailing or embedded comment. +sp_num_before_tr_emb_cmt = 0 # unsigned number + +# (Java) Add or remove space between an annotation and the open parenthesis. sp_annotation_paren = ignore # ignore/add/remove/force # If true, vbrace tokens are dropped to the previous token and skipped. -sp_skip_vbrace_tokens = false # false/true +sp_skip_vbrace_tokens = false # true/false + +# Add or remove space after 'noexcept'. +sp_after_noexcept = remove # ignore/add/remove/force + +# If true, a is inserted after #define. +force_tab_after_define = false # true/false # -# Code alignment (not left column spaces/tabs) +# Indenting options # -# Whether to keep non-indenting tabs -align_keep_tabs = false # false/true +# The number of columns to indent per level. Usually 2, 3, 4, or 8. +# +# Default: 8 +indent_columns = 2 # unsigned number -# Whether to use tabs for aligning -align_with_tabs = false # false/true +# The continuation indent. If non-zero, this overrides the indent of '(' and +# '=' continuation indents. Negative values are OK; negative value is absolute +# and not increased for each '(' level. +# +# For FreeBSD, this is set to 4. +indent_continue = 0 # number -# Whether to bump out to the next tab when aligning -align_on_tabstop = false # false/true +# The continuation indent, only for class header line(s). If non-zero, this +# overrides the indent of 'class' continuation indents. +indent_continue_class_head = 0 # unsigned number -# Whether to left-align numbers -align_number_left = false # false/true +# Whether to indent empty lines (i.e. lines which contain only spaces before +# the newline character). +indent_single_newlines = false # true/false -# Whether to keep whitespace not required for alignment. -align_keep_extra_space = false # false/true +# The continuation indent for func_*_param if they are true. If non-zero, this +# overrides the indent. +indent_param = 0 # unsigned number -# Align variable definitions in prototypes and functions -align_func_params = false # false/true +# How to use tabs when indenting code. +# +# 0: Spaces only +# 1: Indent with tabs to brace level, align with spaces (default) +# 2: Indent and align with tabs, using spaces when not on a tabstop +# +# Default: 1 +indent_with_tabs = 0 # unsigned number -# Align parameters in single-line functions that have the same name. -# The function names must already be aligned with each other. -align_same_func_call_params = false # false/true +# Whether to indent comments that are not at a brace level with tabs on a +# tabstop. Requires indent_with_tabs=2. If false, will use spaces. +indent_cmt_with_tabs = false # true/false -# The span for aligning variable definitions (0=don't align) -align_var_def_span = 0 # number +# Whether to indent strings broken by '\' so that they line up. +indent_align_string = false # true/false -# How to align the star in variable definitions. -# 0=Part of the type 'void * foo;' -# 1=Part of the variable 'void *foo;' -# 2=Dangling 'void *foo;' -align_var_def_star_style = 0 # number +# The number of spaces to indent multi-line XML strings. +# Requires indent_align_string=true. +indent_xml_string = 0 # unsigned number -# How to align the '&' in variable definitions. -# 0=Part of the type -# 1=Part of the variable -# 2=Dangling -align_var_def_amp_style = 0 # number +# Spaces to indent '{' from level. +indent_brace = 2 # unsigned number -# The threshold for aligning variable definitions (0=no limit) -align_var_def_thresh = 0 # number +# Whether braces are indented to the body level. +indent_braces = false # true/false -# The gap for aligning variable definitions -align_var_def_gap = 0 # number +# Whether to disable indenting function braces if indent_braces=true. +indent_braces_no_func = false # true/false -# Whether to align the colon in struct bit fields -align_var_def_colon = false # false/true +# Whether to disable indenting class braces if indent_braces=true. +indent_braces_no_class = false # true/false -# Whether to align any attribute after the variable name -align_var_def_attribute = false # false/true +# Whether to disable indenting struct braces if indent_braces=true. +indent_braces_no_struct = false # true/false -# Whether to align inline struct/enum/union variable definitions -align_var_def_inline = false # false/true +# Whether to indent based on the size of the brace parent, +# i.e. 'if' → 3 spaces, 'for' → 4 spaces, etc. +indent_brace_parent = false # true/false -# The span for aligning on '=' in assignments (0=don't align) -align_assign_span = 0 # number +# Whether to indent based on the open parenthesis instead of the open brace +# in '({\n'. +indent_paren_open_brace = false # true/false -# The threshold for aligning on '=' in assignments (0=no limit) -align_assign_thresh = 0 # number +# (C#) Whether to indent the brace of a C# delegate by another level. +indent_cs_delegate_brace = false # true/false -# The span for aligning on '=' in enums (0=don't align) -align_enum_equ_span = 0 # number +# (C#) Whether to indent a C# delegate (to handle delegates with no brace) by +# another level. +indent_cs_delegate_body = false # true/false -# The threshold for aligning on '=' in enums (0=no limit) -align_enum_equ_thresh = 0 # number +# Whether to indent the body of a 'namespace'. +indent_namespace = true # true/false -# The span for aligning class (0=don't align) -align_var_class_span = 0 # number +# Whether to indent only the first namespace, and not any nested namespaces. +# Requires indent_namespace=true. +indent_namespace_single_indent = false # true/false -# The threshold for aligning class member definitions (0=no limit) -align_var_class_thresh = 0 # number +# The number of spaces to indent a namespace block. +indent_namespace_level = 0 # unsigned number -# The gap for aligning class member definitions -align_var_class_gap = 0 # number +# If the body of the namespace is longer than this number, it won't be +# indented. Requires indent_namespace=true. 0 means no limit. +indent_namespace_limit = 0 # unsigned number -# The span for aligning struct/union (0=don't align) -align_var_struct_span = 0 # number +# Whether the 'extern "C"' body is indented. +indent_extern = true # true/false -# The threshold for aligning struct/union member definitions (0=no limit) -align_var_struct_thresh = 0 # number +# Whether the 'class' body is indented. +indent_class = true # true/false -# The gap for aligning struct/union member definitions -align_var_struct_gap = 0 # number +# Whether to indent the stuff after a leading base class colon. +indent_class_colon = false # true/false -# The span for aligning struct initializer values (0=don't align) -align_struct_init_span = 0 # number +# Whether to indent based on a class colon instead of the stuff after the +# colon. Requires indent_class_colon=true. +indent_class_on_colon = false # true/false -# The minimum space between the type and the synonym of a typedef -align_typedef_gap = 0 # number +# Whether to indent the stuff after a leading class initializer colon. +indent_constr_colon = false # true/false -# The span for aligning single-line typedefs (0=don't align) -align_typedef_span = 0 # number +# Virtual indent from the ':' for member initializers. +# +# Default: 2 +indent_ctor_init_leading = 2 # unsigned number -# How to align typedef'd functions with other typedefs -# 0: Don't mix them at all -# 1: align the open paren with the types -# 2: align the function type name with the other type names -align_typedef_func = 0 # number +# Additional indent for constructor initializer list. +# Negative values decrease indent down to the first column. +indent_ctor_init = 0 # number -# Controls the positioning of the '*' in typedefs. Just try it. -# 0: Align on typedef type, ignore '*' -# 1: The '*' is part of type name: typedef int *pint; -# 2: The '*' is part of the type, but dangling: typedef int *pint; -align_typedef_star_style = 0 # number +# Whether to indent 'if' following 'else' as a new block under the 'else'. +# If false, 'else\nif' is treated as 'else if' for indenting purposes. +indent_else_if = true # true/false -# Controls the positioning of the '&' in typedefs. Just try it. -# 0: Align on typedef type, ignore '&' -# 1: The '&' is part of type name: typedef int &pint; -# 2: The '&' is part of the type, but dangling: typedef int &pint; -align_typedef_amp_style = 0 # number +# Amount to indent variable declarations after a open brace. +# +# <0: Relative +# ≥0: Absolute +indent_var_def_blk = 0 # number -# The span for aligning comments that end lines (0=don't align) -align_right_cmt_span = 0 # number +# Whether to indent continued variable declarations instead of aligning. +indent_var_def_cont = false # true/false -# If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment -align_right_cmt_mix = false # false/true +# Whether to indent continued shift expressions ('<<' and '>>') instead of +# aligning. Set align_left_shift=false when enabling this. +indent_shift = false # true/false -# If a trailing comment is more than this number of columns away from the text it follows, -# it will qualify for being aligned. This has to be > 0 to do anything. -align_right_cmt_gap = 0 # number +# Whether to force indentation of function definitions to start in column 1. +indent_func_def_force_col1 = false # true/false -# Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) -align_right_cmt_at_col = 0 # number +# Whether to indent continued function call parameters one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_call_param = false # true/false -# The span for aligning function prototypes (0=don't align) -align_func_proto_span = 0 # number +# Same as indent_func_call_param, but for function definitions. +indent_func_def_param = false # true/false -# Minimum gap between the return type and the function name. -align_func_proto_gap = 0 # number +# Same as indent_func_call_param, but for function prototypes. +indent_func_proto_param = false # true/false -# Align function protos on the 'operator' keyword instead of what follows -align_on_operator = false # false/true +# Same as indent_func_call_param, but for class declarations. +indent_func_class_param = false # true/false -# Whether to mix aligning prototype and variable declarations. -# If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. -align_mix_var_proto = false # false/true +# Same as indent_func_call_param, but for class variable constructors. +indent_func_ctor_var_param = false # true/false -# Align single-line functions with function prototypes, uses align_func_proto_span -align_single_line_func = false # false/true +# Same as indent_func_call_param, but for template parameter lists. +indent_template_param = false # true/false -# Aligning the open brace of single-line functions. -# Requires align_single_line_func=true, uses align_func_proto_span -align_single_line_brace = false # false/true +# Double the indent for indent_func_xxx_param options. +# Use both values of the options indent_columns and indent_param. +indent_func_param_double = false # true/false -# Gap for align_single_line_brace. -align_single_line_brace_gap = 0 # number +# Indentation column for standalone 'const' qualifier on a function +# prototype. +indent_func_const = 0 # unsigned number -# The span for aligning ObjC msg spec (0=don't align) -align_oc_msg_spec_span = 0 # number +# Indentation column for standalone 'throw' qualifier on a function +# prototype. +indent_func_throw = 0 # unsigned number -# Whether to align macros wrapped with a backslash and a newline. -# This will not work right if the macro contains a multi-line comment. -align_nl_cont = false # false/true +# The number of spaces to indent a continued '->' or '.'. +# Usually set to 0, 1, or indent_columns. +indent_member = 0 # unsigned number -# # Align macro functions and variables together -align_pp_define_together = false # false/true +# Whether lines broken at '.' or '->' should be indented by a single indent. +# The indent_member option will not be effective if this is set to true. +indent_member_single = true # true/false -# The minimum space between label and value of a preprocessor define -align_pp_define_gap = 0 # number +# Spaces to indent single line ('//') comments on lines before code. +indent_sing_line_comments = 0 # unsigned number -# The span for aligning on '#define' bodies (0=don't align, other=number of lines including comments between blocks) -align_pp_define_span = 0 # number +# Whether to indent trailing single line ('//') comments relative to the code +# instead of trying to keep the same absolute column. +indent_relative_single_line_comments = true # true/false -# Align lines that start with '<<' with previous '<<'. Default=True -align_left_shift = true # false/true +# Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns. +indent_switch_case = 0 # unsigned number -# Align text after asm volatile () colons. -align_asm_colon = false # false/true +# Whether to indent preprocessor statements inside of switch statements. +# +# Default: true +indent_switch_pp = true # true/false -# Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) -align_oc_msg_colon_span = 0 # number +# Spaces to shift the 'case' line, without affecting any other lines. +# Usually 0. +indent_case_shift = 0 # unsigned number -# If true, always align with the first parameter, even if it is too short. -align_oc_msg_colon_first = false # false/true +# Spaces to indent '{' from 'case'. By default, the brace will appear under +# the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK. +indent_case_brace = 2 # number -# Aligning parameters in an Obj-C '+' or '-' declaration on the ':' -align_oc_decl_colon = false # false/true +# Whether to indent comments found in first column. +indent_col1_comment = false # true/false + +# How to indent goto labels. +# +# >0: Absolute column where 1 is the leftmost column +# ≤0: Subtract from brace indent +# +# Default: 1 +indent_label = -2 # number + +# Same as indent_label, but for access specifiers that are followed by a +# colon. +# +# Default: 1 +indent_access_spec = -2 # number + +# Whether to indent the code after an access specifier by one level. +# If true, this option forces 'indent_access_spec=0'. +indent_access_spec_body = false # true/false + +# If an open parenthesis is followed by a newline, whether to indent the next +# line so that it lines up after the open parenthesis (not recommended). +indent_paren_nl = false # true/false + +# How to indent a close parenthesis after a newline. +# +# 0: Indent to body level (default) +# 1: Align under the open parenthesis +# 2: Indent to the brace level +indent_paren_close = 0 # unsigned number + +# Whether to indent the open parenthesis of a function definition, +# if the parenthesis is on its own line. +indent_paren_after_func_def = false # true/false + +# Whether to indent the open parenthesis of a function declaration, +# if the parenthesis is on its own line. +indent_paren_after_func_decl = false # true/false + +# Whether to indent the open parenthesis of a function call, +# if the parenthesis is on its own line. +indent_paren_after_func_call = false # true/false + +# Whether to indent a comma when inside a parenthesis. +# If true, aligns under the open parenthesis. +indent_comma_paren = false # true/false + +# Whether to indent a Boolean operator when inside a parenthesis. +# If true, aligns under the open parenthesis. +indent_bool_paren = false # true/false + +# Whether to indent a semicolon when inside a for parenthesis. +# If true, aligns under the open for parenthesis. +indent_semicolon_for_paren = false # true/false + +# Whether to align the first expression to following ones +# if indent_bool_paren=true. +indent_first_bool_expr = false # true/false + +# Whether to align the first expression to following ones +# if indent_semicolon_for_paren=true. +indent_first_for_expr = false # true/false + +# If an open square is followed by a newline, whether to indent the next line +# so that it lines up after the open square (not recommended). +indent_square_nl = false # true/false + +# (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies. +indent_preserve_sql = false # true/false + +# Whether to align continued statements at the '='. If false or if the '=' is +# followed by a newline, the next line is indent one tab. +# +# Default: true +indent_align_assign = true # true/false + +# Whether to align continued statements at the '('. If false or the '(' is not +# followed by a newline, the next line indent is one tab. +# +# Default: true +indent_align_paren = true # true/false + +# (OC) Whether to indent Objective-C blocks at brace level instead of usual +# rules. +indent_oc_block = false # true/false + +# (OC) Indent for Objective-C blocks in a message relative to the parameter +# name. +# +# =0: Use indent_oc_block rules +# >0: Use specified number of spaces to indent +indent_oc_block_msg = 0 # unsigned number + +# (OC) Minimum indent for subsequent parameters +indent_oc_msg_colon = 0 # unsigned number + +# (OC) Whether to prioritize aligning with initial colon (and stripping spaces +# from lines, if necessary). +# +# Default: true +indent_oc_msg_prioritize_first_colon = true # true/false + +# (OC) Whether to indent blocks the way that Xcode does by default +# (from the keyword if the parameter is on its own line; otherwise, from the +# previous indentation level). Requires indent_oc_block_msg=true. +indent_oc_block_msg_xcode_style = false # true/false + +# (OC) Whether to indent blocks from where the brace is, relative to a +# message keyword. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_keyword = false # true/false + +# (OC) Whether to indent blocks from where the brace is, relative to a message +# colon. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_colon = false # true/false + +# (OC) Whether to indent blocks from where the block caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_caret = false # true/false + +# (OC) Whether to indent blocks from where the brace caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_brace = false # true/false + +# When indenting after virtual brace open and newline add further spaces to +# reach this minimum indent. +indent_min_vbrace_open = 0 # unsigned number + +# Whether to add further spaces after regular indent to reach next tabstop +# when identing after virtual brace open and newline. +indent_vbrace_open_on_tabstop = false # true/false + +# How to indent after a brace followed by another token (not a newline). +# true: indent all contained lines to match the token +# false: indent all contained lines to match the brace +# +# Default: true +indent_token_after_brace = true # true/false + +# Whether to indent the body of a C++11 lambda. +indent_cpp_lambda_body = true # true/false + +# (C#) Whether to indent a 'using' block if no braces are used. +# +# Default: true +indent_using_block = true # true/false + +# How to indent the continuation of ternary operator. +# +# 0: Off (default) +# 1: When the `if_false` is a continuation, indent it under `if_false` +# 2: When the `:` is a continuation, indent it under `?` +indent_ternary_operator = 0 # unsigned number + +# If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column. +indent_off_after_return_new = false # true/false + +# If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token. +indent_single_after_return = false # true/false + +# Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they +# have their own indentation). +indent_ignore_asm_block = false # true/false # # Newline adding and removing options # -# Whether to collapse empty blocks between '{' and '}' -nl_collapse_empty_body = false # false/true +# Whether to collapse empty blocks between '{' and '}'. +nl_collapse_empty_body = false # true/false -# Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' -nl_assign_leave_one_liners = true # false/true +# Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'. +nl_assign_leave_one_liners = true # true/false -# Don't split one-line braced statements inside a class xx { } body -nl_class_leave_one_liners = false # false/true +# Don't split one-line braced statements inside a 'class xx { }' body. +nl_class_leave_one_liners = false # true/false -# Don't split one-line enums: 'enum foo { BAR = 15 };' -nl_enum_leave_one_liners = true # false/true +# Don't split one-line enums, as in 'enum foo { BAR = 15 };' +nl_enum_leave_one_liners = true # true/false -# Don't split one-line get or set functions -nl_getset_leave_one_liners = false # false/true +# Don't split one-line get or set functions. +nl_getset_leave_one_liners = false # true/false -# Don't split one-line function definitions - 'int foo() { return 0; }' -nl_func_leave_one_liners = false # false/true +# (C#) Don't split one-line property get or set functions. +nl_cs_property_leave_one_liners = false # true/false -# Don't split one-line C++11 lambdas - '[]() { return 0; }' -nl_cpp_lambda_leave_one_liners = false # false/true +# Don't split one-line function definitions, as in 'int foo() { return 0; }'. +nl_func_leave_one_liners = false # true/false -# Don't split one-line if/else statements - 'if(a) b++;' -nl_if_leave_one_liners = false # false/true +# Don't split one-line C++11 lambdas, as in '[]() { return 0; }'. +nl_cpp_lambda_leave_one_liners = true # true/false -# Don't split one-line while statements - 'while(a) b++;' -nl_while_leave_one_liners = false # false/true +# Don't split one-line if/else statements, as in 'if(...) b++;'. +nl_if_leave_one_liners = false # true/false -# Don't split one-line OC messages -nl_oc_msg_leave_one_liner = false # false/true +# Don't split one-line while statements, as in 'while(...) b++;'. +nl_while_leave_one_liners = false # true/false -# Add or remove newline between Objective-C block signature and '{' +# Don't split one-line for statements, as in 'for(...) b++;'. +nl_for_leave_one_liners = false # true/false + +# (OC) Don't split one-line Objective-C messages. +nl_oc_msg_leave_one_liner = false # true/false + +# (OC) Add or remove newline between method declaration and '{'. +nl_oc_mdef_brace = ignore # ignore/add/remove/force + +# (OC) Add or remove newline between Objective-C block signature and '{'. nl_oc_block_brace = ignore # ignore/add/remove/force -# Add or remove newlines at the start of the file +# (OC) Add or remove newline between '@interface' and '{'. +nl_oc_interface_brace = ignore # ignore/add/remove/force + +# (OC) Add or remove newline between '@implementation' and '{'. +nl_oc_implementation_brace = ignore # ignore/add/remove/force + +# Add or remove newlines at the start of the file. nl_start_of_file = remove # ignore/add/remove/force -# The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' -nl_start_of_file_min = 0 # number +# The minimum number of newlines at the start of the file (only used if +# nl_start_of_file is 'add' or 'force'). +nl_start_of_file_min = 0 # unsigned number -# Add or remove newline at the end of the file -nl_end_of_file = add # ignore/add/remove/force +# Add or remove newline at the end of the file. +nl_end_of_file = force # ignore/add/remove/force -# The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') -nl_end_of_file_min = 1 # number +# The minimum number of newlines at the end of the file (only used if +# nl_end_of_file is 'add' or 'force'). +nl_end_of_file_min = 1 # unsigned number -# Add or remove newline between '=' and '{' +# Add or remove newline between '=' and '{'. nl_assign_brace = ignore # ignore/add/remove/force -# Add or remove newline between '=' and '[' (D only) +# (D) Add or remove newline between '=' and '['. nl_assign_square = ignore # ignore/add/remove/force -# Add or remove newline after '= [' (D only). Will also affect the newline before the ']' +# Add or remove newline between '[]' and '{'. +nl_tsquare_brace = ignore # ignore/add/remove/force + +# (D) Add or remove newline after '= ['. Will also affect the newline before +# the ']'. nl_after_square_assign = ignore # ignore/add/remove/force -# The number of blank lines after a block of variable definitions at the top of a function body -# 0 = No change (default) -nl_func_var_def_blk = 0 # number +# The number of blank lines after a block of variable definitions at the top +# of a function body. +# +# 0 = No change (default). +nl_func_var_def_blk = 0 # unsigned number -# The number of newlines before a block of typedefs -# 0 = No change (default) -# the option 'nl_after_access_spec' takes preference over 'nl_typedef_blk_start' -nl_typedef_blk_start = 0 # number +# The number of newlines before a block of typedefs. If nl_after_access_spec +# is non-zero, that option takes precedence. +# +# 0 = No change (default). +nl_typedef_blk_start = 0 # unsigned number -# The number of newlines after a block of typedefs -# 0 = No change (default) -nl_typedef_blk_end = 0 # number +# The number of newlines after a block of typedefs. +# +# 0 = No change (default). +nl_typedef_blk_end = 0 # unsigned number -# The maximum consecutive newlines within a block of typedefs -# 0 = No change (default) -nl_typedef_blk_in = 0 # number +# The maximum number of consecutive newlines within a block of typedefs. +# +# 0 = No change (default). +nl_typedef_blk_in = 0 # unsigned number -# The number of newlines before a block of variable definitions not at the top of a function body -# 0 = No change (default) -# the option 'nl_after_access_spec' takes preference over 'nl_var_def_blk_start' -nl_var_def_blk_start = 0 # number +# The number of newlines before a block of variable definitions not at the top +# of a function body. If nl_after_access_spec is non-zero, that option takes +# precedence. +# +# 0 = No change (default). +nl_var_def_blk_start = 0 # unsigned number -# The number of newlines after a block of variable definitions not at the top of a function body -# 0 = No change (default) -nl_var_def_blk_end = 0 # number +# The number of newlines after a block of variable definitions not at the top +# of a function body. +# +# 0 = No change (default). +nl_var_def_blk_end = 0 # unsigned number -# The maximum consecutive newlines within a block of variable definitions -# 0 = No change (default) -nl_var_def_blk_in = 0 # number +# The maximum number of consecutive newlines within a block of variable +# definitions. +# +# 0 = No change (default). +nl_var_def_blk_in = 0 # unsigned number -# Add or remove newline between a function call's ')' and '{', as in: -# list_for_each(item, &list) { } +# Add or remove newline between a function call's ')' and '{', as in +# 'list_for_each(item, &list) { }'. nl_fcall_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'enum' and '{' -nl_enum_brace = add # ignore/add/remove/force +# Add or remove newline between 'enum' and '{'. +nl_enum_brace = force # ignore/add/remove/force -# Add or remove newline between 'struct and '{' -nl_struct_brace = add # ignore/add/remove/force +# Add or remove newline between 'enum' and 'class'. +nl_enum_class = ignore # ignore/add/remove/force -# Add or remove newline between 'union' and '{' -nl_union_brace = add # ignore/add/remove/force +# Add or remove newline between 'enum class' and the identifier. +nl_enum_class_identifier = ignore # ignore/add/remove/force -# Add or remove newline between 'if' and '{' -nl_if_brace = add # ignore/add/remove/force +# Add or remove newline between 'enum class' type and ':'. +nl_enum_identifier_colon = ignore # ignore/add/remove/force -# Add or remove newline between '}' and 'else' -nl_brace_else = add # ignore/add/remove/force +# Add or remove newline between 'enum class identifier :' and type. +nl_enum_colon_type = ignore # ignore/add/remove/force -# Add or remove newline between 'else if' and '{' -# If set to ignore, nl_if_brace is used instead +# Add or remove newline between 'struct and '{'. +nl_struct_brace = force # ignore/add/remove/force + +# Add or remove newline between 'union' and '{'. +nl_union_brace = force # ignore/add/remove/force + +# Add or remove newline between 'if' and '{'. +nl_if_brace = force # ignore/add/remove/force + +# Add or remove newline between '}' and 'else'. +nl_brace_else = force # ignore/add/remove/force + +# Add or remove newline between 'else if' and '{'. If set to ignore, +# nl_if_brace is used instead. nl_elseif_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'else' and '{' -nl_else_brace = add # ignore/add/remove/force +# Add or remove newline between 'else' and '{'. +nl_else_brace = force # ignore/add/remove/force -# Add or remove newline between 'else' and 'if' -nl_else_if = ignore # ignore/add/remove/force +# Add or remove newline between 'else' and 'if'. +nl_else_if = remove # ignore/add/remove/force -# Add or remove newline between '}' and 'finally' +# Add or remove newline before 'if'/'else if' closing parenthesis. +nl_before_if_closing_paren = ignore # ignore/add/remove/force + +# Add or remove newline between '}' and 'finally'. nl_brace_finally = ignore # ignore/add/remove/force -# Add or remove newline between 'finally' and '{' +# Add or remove newline between 'finally' and '{'. nl_finally_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'try' and '{' -nl_try_brace = add # ignore/add/remove/force +# Add or remove newline between 'try' and '{'. +nl_try_brace = force # ignore/add/remove/force -# Add or remove newline between get/set and '{' +# Add or remove newline between get/set and '{'. nl_getset_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'for' and '{' -nl_for_brace = add # ignore/add/remove/force +# Add or remove newline between 'for' and '{'. +nl_for_brace = force # ignore/add/remove/force -# Add or remove newline between 'catch' and '{' -nl_catch_brace = add # ignore/add/remove/force +# Add or remove newline before the '{' of a 'catch' statement, as in +# 'catch (decl) {'. +nl_catch_brace = force # ignore/add/remove/force -# Add or remove newline between '}' and 'catch' -nl_brace_catch = add # ignore/add/remove/force +# (OC) Add or remove newline before the '{' of a '@catch' statement, as in +# '@catch (decl) {'. If set to ignore, nl_catch_brace is used. +nl_oc_catch_brace = ignore # ignore/add/remove/force -# Add or remove newline between '}' and ']' +# Add or remove newline between '}' and 'catch'. +nl_brace_catch = force # ignore/add/remove/force + +# (OC) Add or remove newline between '}' and '@catch'. If set to ignore, +# nl_brace_catch is used. +nl_oc_brace_catch = ignore # ignore/add/remove/force + +# Add or remove newline between '}' and ']'. nl_brace_square = ignore # ignore/add/remove/force -# Add or remove newline between '}' and ')' in a function invocation +# Add or remove newline between '}' and ')' in a function invocation. nl_brace_fparen = ignore # ignore/add/remove/force -# Add or remove newline between 'while' and '{' -nl_while_brace = add # ignore/add/remove/force +# Add or remove newline between 'while' and '{'. +nl_while_brace = force # ignore/add/remove/force -# Add or remove newline between 'scope (x)' and '{' (D) +# (D) Add or remove newline between 'scope (x)' and '{'. nl_scope_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'unittest' and '{' (D) +# (D) Add or remove newline between 'unittest' and '{'. nl_unittest_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'version (x)' and '{' (D) +# (D) Add or remove newline between 'version (x)' and '{'. nl_version_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'using' and '{' +# (C#) Add or remove newline between 'using' and '{'. nl_using_brace = ignore # ignore/add/remove/force -# Add or remove newline between two open or close braces. -# Due to general newline/brace handling, REMOVE may not work. +# Add or remove newline between two open or close braces. Due to general +# newline/brace handling, REMOVE may not work. nl_brace_brace = ignore # ignore/add/remove/force -# Add or remove newline between 'do' and '{' -nl_do_brace = add # ignore/add/remove/force +# Add or remove newline between 'do' and '{'. +nl_do_brace = force # ignore/add/remove/force -# Add or remove newline between '}' and 'while' of 'do' statement -nl_brace_while = add # ignore/add/remove/force +# Add or remove newline between '}' and 'while' of 'do' statement. +nl_brace_while = force # ignore/add/remove/force -# Add or remove newline between 'switch' and '{' -nl_switch_brace = add # ignore/add/remove/force +# Add or remove newline between 'switch' and '{'. +nl_switch_brace = force # ignore/add/remove/force -# Add or remove newline between 'synchronized' and '{' +# Add or remove newline between 'synchronized' and '{'. nl_synchronized_brace = ignore # ignore/add/remove/force -# Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. -# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and nl_catch_brace. -nl_multi_line_cond = false # false/true +# Add a newline between ')' and '{' if the ')' is on a different line than the +# if/for/etc. +# +# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and +# nl_catch_brace. +nl_multi_line_cond = false # true/false # Force a newline in a define after the macro name for multi-line defines. -nl_multi_line_define = false # false/true +nl_multi_line_define = false # true/false -# Whether to put a newline before 'case' statement, not after the first 'case' -nl_before_case = false # false/true +# Whether to add a newline before 'case', and a blank line before a 'case' +# statement that follows a ';' or '}'. +nl_before_case = false # true/false -# Add or remove newline between ')' and 'throw' -nl_before_throw = ignore # ignore/add/remove/force +# Whether to add a newline after a 'case' statement. +nl_after_case = false # true/false -# Whether to put a newline after 'case' statement -nl_after_case = false # false/true - -# Add or remove a newline between a case ':' and '{'. Overrides nl_after_case. +# Add or remove newline between a case ':' and '{'. +# +# Overrides nl_after_case. nl_case_colon_brace = ignore # ignore/add/remove/force -# Newline between namespace and { -nl_namespace_brace = add # ignore/add/remove/force +# Add or remove newline between ')' and 'throw'. +nl_before_throw = ignore # ignore/add/remove/force + +# Add or remove newline between 'namespace' and '{'. +nl_namespace_brace = force # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. -nl_template_class = add # ignore/add/remove/force +nl_template_class = force # ignore/add/remove/force -# Add or remove newline between 'class' and '{' -nl_class_brace = add # ignore/add/remove/force +# Add or remove newline between 'class' and '{'. +nl_class_brace = force # ignore/add/remove/force -# Add or remove newline before/after each ',' in the base class list, -# (tied to pos_class_comma). +# Add or remove newline before or after (depending on pos_class_comma) each +# ',' in the base class list. nl_class_init_args = ignore # ignore/add/remove/force -# Add or remove newline after each ',' in the constructor member initialization. -# Related to nl_constr_colon, pos_constr_colon and pos_constr_comma. +# Add or remove newline after each ',' in the constructor member +# initialization. Related to nl_constr_colon, pos_constr_colon and +# pos_constr_comma. nl_constr_init_args = ignore # ignore/add/remove/force -# Add or remove newline before first element, after comma, and after last element in enum +# Add or remove newline before first element, after comma, and after last +# element, in 'enum'. nl_enum_own_lines = ignore # ignore/add/remove/force -# Add or remove newline between return type and function name in a function definition -nl_func_type_name = add # ignore/add/remove/force +# Add or remove newline between return type and function name in a function +# definition. +nl_func_type_name = force # ignore/add/remove/force -# Add or remove newline between return type and function name inside a class {} -# Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. +# Add or remove newline between return type and function name inside a class +# definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name +# is used instead. nl_func_type_name_class = ignore # ignore/add/remove/force -# Add or remove newline between class specification and '::' in 'void A::f() { }' -# Only appears in separate member implementation (does not appear with in-line implmementation) +# Add or remove newline between class specification and '::' +# in 'void A::f() { }'. Only appears in separate member implementation (does +# not appear with in-line implementation). nl_func_class_scope = ignore # ignore/add/remove/force -# Add or remove newline between function scope and name -# Controls the newline after '::' in 'void A::f() { }' +# Add or remove newline between function scope and name, as in +# 'void A :: f() { }'. nl_func_scope_name = ignore # ignore/add/remove/force -# Add or remove newline between return type and function name in a prototype +# Add or remove newline between return type and function name in a prototype. nl_func_proto_type_name = remove # ignore/add/remove/force -# Add or remove newline between a function name and the opening '(' in the declaration +# Add or remove newline between a function name and the opening '(' in the +# declaration. nl_func_paren = remove # ignore/add/remove/force -# Add or remove newline between a function name and the opening '(' in the definition +# Overrides nl_func_paren for functions with no parameters. +nl_func_paren_empty = ignore # ignore/add/remove/force + +# Add or remove newline between a function name and the opening '(' in the +# definition. nl_func_def_paren = ignore # ignore/add/remove/force -# Add or remove newline after '(' in a function declaration +# Overrides nl_func_def_paren for functions with no parameters. +nl_func_def_paren_empty = ignore # ignore/add/remove/force + +# Add or remove newline between a function name and the opening '(' in the +# call. +nl_func_call_paren = ignore # ignore/add/remove/force + +# Overrides nl_func_call_paren for functions with no parameters. +nl_func_call_paren_empty = ignore # ignore/add/remove/force + +# Add or remove newline after '(' in a function declaration. nl_func_decl_start = remove # ignore/add/remove/force -# Add or remove newline after '(' in a function definition +# Add or remove newline after '(' in a function definition. nl_func_def_start = ignore # ignore/add/remove/force # Overrides nl_func_decl_start when there is only one parameter. @@ -1280,28 +1541,32 @@ nl_func_decl_start_single = ignore # ignore/add/remove/force # Overrides nl_func_def_start when there is only one parameter. nl_func_def_start_single = ignore # ignore/add/remove/force -# Whether to add newline after '(' in a function declaration if '(' and ')' are in different lines. -nl_func_decl_start_multi_line = false # false/true +# Whether to add a newline after '(' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_start is used instead. +nl_func_decl_start_multi_line = false # true/false -# Whether to add newline after '(' in a function definition if '(' and ')' are in different lines. -nl_func_def_start_multi_line = false # false/true +# Whether to add a newline after '(' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_start is used instead. +nl_func_def_start_multi_line = false # true/false -# Add or remove newline after each ',' in a function declaration +# Add or remove newline after each ',' in a function declaration. nl_func_decl_args = ignore # ignore/add/remove/force -# Add or remove newline after each ',' in a function definition +# Add or remove newline after each ',' in a function definition. nl_func_def_args = ignore # ignore/add/remove/force -# Whether to add newline after each ',' in a function declaration if '(' and ')' are in different lines. -nl_func_decl_args_multi_line = false # false/true +# Whether to add a newline after each ',' in a function declaration if '(' +# and ')' are in different lines. If false, nl_func_decl_args is used instead. +nl_func_decl_args_multi_line = false # true/false -# Whether to add newline after each ',' in a function definition if '(' and ')' are in different lines. -nl_func_def_args_multi_line = false # false/true +# Whether to add a newline after each ',' in a function definition if '(' +# and ')' are in different lines. If false, nl_func_def_args is used instead. +nl_func_def_args_multi_line = false # true/false -# Add or remove newline before the ')' in a function declaration +# Add or remove newline before the ')' in a function declaration. nl_func_decl_end = ignore # ignore/add/remove/force -# Add or remove newline before the ')' in a function definition +# Add or remove newline before the ')' in a function definition. nl_func_def_end = ignore # ignore/add/remove/force # Overrides nl_func_decl_end when there is only one parameter. @@ -1310,11 +1575,13 @@ nl_func_decl_end_single = ignore # ignore/add/remove/force # Overrides nl_func_def_end when there is only one parameter. nl_func_def_end_single = ignore # ignore/add/remove/force -# Whether to add newline before ')' in a function declaration if '(' and ')' are in different lines. -nl_func_decl_end_multi_line = false # false/true +# Whether to add a newline before ')' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_end is used instead. +nl_func_decl_end_multi_line = false # true/false -# Whether to add newline before ')' in a function definition if '(' and ')' are in different lines. -nl_func_def_end_multi_line = false # false/true +# Whether to add a newline before ')' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_end is used instead. +nl_func_def_end_multi_line = false # true/false # Add or remove newline between '()' in a function declaration. nl_func_decl_empty = ignore # ignore/add/remove/force @@ -1322,640 +1589,1148 @@ nl_func_decl_empty = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function definition. nl_func_def_empty = ignore # ignore/add/remove/force -# Whether to add newline after '(' in a function call if '(' and ')' are in different lines. -nl_func_call_start_multi_line = false # false/true +# Add or remove newline between '()' in a function call. +nl_func_call_empty = ignore # ignore/add/remove/force -# Whether to add newline after each ',' in a function call if '(' and ')' are in different lines. -nl_func_call_args_multi_line = false # false/true +# Whether to add a newline after '(' in a function call if '(' and ')' are in +# different lines. +nl_func_call_start_multi_line = false # true/false -# Whether to add newline before ')' in a function call if '(' and ')' are in different lines. -nl_func_call_end_multi_line = false # false/true +# Whether to add a newline after each ',' in a function call if '(' and ')' +# are in different lines. +nl_func_call_args_multi_line = false # true/false -# Whether to put each OC message parameter on a separate line -# See nl_oc_msg_leave_one_liner -nl_oc_msg_args = false # false/true +# Whether to add a newline before ')' in a function call if '(' and ')' are in +# different lines. +nl_func_call_end_multi_line = false # true/false -# Add or remove newline between function signature and '{' -nl_fdef_brace = add # ignore/add/remove/force +# (OC) Whether to put each Objective-C message parameter on a separate line. +# See nl_oc_msg_leave_one_liner. +nl_oc_msg_args = false # true/false -# Add or remove newline between C++11 lambda signature and '{' +# Add or remove newline between function signature and '{'. +nl_fdef_brace = force # ignore/add/remove/force + +# Add or remove newline between C++11 lambda signature and '{'. nl_cpp_ldef_brace = ignore # ignore/add/remove/force -# Add or remove a newline between the return keyword and return expression. -nl_return_expr = ignore # ignore/add/remove/force +# Add or remove newline between 'return' and the return expression. +nl_return_expr = remove # ignore/add/remove/force -# Whether to put a newline after semicolons, except in 'for' statements -nl_after_semicolon = false # false/true +# Whether to add a newline after semicolons, except in 'for' statements. +nl_after_semicolon = false # true/false -# Java: Control the newline between the ')' and '{{' of the double brace initializer. +# (Java) Add or remove newline between the ')' and '{{' of the double brace +# initializer. nl_paren_dbrace_open = ignore # ignore/add/remove/force -# Whether to put a newline after brace open. -# This also adds a newline before the matching brace close. -nl_after_brace_open = false # false/true +# Whether to add a newline after the type in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst = ignore # ignore/add/remove/force -# If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is -# placed between the open brace and a trailing single-line comment. -nl_after_brace_open_cmt = false # false/true +# Whether to add a newline after the open brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_open = ignore # ignore/add/remove/force -# Whether to put a newline after a virtual brace open with a non-empty body. +# Whether to add a newline before the close brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_close = ignore # ignore/add/remove/force + +# Whether to add a newline after '{'. This also adds a newline before the +# matching '}'. +nl_after_brace_open = false # true/false + +# Whether to add a newline between the open brace and a trailing single-line +# comment. Requires nl_after_brace_open=true. +nl_after_brace_open_cmt = false # true/false + +# Whether to add a newline after a virtual brace open with a non-empty body. # These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open = false # false/true +nl_after_vbrace_open = false # true/false -# Whether to put a newline after a virtual brace open with an empty body. +# Whether to add a newline after a virtual brace open with an empty body. # These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open_empty = false # false/true +nl_after_vbrace_open_empty = false # true/false -# Whether to put a newline after a brace close. -# Does not apply if followed by a necessary ';'. -nl_after_brace_close = false # false/true +# Whether to add a newline after '}'. Does not apply if followed by a +# necessary ';'. +nl_after_brace_close = false # true/false -# Whether to put a newline after a virtual brace close. -# Would add a newline before return in: 'if (foo) a++; return;' -nl_after_vbrace_close = false # false/true +# Whether to add a newline after a virtual brace close, +# as in 'if (foo) a++; return;'. +nl_after_vbrace_close = false # true/false -# Control the newline between the close brace and 'b' in: 'struct { int a; } b;' -# Affects enums, unions and structures. If set to ignore, uses nl_after_brace_close +# Add or remove newline between the close brace and identifier, +# as in 'struct { int a; } b;'. Affects enumerations, unions and +# structures. If set to ignore, uses nl_after_brace_close. nl_brace_struct_var = ignore # ignore/add/remove/force -# Whether to alter newlines in '#define' macros -nl_define_macro = false # false/true +# Whether to alter newlines in '#define' macros. +nl_define_macro = false # true/false -# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and '#endif'. Does not affect top-level #ifdefs. -nl_squeeze_ifdef = false # false/true +# Whether to alter newlines between consecutive parenthesis closes. The number +# of closing parentheses in a line will depend on respective open parenthesis +# lines. +nl_squeeze_paren_close = false # true/false + +# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and +# '#endif'. Does not affect top-level #ifdefs. +nl_squeeze_ifdef = false # true/false # Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. -nl_squeeze_ifdef_top_level = false # false/true +nl_squeeze_ifdef_top_level = false # true/false -# Add or remove blank line before 'if' +# Add or remove blank line before 'if'. nl_before_if = ignore # ignore/add/remove/force -# Add or remove blank line after 'if' statement +# Add or remove blank line after 'if' statement. Add/Force work only if the +# next token is not a closing brace. nl_after_if = ignore # ignore/add/remove/force -# Add or remove blank line before 'for' +# Add or remove blank line before 'for'. nl_before_for = ignore # ignore/add/remove/force -# Add or remove blank line after 'for' statement +# Add or remove blank line after 'for' statement. nl_after_for = ignore # ignore/add/remove/force -# Add or remove blank line before 'while' +# Add or remove blank line before 'while'. nl_before_while = ignore # ignore/add/remove/force -# Add or remove blank line after 'while' statement +# Add or remove blank line after 'while' statement. nl_after_while = ignore # ignore/add/remove/force -# Add or remove blank line before 'switch' +# Add or remove blank line before 'switch'. nl_before_switch = ignore # ignore/add/remove/force -# Add or remove blank line after 'switch' statement +# Add or remove blank line after 'switch' statement. nl_after_switch = ignore # ignore/add/remove/force -# Add or remove blank line before 'synchronized' +# Add or remove blank line before 'synchronized'. nl_before_synchronized = ignore # ignore/add/remove/force -# Add or remove blank line after 'synchronized' statement +# Add or remove blank line after 'synchronized' statement. nl_after_synchronized = ignore # ignore/add/remove/force -# Add or remove blank line before 'do' +# Add or remove blank line before 'do'. nl_before_do = ignore # ignore/add/remove/force -# Add or remove blank line after 'do/while' statement +# Add or remove blank line after 'do/while' statement. nl_after_do = ignore # ignore/add/remove/force -# Whether to double-space commented-entries in struct/union/enum -nl_ds_struct_enum_cmt = false # false/true +# Whether to double-space commented-entries in 'struct'/'union'/'enum'. +nl_ds_struct_enum_cmt = false # true/false -# force nl before } of a struct/union/enum -# (lower priority than 'eat_blanks_before_close_brace') -nl_ds_struct_enum_close_brace = false # false/true +# Whether to force a newline before '}' of a 'struct'/'union'/'enum'. +# (Lower priority than eat_blanks_before_close_brace.) +nl_ds_struct_enum_close_brace = false # true/false -# Add or remove blank line before 'func_class_def' -nl_before_func_class_def = 0 # number - -# Add or remove blank line before 'func_class_proto' -nl_before_func_class_proto = 0 # number - -# Add or remove a newline before/after a class colon, -# (tied to pos_class_colon). +# Add or remove newline before or after (depending on pos_class_colon) a class +# colon, as in 'class Foo : public Bar'. nl_class_colon = ignore # ignore/add/remove/force -# Add or remove a newline around a class constructor colon. -# Related to nl_constr_init_args, pos_constr_colon and pos_constr_comma. +# Add or remove newline around a class constructor colon. The exact position +# depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma. nl_constr_colon = ignore # ignore/add/remove/force -# Change simple unbraced if statements into a one-liner -# 'if(b)\n i++;' => 'if(b) i++;' -nl_create_if_one_liner = false # false/true +# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }' +# into a single line. If true, prevents other brace newline rules from turning +# such code into four lines. +nl_namespace_two_to_one_liner = false # true/false -# Change simple unbraced for statements into a one-liner -# 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' -nl_create_for_one_liner = false # false/true +# Whether to remove a newline in simple unbraced if statements, turning them +# into one-liners, as in 'if(b)\n i++;' → 'if(b) i++;'. +nl_create_if_one_liner = false # true/false -# Change simple unbraced while statements into a one-liner -# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' -nl_create_while_one_liner = false # false/true +# Whether to remove a newline in simple unbraced for statements, turning them +# into one-liners, as in 'for (...)\n stmt;' → 'for (...) stmt;'. +nl_create_for_one_liner = false # true/false -# Change a one-liner if statement into simple unbraced if -# 'if(b) i++;' => 'if(b) i++;' -nl_split_if_one_liner = false # false/true +# Whether to remove a newline in simple unbraced while statements, turning +# them into one-liners, as in 'while (expr)\n stmt;' → 'while (expr) stmt;'. +nl_create_while_one_liner = false # true/false -# Change a one-liner for statement into simple unbraced for -# 'for (i=0;<5;i++) foo(i);' => 'for (i=0;<5;i++) foo(i);' -nl_split_for_one_liner = false # false/true +# Whether to collapse a function definition whose body (not counting braces) +# is only one line so that the entire definition (prototype, braces, body) is +# a single line. +nl_create_func_def_one_liner = false # true/false -# Change simple unbraced while statements into a one-liner while -# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' -nl_split_while_one_liner = false # false/true +# Whether to split one-line simple unbraced if statements into two lines by +# adding a newline, as in 'if(b) i++;'. +nl_split_if_one_liner = false # true/false -# -# Positioning options -# +# Whether to split one-line simple unbraced for statements into two lines by +# adding a newline, as in 'for (...) stmt;'. +nl_split_for_one_liner = false # true/false -# The position of arithmetic operators in wrapped expressions -pos_arith = lead # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of assignment in wrapped expressions. -# Do not affect '=' followed by '{' -pos_assign = lead # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of boolean operators in wrapped expressions -pos_bool = lead # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of comparison operators in wrapped expressions -pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of conditional (b ? t : f) operators in wrapped expressions -pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of the comma in wrapped expressions -pos_comma = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of the comma in enum entries -pos_enum_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of the comma in the base class list if there are more than one line, -# (tied to nl_class_init_args). -pos_class_comma = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of the comma in the constructor initialization list. -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. -pos_constr_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of trailing/leading class colon, between class and base class list -# (tied to nl_class_colon). -pos_class_colon = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# The position of colons between constructor and member initialization, -# (tied to UO_nl_constr_colon). -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. -pos_constr_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force - -# -# Line Splitting options -# - -# Try to limit code width to N number of columns -code_width = 0 # number - -# Whether to fully split long 'for' statements at semi-colons -ls_for_split_full = false # false/true - -# Whether to fully split long function protos/calls at commas -ls_func_split_full = false # false/true - -# Whether to split lines as close to code_width as possible and ignore some groupings -ls_code_width = false # false/true +# Whether to split one-line simple unbraced while statements into two lines by +# adding a newline, as in 'while (expr) stmt;'. +nl_split_while_one_liner = false # true/false # # Blank line options # -# The maximum consecutive newlines (3 = 2 blank lines) -nl_max = 2 # number +# The maximum number of consecutive newlines (3 = 2 blank lines). +nl_max = 2 # unsigned number -# The number of newlines after a function prototype, if followed by another function prototype -nl_after_func_proto = 0 # number +# The maximum number of consecutive newlines in a function. +nl_max_blank_in_func = 0 # unsigned number -# The number of newlines after a function prototype, if not followed by another function prototype -nl_after_func_proto_group = 0 # number +# The number of newlines before a function prototype. +nl_before_func_body_proto = 0 # unsigned number -# The number of newlines after a function class prototype, if followed by another function class prototype -nl_after_func_class_proto = 0 # number +# The number of newlines before a multi-line function definition. +nl_before_func_body_def = 0 # unsigned number -# The number of newlines after a function class prototype, if not followed by another function class prototype -nl_after_func_class_proto_group = 0 # number +# The number of newlines before a class constructor/destructor prototype. +nl_before_func_class_proto = 0 # unsigned number -# The number of newlines before a multi-line function def body -nl_before_func_body_def = 0 # number +# The number of newlines before a class constructor/destructor definition. +nl_before_func_class_def = 0 # unsigned number -# The number of newlines before a multi-line function prototype body -nl_before_func_body_proto = 0 # number +# The number of newlines after a function prototype. +nl_after_func_proto = 0 # unsigned number -# The number of newlines after '}' of a multi-line function body -nl_after_func_body = 0 # number +# The number of newlines after a function prototype, if not followed by +# another function prototype. +nl_after_func_proto_group = 0 # unsigned number -# The number of newlines after '}' of a multi-line function body in a class declaration -nl_after_func_body_class = 0 # number +# The number of newlines after a class constructor/destructor prototype. +nl_after_func_class_proto = 0 # unsigned number -# The number of newlines after '}' of a single line function body -nl_after_func_body_one_liner = 0 # number +# The number of newlines after a class constructor/destructor prototype, +# if not followed by another constructor/destructor prototype. +nl_after_func_class_proto_group = 0 # unsigned number + +# Whether one-line method definitions inside a class body should be treated +# as if they were prototypes for the purposes of adding newlines. +# +# Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def +# and nl_before_func_class_def for one-liners. +nl_class_leave_one_liner_groups = false # true/false + +# The number of newlines after '}' of a multi-line function body. +nl_after_func_body = 0 # unsigned number + +# The number of newlines after '}' of a multi-line function body in a class +# declaration. Also affects class constructors/destructors. +# +# Overrides nl_after_func_body. +nl_after_func_body_class = 0 # unsigned number + +# The number of newlines after '}' of a single line function body. Also +# affects class constructors/destructors. +# +# Overrides nl_after_func_body and nl_after_func_body_class. +nl_after_func_body_one_liner = 0 # unsigned number # The minimum number of newlines before a multi-line comment. # Doesn't apply if after a brace open or another multi-line comment. -nl_before_block_comment = 0 # number +nl_before_block_comment = 0 # unsigned number # The minimum number of newlines before a single-line C comment. # Doesn't apply if after a brace open or other single-line C comments. -nl_before_c_comment = 0 # number +nl_before_c_comment = 0 # unsigned number # The minimum number of newlines before a CPP comment. # Doesn't apply if after a brace open or other CPP comments. -nl_before_cpp_comment = 0 # number +nl_before_cpp_comment = 0 # unsigned number # Whether to force a newline after a multi-line comment. -nl_after_multiline_comment = false # false/true +nl_after_multiline_comment = false # true/false # Whether to force a newline after a label's colon. -nl_after_label_colon = false # false/true +nl_after_label_colon = false # true/false -# The number of newlines after '}' or ';' of a struct/enum/union definition -nl_after_struct = 0 # number +# The number of newlines after '}' or ';' of a struct/enum/union definition. +nl_after_struct = 0 # unsigned number -# The number of newlines before a class definition -nl_before_class = 0 # number +# The number of newlines before a class definition. +nl_before_class = 0 # unsigned number -# The number of newlines after '}' or ';' of a class definition -nl_after_class = 0 # number +# The number of newlines after '}' or ';' of a class definition. +nl_after_class = 0 # unsigned number -# The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. -# Will not change the newline count if after a brace open. -# 0 = No change. -nl_before_access_spec = 0 # number +# The number of newlines before an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0 = No change (default). +nl_before_access_spec = 0 # unsigned number -# The number of newlines after a 'private:', 'public:', 'protected:', 'signals:' or 'slots:' label. -# 0 = No change. -# the option 'nl_after_access_spec' takes preference over 'nl_typedef_blk_start' and 'nl_var_def_blk_start' -nl_after_access_spec = 0 # number +# The number of newlines after an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0 = No change (default). +# +# Overrides nl_typedef_blk_start and nl_var_def_blk_start. +nl_after_access_spec = 0 # unsigned number -# The number of newlines between a function def and the function comment. -# 0 = No change. -nl_comment_func_def = 0 # number +# The number of newlines between a function definition and the function +# comment, as in '// comment\n void foo() {...}'. +# +# 0 = No change (default). +nl_comment_func_def = 0 # unsigned number -# The number of newlines after a try-catch-finally block that isn't followed by a brace close. -# 0 = No change. -nl_after_try_catch_finally = 0 # number +# The number of newlines after a try-catch-finally block that isn't followed +# by a brace close. +# +# 0 = No change (default). +nl_after_try_catch_finally = 0 # unsigned number -# The number of newlines before and after a property, indexer or event decl. -# 0 = No change. -nl_around_cs_property = 0 # number +# (C#) The number of newlines before and after a property, indexer or event +# declaration. +# +# 0 = No change (default). +nl_around_cs_property = 0 # unsigned number -# The number of newlines between the get/set/add/remove handlers in C#. -# 0 = No change. -nl_between_get_set = 0 # number +# (C#) The number of newlines between the get/set/add/remove handlers. +# +# 0 = No change (default). +nl_between_get_set = 0 # unsigned number -# Add or remove newline between C# property and the '{' +# (C#) Add or remove newline between property and the '{'. nl_property_brace = ignore # ignore/add/remove/force -# Whether to remove blank lines after '{' -eat_blanks_after_open_brace = false # false/true +# The number of newlines after '{' of a namespace. This also adds newlines +# before the matching '}'. +# +# 0 = Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if +# applicable, otherwise no change. +# +# Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace. +nl_inside_namespace = 0 # unsigned number -# Whether to remove blank lines before '}' -eat_blanks_before_close_brace = false # false/true +# Whether to remove blank lines after '{'. +eat_blanks_after_open_brace = false # true/false -# How aggressively to remove extra newlines not in preproc. -# 0: No change +# Whether to remove blank lines before '}'. +eat_blanks_before_close_brace = false # true/false + +# How aggressively to remove extra newlines not in preprocessor. +# +# 0: No change (default) # 1: Remove most newlines not handled by other config # 2: Remove all newlines and reformat completely by config -nl_remove_extra_newlines = 0 # number +nl_remove_extra_newlines = 0 # unsigned number -# Whether to put a blank line before 'return' statements, unless after an open brace. -nl_before_return = false # false/true +# Whether to put a blank line before 'return' statements, unless after an open +# brace. +nl_before_return = false # true/false -# Whether to put a blank line after 'return' statements, unless followed by a close brace. -nl_after_return = false # false/true +# Whether to put a blank line after 'return' statements, unless followed by a +# close brace. +nl_after_return = false # true/false -# Whether to put a newline after a Java annotation statement. -# Only affects annotations that are after a newline. +# (Java) Add or remove newline after an annotation statement. Only affects +# annotations that are after a newline. nl_after_annotation = ignore # ignore/add/remove/force -# Controls the newline between two annotations. +# (Java) Add or remove newline between two annotations. nl_between_annotation = ignore # ignore/add/remove/force +# +# Positioning options +# + +# The position of arithmetic operators in wrapped expressions. +pos_arith = lead # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of assignment in wrapped expressions. Do not affect '=' +# followed by '{'. +pos_assign = lead # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of Boolean operators in wrapped expressions. +pos_bool = lead # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of comparison operators in wrapped expressions. +pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of conditional operators, as in the '?' and ':' of +# 'expr ? stmt : stmt', in wrapped expressions. +pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in wrapped expressions. +pos_comma = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in enum entries. +pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the base class list if there is more than one +# line. Affects nl_class_init_args. +pos_class_comma = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the constructor initialization list. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. +pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of trailing/leading class colon, between class and base class +# list. Affects nl_class_colon. +pos_class_colon = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of colons between constructor and member initialization. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. +pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# +# Line splitting options +# + +# Try to limit code width to N columns. +code_width = 0 # unsigned number + +# Whether to fully split long 'for' statements at semi-colons. +ls_for_split_full = false # true/false + +# Whether to fully split long function prototypes/calls at commas. +ls_func_split_full = false # true/false + +# Whether to split lines as close to code_width as possible and ignore some +# groupings. +ls_code_width = false # true/false + +# +# Code alignment options (not left column spaces/tabs) +# + +# Whether to keep non-indenting tabs. +align_keep_tabs = false # true/false + +# Whether to use tabs for aligning. +align_with_tabs = false # true/false + +# Whether to bump out to the next tab when aligning. +align_on_tabstop = false # true/false + +# Whether to right-align numbers. +align_number_right = false # true/false + +# Whether to keep whitespace not required for alignment. +align_keep_extra_space = false # true/false + +# Whether to align variable definitions in prototypes and functions. +align_func_params = false # true/false + +# The span for aligning parameter definitions in function on parameter name. +# +# 0 = Don't align (default). +align_func_params_span = 0 # unsigned number + +# The threshold for aligning function parameter definitions. +# +# 0 = No limit (default). +align_func_params_thresh = 0 # unsigned number + +# The gap for aligning function parameter definitions. +align_func_params_gap = 0 # unsigned number + +# Whether to align parameters in single-line functions that have the same +# name. The function names must already be aligned with each other. +align_same_func_call_params = false # true/false + +# The span for aligning function-call parameters for single line functions. +# +# 0 = Don't align (default). +align_same_func_call_params_span = 0 # unsigned number + +# The threshold for aligning function-call parameters for single line +# functions. +# +# 0 = No limit (default). +align_same_func_call_params_thresh = 0 # unsigned number + +# The span for aligning variable definitions. +# +# 0 = Don't align (default). +align_var_def_span = 0 # unsigned number + +# How to align the '*' in variable definitions. +# +# 0: Part of the type 'void * foo;' (default) +# 1: Part of the variable 'void *foo;' +# 2: Dangling 'void *foo;' +align_var_def_star_style = 0 # unsigned number + +# How to align the '&' in variable definitions. +# +# 0: Part of the type 'long & foo;' (default) +# 1: Part of the variable 'long &foo;' +# 2: Dangling 'long &foo;' +align_var_def_amp_style = 0 # unsigned number + +# The threshold for aligning variable definitions. +# +# 0 = No limit (default). +align_var_def_thresh = 0 # unsigned number + +# The gap for aligning variable definitions. +align_var_def_gap = 0 # unsigned number + +# Whether to align the colon in struct bit fields. +align_var_def_colon = false # true/false + +# The gap for aligning the colon in struct bit fields. +align_var_def_colon_gap = 0 # unsigned number + +# Whether to align any attribute after the variable name. +align_var_def_attribute = false # true/false + +# Whether to align inline struct/enum/union variable definitions. +align_var_def_inline = false # true/false + +# The span for aligning on '=' in assignments. +# +# 0 = Don't align (default). +align_assign_span = 0 # unsigned number + +# The threshold for aligning on '=' in assignments. +# +# 0 = No limit (default). +align_assign_thresh = 0 # unsigned number + +# How to apply align_assign_span to function declaration "assignments", i.e. +# 'virtual void foo() = 0' or '~foo() = {default|delete}'. +# +# 0: Align with other assignments (default) +# 1: Align with each other, ignoring regular assignments +# 2: Don't align +align_assign_decl_func = 0 # unsigned number + +# The span for aligning on '=' in enums. +# +# 0 = Don't align (default). +align_enum_equ_span = 0 # unsigned number + +# The threshold for aligning on '=' in enums. +# +# 0 = no limit (default). +align_enum_equ_thresh = 0 # unsigned number + +# The span for aligning class member definitions. +# +# 0 = Don't align (default). +align_var_class_span = 0 # unsigned number + +# The threshold for aligning class member definitions. +# +# 0 = No limit (default). +align_var_class_thresh = 0 # unsigned number + +# The gap for aligning class member definitions. +align_var_class_gap = 0 # unsigned number + +# The span for aligning struct/union member definitions. +# +# 0 = Don't align (default). +align_var_struct_span = 0 # unsigned number + +# The threshold for aligning struct/union member definitions. +# +# 0 = No limit (default). +align_var_struct_thresh = 0 # unsigned number + +# The gap for aligning struct/union member definitions. +align_var_struct_gap = 0 # unsigned number + +# The span for aligning struct initializer values. +# +# 0 = Don't align (default). +align_struct_init_span = 0 # unsigned number + +# The minimum space between the type and the synonym of a typedef. +align_typedef_gap = 0 # unsigned number + +# The span for aligning single-line typedefs. +# +# 0 = Don't align (default). +align_typedef_span = 0 # unsigned number + +# How to align typedef'd functions with other typedefs. +# +# 0: Don't mix them at all (default) +# 1: Align the open parenthesis with the types +# 2: Align the function type name with the other type names +align_typedef_func = 0 # unsigned number + +# How to align the '*' in typedefs. +# +# 0: Align on typedef type, ignore '*' (default) +# 1: The '*' is part of type name: 'typedef int *pint;' +# 2: The '*' is part of the type, but dangling: 'typedef int *pint;' +align_typedef_star_style = 0 # unsigned number + +# How to align the '&' in typedefs. +# +# 0: Align on typedef type, ignore '&' (default) +# 1: The '&' is part of type name: 'typedef int &pint;' +# 2: The '&' is part of the type, but dangling: 'typedef int &pint;' +align_typedef_amp_style = 0 # unsigned number + +# The span for aligning comments that end lines. +# +# 0 = Don't align (default). +align_right_cmt_span = 0 # unsigned number + +# If aligning comments, whether to mix with comments after '}' and #endif with +# less than three spaces before the comment. +align_right_cmt_mix = false # true/false + +# Whether to only align trailing comments that are at the same brace level. +align_right_cmt_same_level = false # true/false + +# Minimum number of columns between preceding text and a trailing comment in +# order for the comment to qualify for being aligned. Must be non-zero to have +# an effect. +align_right_cmt_gap = 0 # unsigned number + +# Minimum column at which to align trailing comments. Comments which are +# aligned beyond this column, but which can be aligned in a lesser column, +# may be "pulled in". +# +# 0 = Ignore (default). +align_right_cmt_at_col = 0 # unsigned number + +# The span for aligning function prototypes. +# +# 0 = Don't align (default). +align_func_proto_span = 0 # unsigned number + +# Minimum gap between the return type and the function name. +align_func_proto_gap = 0 # unsigned number + +# Whether to align function prototypes on the 'operator' keyword instead of +# what follows. +align_on_operator = false # true/false + +# Whether to mix aligning prototype and variable declarations. If true, +# align_var_def_XXX options are used instead of align_func_proto_XXX options. +align_mix_var_proto = false # true/false + +# Whether to align single-line functions with function prototypes. +# Uses align_func_proto_span. +align_single_line_func = false # true/false + +# Whether to align the open brace of single-line functions. +# Requires align_single_line_func=true. Uses align_func_proto_span. +align_single_line_brace = false # true/false + +# Gap for align_single_line_brace. +align_single_line_brace_gap = 0 # unsigned number + +# (OC) The span for aligning Objective-C message specifications. +# +# 0 = Don't align (default). +align_oc_msg_spec_span = 0 # unsigned number + +# Whether to align macros wrapped with a backslash and a newline. This will +# not work right if the macro contains a multi-line comment. +align_nl_cont = false # true/false + +# Whether to align macro functions and variables together. +align_pp_define_together = false # true/false + +# The minimum space between label and value of a preprocessor define. +align_pp_define_gap = 0 # unsigned number + +# The span for aligning on '#define' bodies. +# +# =0: Don't align (default) +# >0: Number of lines (including comments) between blocks +align_pp_define_span = 0 # unsigned number + +# Whether to align lines that start with '<<' with previous '<<'. +# +# Default: true +align_left_shift = true # true/false + +# Whether to align text after 'asm volatile ()' colons. +align_asm_colon = false # true/false + +# (OC) Span for aligning parameters in an Objective-C message call +# on the ':'. +# +# 0 = Don't align. +align_oc_msg_colon_span = 0 # unsigned number + +# (OC) Whether to always align with the first parameter, even if it is too +# short. +align_oc_msg_colon_first = false # true/false + +# (OC) Whether to align parameters in an Objective-C '+' or '-' declaration +# on the ':'. +align_oc_decl_colon = false # true/false + +# +# Comment modification options +# + +# Try to wrap comments at N columns. +cmt_width = 0 # unsigned number + +# How to reflow comments. +# +# 0: No reflowing (apart from the line wrapping due to cmt_width) (default) +# 1: No touching at all +# 2: Full reflow +cmt_reflow_mode = 0 # unsigned number + +# Whether to convert all tabs to spaces in comments. If false, tabs in +# comments are left alone, unless used for indenting. +cmt_convert_tab_to_spaces = false # true/false + +# Whether to apply changes to multi-line comments, including cmt_width, +# keyword substitution and leading chars. +# +# Default: true +cmt_indent_multi = true # true/false + +# Whether to group c-comments that look like they are in a block. +cmt_c_group = false # true/false + +# Whether to put an empty '/*' on the first line of the combined c-comment. +cmt_c_nl_start = false # true/false + +# Whether to add a newline before the closing '*/' of the combined c-comment. +cmt_c_nl_end = false # true/false + +# Whether to change cpp-comments into c-comments. +cmt_cpp_to_c = false # true/false + +# Whether to group cpp-comments that look like they are in a block. Only +# meaningful if cmt_cpp_to_c=true. +cmt_cpp_group = false # true/false + +# Whether to put an empty '/*' on the first line of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_start = false # true/false + +# Whether to add a newline before the closing '*/' of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_end = false # true/false + +# Whether to put a star on subsequent comment lines. +cmt_star_cont = false # true/false + +# The number of spaces to insert at the start of subsequent comment lines. +cmt_sp_before_star_cont = 0 # unsigned number + +# The number of spaces to insert after the star on subsequent comment lines. +cmt_sp_after_star_cont = 0 # unsigned number + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length. +# +# Default: true +cmt_multi_check_last = true # true/false + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length AND if the length is +# bigger as the first_len minimum. +# +# Default: 4 +cmt_multi_first_len_minimum = 4 # unsigned number + +# Path to a file that contains text to insert at the beginning of a file if +# the file doesn't start with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_header = "" # string + +# Path to a file that contains text to insert at the end of a file if the +# file doesn't end with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_footer = "" # string + +# Path to a file that contains text to insert before a function definition if +# the function isn't preceded by a C/C++ comment. If the inserted text +# contains '$(function)', '$(javaparam)' or '$(fclass)', these will be +# replaced with, respectively, the name of the function, the javadoc '@param' +# and '@return' stuff, or the name of the class to which the member function +# belongs. +cmt_insert_func_header = "" # string + +# Path to a file that contains text to insert before a class if the class +# isn't preceded by a C/C++ comment. If the inserted text contains '$(class)', +# that will be replaced with the class name. +cmt_insert_class_header = "" # string + +# Path to a file that contains text to insert before an Objective-C message +# specification, if the method isn't preceded by a C/C++ comment. If the +# inserted text contains '$(message)' or '$(javaparam)', these will be +# replaced with, respectively, the name of the function, or the javadoc +# '@param' and '@return' stuff. +cmt_insert_oc_msg_header = "" # string + +# Whether a comment should be inserted if a preprocessor is encountered when +# stepping backwards from a function name. +# +# Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and +# cmt_insert_class_header. +cmt_insert_before_preproc = false # true/false + +# Whether a comment should be inserted if a function is declared inline to a +# class definition. +# +# Applies to cmt_insert_func_header. +# +# Default: true +cmt_insert_before_inlines = true # true/false + +# Whether a comment should be inserted if the function is a class constructor +# or destructor. +# +# Applies to cmt_insert_func_header. +cmt_insert_before_ctor_dtor = false # true/false + # # Code modifying options (non-whitespace) # -# Add or remove braces on single-line 'do' statement +# Add or remove braces on a single-line 'do' statement. mod_full_brace_do = ignore # ignore/add/remove/force -# Add or remove braces on single-line 'for' statement +# Add or remove braces on a single-line 'for' statement. mod_full_brace_for = ignore # ignore/add/remove/force -# Add or remove braces on single-line function definitions. (Pawn) +# (Pawn) Add or remove braces on a single-line function definition. mod_full_brace_function = ignore # ignore/add/remove/force -# Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. +# Add or remove braces on a single-line 'if' statement. Braces will not be +# removed if the braced statement contains an 'else'. mod_full_brace_if = ignore # ignore/add/remove/force -# Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. -# If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. -mod_full_brace_if_chain = false # false/true +# Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either +# have, or do not have, braces. If true, braces will be added if any block +# needs braces, and will only be removed if they can be removed from all +# blocks. +# +# Overrides mod_full_brace_if. +mod_full_brace_if_chain = false # true/false -# Make all if/elseif/else statements with at least one 'else' or 'else if' fully braced. -# If mod_full_brace_if_chain is used together with this option, all if-else chains will get braces, -# and simple 'if' statements will lose them (if possible). -mod_full_brace_if_chain_only = false # false/true +# Whether to add braces to all blocks of an 'if'/'else if'/'else' chain. +# If true, mod_full_brace_if_chain will only remove braces from an 'if' that +# does not have an 'else if' or 'else'. +mod_full_brace_if_chain_only = false # true/false -# Don't remove braces around statements that span N newlines -mod_full_brace_nl = 0 # number - -# Add or remove braces on single-line 'while' statement +# Add or remove braces on single-line 'while' statement. mod_full_brace_while = ignore # ignore/add/remove/force -# Add or remove braces on single-line 'using ()' statement +# Add or remove braces on single-line 'using ()' statement. mod_full_brace_using = ignore # ignore/add/remove/force -# Add or remove unnecessary paren on 'return' statement +# Don't remove braces around statements that span N newlines +mod_full_brace_nl = 0 # unsigned number + +# Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks +# which span multiple lines. +# +# Affects: +# mod_full_brace_for +# mod_full_brace_if +# mod_full_brace_if_chain +# mod_full_brace_if_chain_only +# mod_full_brace_while +# mod_full_brace_using +# +# Does not affect: +# mod_full_brace_do +# mod_full_brace_function +mod_full_brace_nl_block_rem_mlcond = false # true/false + +# Add or remove unnecessary parenthesis on 'return' statement. mod_paren_on_return = ignore # ignore/add/remove/force -# Whether to change optional semicolons to real semicolons -mod_pawn_semicolon = false # false/true +# (Pawn) Whether to change optional semicolons to real semicolons. +mod_pawn_semicolon = false # true/false -# Add parens on 'while' and 'if' statement around bools -mod_full_paren_if_bool = false # false/true +# Whether to fully parenthesize Boolean expressions in 'while' and 'if' +# statement, as in 'if (a && b > c)' → 'if (a && (b > c))'. +mod_full_paren_if_bool = false # true/false -# Whether to remove superfluous semicolons -mod_remove_extra_semicolon = false # false/true +# Whether to remove superfluous semicolons. +mod_remove_extra_semicolon = false # true/false -# If a function body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_function_closebrace_comment = 0 # number +# If a function body exceeds the specified number of newlines and doesn't have +# a comment after the close brace, a comment will be added. +mod_add_long_function_closebrace_comment = 0 # unsigned number -# If a namespace body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_namespace_closebrace_comment = 0 # number +# If a namespace body exceeds the specified number of newlines and doesn't +# have a comment after the close brace, a comment will be added. +mod_add_long_namespace_closebrace_comment = 0 # unsigned number -# If a class body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_class_closebrace_comment = 0 # number +# If a class body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_class_closebrace_comment = 0 # unsigned number -# If a switch body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_switch_closebrace_comment = 0 # number +# If a switch body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_switch_closebrace_comment = 0 # unsigned number -# If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after -# the #endif, a comment will be added. -mod_add_long_ifdef_endif_comment = 0 # number +# If an #ifdef body exceeds the specified number of newlines and doesn't have +# a comment after the #endif, a comment will be added. +mod_add_long_ifdef_endif_comment = 0 # unsigned number -# If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after -# the #else, a comment will be added. -mod_add_long_ifdef_else_comment = 0 # number +# If an #ifdef or #else body exceeds the specified number of newlines and +# doesn't have a comment after the #else, a comment will be added. +mod_add_long_ifdef_else_comment = 0 # unsigned number -# If TRUE, will sort consecutive single-line 'import' statements [Java, D] -mod_sort_import = false # false/true +# Whether to sort consecutive single-line 'import' statements. +mod_sort_import = false # true/false -# If TRUE, will sort consecutive single-line 'using' statements [C#] -mod_sort_using = false # false/true +# (C#) Whether to sort consecutive single-line 'using' statements. +mod_sort_using = false # true/false -# If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] -# This is generally a bad idea, as it may break your code. -mod_sort_include = false # false/true +# Whether to sort consecutive single-line '#include' statements (C/C++) and +# '#import' statements (Objective-C). Be aware that this has the potential to +# break your code if your includes/imports have ordering dependencies. +mod_sort_include = false # true/false -# If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. -mod_move_case_break = false # false/true +# Whether to move a 'break' that appears after a fully braced 'case' before +# the close brace, as in 'case X: { ... } break;' → 'case X: { ... break; }'. +mod_move_case_break = false # true/false -# Will add or remove the braces around a fully braced case statement. -# Will only remove the braces if there are no variable declarations in the block. +# Add or remove braces around a fully braced case statement. Will only remove +# braces if there are no variable declarations in the block. mod_case_brace = ignore # ignore/add/remove/force -# If TRUE, it will remove a void 'return;' that appears as the last statement in a function. -mod_remove_empty_return = false # false/true +# Whether to remove a void 'return;' that appears as the last statement in a +# function. +mod_remove_empty_return = false # true/false -# If TRUE, it will organize the properties (Obj-C) -mod_sort_oc_properties = false # false/true +# Add or remove the comma after the last value of an enumeration. +mod_enum_last_comma = ignore # ignore/add/remove/force -# Determines weight of atomic/nonatomic (Obj-C) +# (OC) Whether to organize the properties. If true, properties will be +# rearranged according to the mod_sort_oc_property_*_weight factors. +mod_sort_oc_properties = false # true/false + +# (OC) Weight of a class property modifier. +mod_sort_oc_property_class_weight = 0 # number + +# (OC) Weight of 'atomic' and 'nonatomic'. mod_sort_oc_property_thread_safe_weight = 0 # number -# Determines weight of readwrite (Obj-C) +# (OC) Weight of 'readwrite' when organizing properties. mod_sort_oc_property_readwrite_weight = 0 # number -# Determines weight of reference type (retain, copy, assign, weak, strong) (Obj-C) +# (OC) Weight of a reference type specifier ('retain', 'copy', 'assign', +# 'weak', 'strong') when organizing properties. mod_sort_oc_property_reference_weight = 0 # number -# Determines weight of getter type (getter=) (Obj-C) +# (OC) Weight of getter type ('getter=') when organizing properties. mod_sort_oc_property_getter_weight = 0 # number -# Determines weight of setter type (setter=) (Obj-C) +# (OC) Weight of setter type ('setter=') when organizing properties. mod_sort_oc_property_setter_weight = 0 # number -# Determines weight of nullability type (nullable/nonnull) (Obj-C) +# (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified', +# 'null_resettable') when organizing properties. mod_sort_oc_property_nullability_weight = 0 # number -# -# Comment modifications -# - -# Try to wrap comments at cmt_width columns -cmt_width = 0 # number - -# Set the comment reflow mode (default: 0) -# 0: no reflowing (apart from the line wrapping due to cmt_width) -# 1: no touching at all -# 2: full reflow -cmt_reflow_mode = 0 # number - -# Whether to convert all tabs to spaces in comments. Default is to leave tabs inside comments alone, unless used for indenting. -cmt_convert_tab_to_spaces = false # false/true - -# If false, disable all multi-line comment changes, including cmt_width. keyword substitution and leading chars. -# Default=True. -cmt_indent_multi = true # false/true - -# Whether to group c-comments that look like they are in a block -cmt_c_group = false # false/true - -# Whether to put an empty '/*' on the first line of the combined c-comment -cmt_c_nl_start = false # false/true - -# Whether to put a newline before the closing '*/' of the combined c-comment -cmt_c_nl_end = false # false/true - -# Whether to group cpp-comments that look like they are in a block -cmt_cpp_group = false # false/true - -# Whether to put an empty '/*' on the first line of the combined cpp-comment -cmt_cpp_nl_start = false # false/true - -# Whether to put a newline before the closing '*/' of the combined cpp-comment -cmt_cpp_nl_end = false # false/true - -# Whether to change cpp-comments into c-comments -cmt_cpp_to_c = false # false/true - -# Whether to put a star on subsequent comment lines -cmt_star_cont = false # false/true - -# The number of spaces to insert at the start of subsequent comment lines -cmt_sp_before_star_cont = 0 # number - -# The number of spaces to insert after the star on subsequent comment lines -cmt_sp_after_star_cont = 0 # number - -# For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of -# the comment are the same length. Default=True -cmt_multi_check_last = true # false/true - -# For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of -# the comment are the same length AND if the length is bigger as the first_len minimum. Default=4 -cmt_multi_first_len_minimum = 4 # number - -# The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. -# Will substitute $(filename) with the current file's name. -cmt_insert_file_header = "" # string - -# The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. -# Will substitute $(filename) with the current file's name. -cmt_insert_file_footer = "" # string - -# The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. -# Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. -# Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } -cmt_insert_func_header = "" # string - -# The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. -# Will substitute $(class) with the class name. -cmt_insert_class_header = "" # string - -# The filename that contains text to insert before a Obj-C message specification if the method isn't preceded with a C/C++ comment. -# Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff. -cmt_insert_oc_msg_header = "" # string - -# If a preprocessor is encountered when stepping backwards from a function name, then -# this option decides whether the comment should be inserted. -# Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header. -cmt_insert_before_preproc = false # false/true - -# If a function is declared inline to a class definition, then -# this option decides whether the comment should be inserted. -# Affects cmt_insert_func_header. -cmt_insert_before_inlines = true # false/true - -# If the function is a constructor/destructor, then -# this option decides whether the comment should be inserted. -# Affects cmt_insert_func_header. -cmt_insert_before_ctor_dtor = false # false/true - # # Preprocessor options # -# Control indent of preprocessors inside #if blocks at brace level 0 (file-level) +# Add or remove indentation of preprocessor directives inside #if blocks +# at brace level 0 (file-level). pp_indent = remove # ignore/add/remove/force -# Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) -pp_indent_at_level = false # false/true +# Whether to indent #if/#else/#endif at the brace level. If false, these are +# indented from column 1. +pp_indent_at_level = false # true/false -# Specifies the number of columns to indent preprocessors per level at brace level 0 (file-level). -# If pp_indent_at_level=false, specifies the number of columns to indent preprocessors per level at brace level > 0 (function-level). -# Default=1. -pp_indent_count = 1 # number +# Specifies the number of columns to indent preprocessors per level +# at brace level 0 (file-level). If pp_indent_at_level=false, also specifies +# the number of columns to indent preprocessors per level +# at brace level > 0 (function-level). +# +# Default: 1 +pp_indent_count = 1 # unsigned number -# Add or remove space after # based on pp_level of #if blocks -pp_space = add # ignore/add/remove/force +# Add or remove space after # based on pp_level of #if blocks. +pp_space = force # ignore/add/remove/force -# Sets the number of spaces added with pp_space -pp_space_count = 1 # number +# Sets the number of spaces per level added with pp_space. +pp_space_count = 1 # unsigned number -# The indent for #region and #endregion in C# and '#pragma region' in C/C++ +# The indent for '#region' and '#endregion' in C# and '#pragma region' in +# C/C++. Negative values decrease indent down to the first column. pp_indent_region = 0 # number -# Whether to indent the code between #region and #endregion -pp_region_indent_code = false # false/true +# Whether to indent the code between #region and #endregion. +pp_region_indent_code = false # true/false -# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when not at file-level. -# 0: indent preprocessors using output_tab_size. -# >0: column at which all preprocessors will be indented. +# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when +# not at file-level. Negative values decrease indent down to the first column. +# +# =0: Indent preprocessors using output_tab_size +# >0: Column at which all preprocessors will be indented pp_indent_if = 0 # number -# Control whether to indent the code between #if, #else and #endif. -pp_if_indent_code = false # false/true +# Whether to indent the code between #if, #else and #endif. +pp_if_indent_code = false # true/false -# Whether to indent '#define' at the brace level (true) or from column 1 (false) -pp_define_at_level = false # false/true +# Whether to indent '#define' at the brace level. If false, these are +# indented from column 1. +pp_define_at_level = false # true/false + +# Whether to ignore the '#define' body while formatting. +pp_ignore_define_body = false # true/false + +# Whether to indent case statements between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the case statements +# directly inside of. +# +# Default: true +pp_indent_case = true # true/false + +# Whether to indent whole function definitions between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the function definition +# is directly inside of. +# +# Default: true +pp_indent_func_def = true # true/false + +# Whether to indent extern C blocks between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the extern block is +# directly inside of. +# +# Default: true +pp_indent_extern = true # true/false + +# Whether to indent braces directly inside #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the braces are directly +# inside of. +# +# Default: true +pp_indent_brace = true # true/false + +# +# Sort includes options +# + +# The regex for include category with priority 0. +include_category_0 = "" # string + +# The regex for include category with priority 1. +include_category_1 = "" # string + +# The regex for include category with priority 2. +include_category_2 = "" # string # # Use or Do not Use options # -# True: indent_func_call_param will be used (default) -# False: indent_func_call_param will NOT be used -use_indent_func_call_param = true # false/true +# true: indent_func_call_param will be used (default) +# false: indent_func_call_param will NOT be used +# +# Default: true +use_indent_func_call_param = true # true/false -# The value of the indentation for a continuation line is calculate differently if the line is: -# a declaration :your case with QString fileName ... -# an assigment :your case with pSettings = new QSettings( ... -# At the second case the option value might be used twice: -# at the assigment -# at the function call (if present) -# To prevent the double use of the option value, use this option with the value 'true'. -# True: indent_continue will be used only once -# False: indent_continue will be used every time (default) -use_indent_continue_only_once = false # false/true +# The value of the indentation for a continuation line is calculated +# differently if the statement is: +# - a declaration: your case with QString fileName ... +# - an assignment: your case with pSettings = new QSettings( ... +# +# At the second case the indentation value might be used twice: +# - at the assignment +# - at the function call (if present) +# +# To prevent the double use of the indentation value, use this option with the +# value 'true'. +# +# true: indent_continue will be used only once +# false: indent_continue will be used every time (default) +use_indent_continue_only_once = false # true/false -# SIGNAL/SLOT Qt macros have special formatting options. See options_for_QT.cpp for details. -# Default=True. -use_options_overriding_for_qt_macros = true # false/true +# The value might be used twice: +# - at the assignment +# - at the opening brace +# +# To prevent the double use of the indentation value, use this option with the +# value 'true'. +# +# true: indentation will be used only once +# false: indentation will be used every time (default) +indent_cpp_lambda_only_once = true # true/false + +# Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially, +# this tries to format these so that they match Qt's normalized form (i.e. the +# result of QMetaObject::normalizedSignature), which can slightly improve the +# performance of the QObject::connect call, rather than how they would +# otherwise be formatted. +# +# See options_for_QT.cpp for details. +# +# Default: true +use_options_overriding_for_qt_macros = true # true/false # # Warn levels - 1: error, 2: warning (default), 3: note # -# Warning is given if doing tab-to-\t replacement and we have found one in a C# verbatim string literal. -warn_level_tabs_found_in_verbatim_string_literals = 2 # number +# (C#) Warning is given if doing tab-to-\t replacement and we have found one +# in a C# verbatim string literal. +# +# Default: 2 +warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number -# You can force a token to be a type with the 'type' option. -# Example: -# type myfoo1 myfoo2 +# Meaning of the settings: +# Ignore - do not do any changes +# Add - makes sure there is 1 or more space/brace/newline/etc +# Force - makes sure there is exactly 1 space/brace/newline/etc, +# behaves like Add in some contexts +# Remove - removes space/brace/newline/etc # -# You can create custom macro-based indentation using macro-open, -# macro-else and macro-close. -# Example: -# macro-open BEGIN_TEMPLATE_MESSAGE_MAP -# macro-open BEGIN_MESSAGE_MAP -# macro-close END_MESSAGE_MAP # -# You can assign any keyword to any type with the set option. -# set func_call_user _ N_ +# - Token(s) can be treated as specific type(s) with the 'set' option: +# `set tokenType tokenString [tokenString...]` # -# The full syntax description of all custom definition config entries -# is shown below: +# Example: +# `set BOOL __AND__ __OR__` # -# define custom tokens as: -# - embed whitespace in token using '' escape character, or -# put token in quotes -# - these: ' " and ` are recognized as quote delimiters +# tokenTypes are defined in src/token_enum.h, use them without the +# 'CT_' prefix: 'CT_BOOL' → 'BOOL' # -# type token1 token2 token3 ... -# ^ optionally specify multiple tokens on a single line -# define def_token output_token -# ^ output_token is optional, then NULL is assumed -# macro-open token -# macro-close token -# macro-else token -# set id token1 token2 ... -# ^ optionally specify multiple tokens on a single line -# ^ id is one of the names in token_enum.h sans the CT_ prefix, -# e.g. PP_PRAGMA # -# all tokens are separated by any mix of ',' commas, '=' equal signs -# and whitespace (space, tab) +# - Token(s) can be treated as type(s) with the 'type' option. +# `type tokenString [tokenString...]` # -# You can add support for other file extensions using the 'file_ext' command. -# The first arg is the language name used with the '-l' option. -# The remaining args are file extensions, matched with 'endswith'. -# file_ext CPP .ch .cxx .cpp.in +# Example: +# `type int c_uint_8 Rectangle` # -# option(s) with 'not default' value: 0 +# This can also be achieved with `set TYPE int c_uint_8 Rectangle` +# +# +# To embed whitespace in tokenStrings use the '\' escape character, or quote +# the tokenStrings. These quotes are supported: "'` +# +# +# - Support for the auto detection of languages through the file ending can be +# added using the 'file_ext' command. +# `file_ext langType langString [langString..]` +# +# Example: +# `file_ext CPP .ch .cxx .cpp.in` +# +# langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use +# them without the 'LANG_' prefix: 'LANG_CPP' → 'CPP' +# +# +# - Custom macro-based indentation can be set up using 'macro-open', +# 'macro-else' and 'macro-close'. +# `(macro-open | macro-else | macro-close) tokenString` +# +# Example: +# `macro-open BEGIN_TEMPLATE_MESSAGE_MAP` +# `macro-open BEGIN_MESSAGE_MAP` +# `macro-close END_MESSAGE_MAP` +# +# +# option(s) with 'not default' value: 98 # diff --git a/tests/.gitignore b/tests/.gitignore index 46192fa75..3a531c3c9 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -33,6 +33,7 @@ wsOct !/AIM/fs2000_b1L1L_steadystate.m !/AIM/fsdat.m !/analytic_derivatives/fsdat_simul.m +!/analytic_derivatives/nBrockMirmanSYM.mat !/block_bytecode/run_ls2003.m !/bvar_a_la_sims/bvar_sample.m !/conditional_forecasts/2/fsdat_simul.m @@ -67,6 +68,7 @@ wsOct !/gsa/ls2003scr_results.mat !/gsa/morris/nk_est_data.m !/identification/as2007/as2007_steadystate.m +!/identification/as2007/G_QT.mat !/identification/kim/kim2_steadystate.m !/initval_file/ramst_initval_file_data.m !/internals/tests.m @@ -124,6 +126,7 @@ wsOct !/practicing/dataHST.mat !/practicing/data_consRicardoypg.mat !/practicing/datasaver.m +!/pruning/Andreasen_et_al_2018_Dynare44Pruning_v2.mat !/utils/printMakeCheckMatlabErrMsg.m !/utils/printMakeCheckOctaveErrMsg.m !/prior_posterior_function/posterior_function_demo.m diff --git a/tests/Makefile.am b/tests/Makefile.am index e0c9bbab0..fe9889744 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -19,6 +19,9 @@ MODFILES = \ optimizers/fs2000_9.mod \ optimizers/fs2000_10.mod \ analytic_derivatives/fs2000_analytic_derivation.mod \ + analytic_derivatives/BrockMirman_PertParamsDerivs.mod \ + analytic_derivatives/burnside_3_order_PertParamsDerivs.mod \ + pruning/AnSchorfheide_pruned_state_space.mod \ measurement_errors/fs2000_corr_me_ml_mcmc/fs2000_corr_ME.mod \ TeX/fs2000_corr_ME.mod \ estimation/MH_recover/fs2000_recover_tarb.mod \ @@ -98,9 +101,12 @@ MODFILES = \ optimal_policy/Ramsey/ramsey_histval.mod \ optimal_policy/Ramsey/Gali_commitment.mod \ optimal_policy/RamseyConstraints/test1.mod \ + optimal_policy/Ramsey/Ramsey_Example_estimation.mod \ discretionary_policy/dennis_1.mod \ + discretionary_policy/dennis_1_estim.mod \ discretionary_policy/Gali_discretion.mod \ initval_file/ramst_initval_file.mod \ + initval_file/ramst_datafile.mod \ ramst_normcdf_and_friends.mod \ ramst_vec.mod \ example1_varexo_det.mod \ @@ -109,6 +115,7 @@ MODFILES = \ comments.mod \ histval_sto.mod \ histval_det.mod \ + histval_predetermined.mod \ auxiliary_variables/test1.mod \ expectations/expectation.mod \ expectations/expectation_ss.mod \ @@ -120,6 +127,7 @@ MODFILES = \ steady_state/walsh1_ssm_block.mod \ steady_state/multi_leads.mod \ steady_state/example1_trust_region.mod \ + steady_state/Gali_2015_chapter_6_4.mod \ steady_state_operator/standard.mod \ steady_state_operator/use_dll.mod \ steady_state_operator/block.mod \ @@ -183,11 +191,15 @@ MODFILES = \ external_function/no_deriv_given.mod \ external_function/no_deriv_given_dll.mod \ seeds.mod \ + minimal_state_space_system/as2007_minimal.mod \ + minimal_state_space_system/sw_minimal.mod \ identification/kim/kim2.mod \ identification/as2007/as2007.mod \ identification/as2007/as2007_kronflags.mod \ identification/as2007/as2007_QT.mod \ identification/as2007/as2007_QT_equal_autocorr.mod \ + identification/as2007/as2007_order_1_2_3.mod \ + identification/as2007/as2007_order3_no_stoch_simul.mod \ identification/BrockMirman/BrockMirman.mod \ identification/cgg/cgg_criteria_differ.mod \ identification/ident_unit_root/ident_unit_root.mod \ @@ -268,6 +280,7 @@ MODFILES = \ ep/rbcii.mod \ ep/linearmodel0.mod \ ep/linearmodel1.mod \ + stochastic_simulations/example1_noprint.mod \ stochastic-backward-models/solow_cd.mod \ stochastic-backward-models/solow_ces.mod \ stochastic-backward-models/solow_cd_with_steadystate.mod \ @@ -371,7 +384,8 @@ MODFILES = \ bgp/solow-1/solow.mod \ bgp/nk-1/nk.mod \ bgp/ramsey-1/ramsey.mod \ - dynare-command-options/ramst.mod + dynare-command-options/ramst.mod \ + particle/local_state_space_iteration_k_test.mod ECB_MODFILES = \ var-expectations/1/example.mod \ @@ -508,9 +522,12 @@ XFAIL_MODFILES = ramst_xfail.mod \ estimation/fs2000_mixed_ML_xfail.mod \ estimation/fs2000_stochastic_singularity_xfail.mod \ identification/ident_unit_root/ident_unit_root_xfail.mod \ + identification/LindeTrabandt/LindeTrabandt2019_xfail.mod \ steady_state/Linear_steady_state_xfail.mod \ optimal_policy/Ramsey/ramsey_histval_xfail.mod \ - example1_extra_exo_xfail.mod + example1_extra_exo_xfail.mod \ + estimation/tune_mh_jscale/fs2000_1_xfail.mod \ + estimation/tune_mh_jscale/fs2000_2_xfail.mod MFILES = initval_file/ramst_initval_file_data.m @@ -612,6 +629,8 @@ deterministic_simulations/rbc_det_stack_solve_algo_7_exo_lag.o.trs: deterministi initval_file/ramst_initval_file.m.trs: initval_file/ramst_initval_file_data.m.tls initval_file/ramst_initval_file.o.trs: initval_file/ramst_initval_file_data.o.tls +initval_file/ramst_datafile.m.trs: initval_file/ramst_initval_file_data.m.tls +initval_file/ramst_datafile.o.trs: initval_file/ramst_initval_file_data.o.tls identification/rbc_ident/rbc_ident_varexo_only.m.trs: identification/rbc_ident/rbc_ident_std_as_structural_par.m.trs identification/rbc_ident/rbc_ident_varexo_only.o.trs: identification/rbc_ident/rbc_ident_std_as_structural_par.o.trs @@ -719,6 +738,9 @@ trend-component-and-var-models/tcm7.o.trs: trend-component-and-var-models/tcm6.o trend-component-and-var-models/tcm8.m.trs: trend-component-and-var-models/tcm6.m.trs trend-component-and-var-models/tcm8.o.trs: trend-component-and-var-models/tcm6.o.trs +discretionary_policy/dennis_1_estim.m.trs: discretionary_policy/dennis_1.m.trs +discretionary_policy/dennis_1_estim.o.trs: discretionary_policy/dennis_1.o.trs + observation_trends_and_prefiltering/MCMC: m/observation_trends_and_prefiltering/MCMC o/observation_trends_and_prefiltering/MCMC m/observation_trends_and_prefiltering/MCMC: $(patsubst %.mod, %.m.trs, $(filter observation_trends_and_prefiltering/MCMC/%.mod, $(MODFILES))) o/observation_trends_and_prefiltering/MCMC: $(patsubst %.mod, %.o.trs, $(filter observation_trends_and_prefiltering/MCMC/%.mod, $(MODFILES))) @@ -788,7 +810,7 @@ m/optimal_policy/OSR: $(patsubst %.mod, %.m.trs, $(filter optimal_policy/OSR/%.m o/optimal_policy/OSR: $(patsubst %.mod, %.o.trs, $(filter optimal_policy/OSR/%.mod, $(MODFILES))) optimal_policy/Ramsey: m/optimal_policy/Ramsey o/optimal_policy/Ramsey -m/optimal_policy/Ramsey: $(patsubst %.mod, %.m.trs, $(filter optimal_policy/Ransey/%.mod, $(MODFILES))) +m/optimal_policy/Ramsey: $(patsubst %.mod, %.m.trs, $(filter optimal_policy/Ramsey/%.mod, $(MODFILES))) o/optimal_policy/Ramsey: $(patsubst %.mod, %.o.trs, $(filter optimal_policy/Ramsey/%.mod, $(MODFILES))) optimal_policy: m/optimal_policy o/optimal_policy @@ -843,6 +865,14 @@ identification: m/identification o/identification m/identification: $(patsubst %.mod, %.m.trs, $(filter identification/%.mod, $(MODFILES))) o/identification: $(patsubst %.mod, %.o.trs, $(filter identification/%.mod, $(MODFILES))) +analytic_derivatives: m/analytic_derivatives o/analytic_derivatives +m/analytic_derivatives: $(patsubst %.mod, %.m.trs, $(filter analytic_derivatives/%.mod, $(MODFILES))) +o/analytic_derivatives: $(patsubst %.mod, %.o.trs, $(filter analytic_derivatives/%.mod, $(MODFILES))) + +pruning: m/pruning o/pruning +m/pruning: $(patsubst %.mod, %.m.trs, $(filter pruning/%.mod, $(MODFILES))) +o/pruning: $(patsubst %.mod, %.o.trs, $(filter pruning/%.mod, $(MODFILES))) + fs2000: m/fs2000 o/fs2000 m/fs2000: $(patsubst %.mod, %.m.trs, $(filter fs2000/%.mod, $(MODFILES))) o/fs2000: $(patsubst %.mod, %.o.trs, $(filter fs2000/%.mod, $(MODFILES))) @@ -946,6 +976,7 @@ EXTRA_DIST = \ read_trs_files.sh \ run_test_matlab.m \ run_test_octave.m \ + run_m_script.m \ load_octave_packages.m \ $(MODFILES) \ $(XFAIL_MODFILES) \ @@ -990,8 +1021,14 @@ EXTRA_DIST = \ data/test.xls \ data/test.xlsx \ gsa/morris/nk_est_data.m \ + gsa/data_ca1.m \ + gsa/data_ca1.mat \ analytic_derivatives/fsdat_simul.m \ + analytic_derivatives/nBrockMirmanSYM.mat \ + pruning/Andreasen_et_al_2018_Dynare44Pruning_v2.mat \ fs2000/fsdat_simul.m \ + fs2000/fsdat_simul_dseries.m \ + fs2000/fsdat_simul_missing_obs.m \ ls2003/data_ca1.m \ measurement_errors/data_ca1.m \ measurement_errors/fs2000_corr_me_ml_mcmc/fsdat_simul.m \ @@ -1026,8 +1063,10 @@ EXTRA_DIST = \ kalman/likelihood_from_dynare/fs2000_estimation_check.inc \ kalman/likelihood_from_dynare/fs2000ns_model.inc \ kalman/likelihood_from_dynare/fs2000ns_estimation_check.inc \ + identification/as2007/G_QT.mat \ estimation/fsdat_simul.m \ ep/mean_preserving_spread.m \ + ep/rbcii_steady_state.m \ decision_rules/example1_results_dyn_432.mat \ decision_rules/third_order/comparison_policy_functions_dynare_mathematica.m \ decision_rules/third_order/FV_2011_policyfunctions.mat \ @@ -1036,6 +1075,7 @@ EXTRA_DIST = \ smoother2histval/fsdat_simul.m \ optimal_policy/Ramsey/find_c.m \ optimal_policy/Ramsey/oo_ramsey_policy_initval.mat \ + observation_trends_and_prefiltering/generate_trend_stationary_AR1.m \ observation_trends_and_prefiltering/Trend_diagnostics_MCMC_common.inc \ observation_trends_and_prefiltering/Trend_diagnostics_calib_common.inc \ observation_trends_and_prefiltering/Trend_diagnostics_ML_common.inc \ @@ -1055,6 +1095,10 @@ EXTRA_DIST = \ estimation/MH_recover/fs2000.common.inc \ prior_posterior_function/posterior_function_demo.m \ deterministic_simulations/lola_data.mat \ + k_order_perturbation/fs2000k++.mod \ + lmmcp/sw-common-header.inc \ + lmmcp/sw-common-footer.inc \ + estimation/tune_mh_jscale/fs2000.inc \ estimation/univariate/data.csv \ estimation/univariate/ols/mc-ols.inc \ ecb/SURGibbs/fishdata.csv \ @@ -1245,6 +1289,17 @@ clean-local: rm -rf ecb/cherrypick/simulation-files1 ecb/cherrypick/simulation-files2 toto.mod + rm -f discretionary_policy/dennis_simul.m + + rm -f kalman/likelihood_from_dynare/fsdat_simul_corr_ME.m \ + kalman/likelihood_from_dynare/fsdat_simul_corr_ME_missing.m \ + kalman/likelihood_from_dynare/fsdat_simul_uncorr_ME.m \ + kalman/likelihood_from_dynare/fsdat_simul_uncorr_ME_missing.m \ + kalman/likelihood_from_dynare/fs_ns_dat_simul_corr_ME.m \ + kalman/likelihood_from_dynare/fs_ns_dat_simul_corr_ME_missing.m \ + kalman/likelihood_from_dynare/fs_ns_dat_simul_uncorr_ME.m \ + kalman/likelihood_from_dynare/fs_ns_dat_simul_uncorr_ME_missing.m + find . -name "*.tex" -type f -delete find . -name "*.aux" -type f -delete find . -name "*.log" -type f -delete diff --git a/tests/analytic_derivatives/BrockMirman_PertParamsDerivs.mod b/tests/analytic_derivatives/BrockMirman_PertParamsDerivs.mod new file mode 100644 index 000000000..e2b407c49 --- /dev/null +++ b/tests/analytic_derivatives/BrockMirman_PertParamsDerivs.mod @@ -0,0 +1,479 @@ +% "Augmented" Brock Mirman model +% True policy functions and their exact derivatives (ghx,ghu,ghxx,ghxu,ghuu,ghs2,ghxxx,ghxxu,ghxuu,ghuuu,ghxss,ghuss) are computed using Matlab's symbolic toolbox and saved to a mat file +% Created by @wmutschl (Willi Mutschler, willi@mutschler.eu) + +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= + + +@#define CREATE_SYMBOLIC = 0 +@#define ORDER = 3 + +%define parameter values which are used for calibration and estimated_params block +@#define value_SE_A = 0.3 +@#define value_SE_X = 0.1 +@#define value_SE_Y = 0.9 +@#define value_rho_AX = 0.4 +@#define value_alph = 0.35 +@#define value_betta = 0.99 +@#define value_rhoA = 0.9 +@#define value_sigA = 0.6 +@#define value_sigX = 0.25 +@#define value_Xss = 1.2 +@#define value_dumA = 2 +@#define value_dumK = 1 +@#define value_dumepsA = 4 +@#define value_dumepsX = 5 + + +%define parameter values which are used for estimated_params block, note that all are different +@#define prior_value_SE_A = 0.8 +@#define prior_value_SE_X = 0.6 +@#define prior_value_SE_Y = 0.1 +@#define prior_value_rho_AX = 0.1 +@#define prior_value_alph = 0.15 +@#define prior_value_betta = 0.92 +@#define prior_value_rhoA = 0.3 +@#define prior_value_sigA = 0.3 +@#define prior_value_sigX = 0.15 +@#define prior_value_Xss = 1.1 +@#define prior_value_dumA = 2 +@#define prior_value_dumK = 1 +@#define prior_value_dumepsA = 5 +@#define prior_value_dumepsX = 6 + +var Y X K C A W Z; %note that declaration order is different from DR order on purpose +varobs C K A; +varexo epsA epsX epsY; +parameters alph betta rhoA sigA sigX Xss dumA dumK dumepsA dumepsX; + +%Calibration +alph = @{value_alph}; +betta = @{value_betta}; +rhoA = @{value_rhoA}; +sigA = @{value_sigA}; +sigX = @{value_sigX}; +Xss = @{value_Xss}; +dumA = @{value_dumA}; +dumK = @{value_dumK}; +dumepsA = @{value_dumepsA}; +dumepsX = @{value_dumepsX}; + +model; +%this is original Brock-Mirman model equations with AR(1) shock +C^(-1) = alph*betta*C(+1)^(-1)*A(+1)*K^(alph-1); +K = A*K(-1)^alph - C; +log(A) = rhoA*log(A(-1)) + sigA*epsA; +Y = A*K(-1)^alph + epsY; +%augmented auxiliary equations to get nonzero ghs2, ghxss and ghuss, they have no economic meaning +log(X) = log(Xss) + sigX*epsX; +W = X(+1)*exp(dumA*A(-1))*exp(dumK*K(-1)); %this will get a nonzero ghs2 and ghxss +Z = X(+1)*exp(dumepsA*epsA)*exp(dumepsX*epsX); %this will get a nonzero ghs2 and ghuss +end; + +shocks; +var epsA = (@{value_SE_A})^2; +var epsX = (@{value_SE_X})^2; +var epsA, epsX = @{value_rho_AX}*@{value_SE_A}*@{value_SE_X}; +var epsY = (@{value_SE_Y})^2; +end; + +steady_state_model; +X = Xss; +A = 1; +K = (alph*betta*A)^(1/(1-alph)); +C = A*K^alph-K; +Y = A*K^alph; +W = Xss*exp(dumA*A)*exp(dumK*K); +Z = Xss*exp(dumepsA*0)*exp(dumepsX*0); +end; + +estimated_params;%note that the parameter ordering is different than declaration order +rhoA, normal_pdf, @{prior_value_rhoA}, 0.1; +betta, normal_pdf, @{prior_value_betta}, 0.1; +alph, normal_pdf, @{prior_value_alph}, 0.1; +corr epsA, epsX, normal_pdf, @{prior_value_rho_AX}, 0.1; +sigA, normal_pdf, @{prior_value_sigA}, 0.1; +stderr epsA, normal_pdf, @{prior_value_SE_A}, 0.1; +stderr epsX, normal_pdf, @{prior_value_SE_X}, 0.1; +stderr epsY, normal_pdf, @{prior_value_SE_Y}, 0.1; +sigX, normal_pdf, @{prior_value_sigX}, 0.1; +Xss, normal_pdf, @{prior_value_Xss}, 0.1; +dumepsX, normal_pdf, @{prior_value_dumepsX}, 0.1; +dumK, normal_pdf, @{prior_value_dumK}, 0.1; +dumepsA, normal_pdf, @{prior_value_dumepsA}, 0.1; +dumA, normal_pdf, @{prior_value_dumA}, 0.1; +end; + +%save calibration parameters as these get overwritten through stoch_simul and identification command +calib_params = M_.params; +calib_Sigma_e = M_.Sigma_e; + +/* Skip test under MATLAB R2009b + MATLAB crashes, most likely due to an internal bug */ +if isoctave || ~matlab_ver_less_than('7.10') + +stoch_simul(order=@{ORDER},nograph,irf=0,periods=0); +identification(order=@{ORDER},nograph,no_identification_strength); + +indpmodel = estim_params_.param_vals(:,1); +indpstderr = estim_params_.var_exo(:,1); +indpcorr = estim_params_.corrx(:,1:2); +[I,~] = find(M_.lead_lag_incidence'); + +%% Parameter derivatives of perturbation +@#if CREATE_SYMBOLIC == 1 + syms Y_ Y0 Yp C_ C0 Cp K_ K0 Kp A_ A0 Ap X_ X0 Xp W_ W0 Wp Z_ Z0 Zp; + syms epsA0 epsX0 epsY0; + syms RHO_AX SE_A SE_X SE_Y ALPH BETTA RHOA SIGA SIGX XSS DUMA DUMK DUMEPSA DUMEPSX; + syms sig; + + SYM.corr_params = [RHO_AX]; + SYM.stderr_params_decl = [SE_A SE_X SE_Y]; + SYM.modparams_decl = [ALPH BETTA RHOA SIGA SIGX XSS DUMA DUMK DUMEPSA DUMEPSX]; + SYM.endo_decl_ = [Y_ X_ K_ C_ A_ W_ Z_]; + SYM.endo_decl0 = [Y0 X0 K0 C0 A0 W0 Z0]; + SYM.endo_declp = [Yp Xp Kp Cp Ap Wp Zp]; + SYM.ex0 = [epsA0 epsX0 epsY0]; + SYM.model_eqs = [C0^(-1)-ALPH*BETTA*Cp^(-1)*Ap*K0^(ALPH-1); + K0-A0*K_^ALPH+C0; + log(A0)-RHOA*log(A_)-SIGA*epsA0; + Y0 - A0*K_^ALPH - epsY0; + log(X0)-log(XSS)-SIGX*epsX0; + W0 - Xp*exp(DUMA*A_)*exp(DUMK*K_); + Z0 - Xp*exp(DUMEPSA*epsA0)*exp(DUMEPSX*epsX0); + ]; + SYM.Sigma_e = [SE_A^2 RHO_AX*SE_A*SE_X 0; RHO_AX*SE_A*SE_X SE_X^2 0; 0 0 SE_Y^2]; + SYM.Correlation_matrix = [1 RHO_AX 0; RHO_AX 1 0; 0 0 1]; + %steady states + SYM.epsAbar = sym(0); + SYM.epsXbar = sym(0); + SYM.epsYbar = sym(0); + SYM.Abar = sym(1); + SYM.Xbar = XSS; + SYM.Kbar = (ALPH*BETTA*SYM.Abar)^(1/(1-ALPH)); + SYM.Cbar = SYM.Abar*SYM.Kbar^ALPH-SYM.Kbar; + SYM.Ybar = SYM.Abar*SYM.Kbar^ALPH; + SYM.Wbar = XSS*exp(DUMA*SYM.Abar)*exp(DUMK*SYM.Kbar); + SYM.Zbar = XSS*exp(DUMEPSA*0)*exp(DUMEPSX*0); + SYM.endo_bar_decl = [SYM.Ybar SYM.Xbar SYM.Kbar SYM.Cbar SYM.Abar SYM.Wbar SYM.Zbar]; + SYM.ex0bar = [SYM.epsAbar SYM.epsXbar SYM.epsYbar]; + %True policy functions (in declaration order): gs is used for derivatives wrt to perturbation parameter + SYM.g = [A_^RHOA*K_^ALPH*exp(SIGA*epsA0) + epsY0; %Y + XSS*exp(SIGX*epsX0); %X + ALPH*BETTA*A_^RHOA*K_^ALPH*exp(SIGA*epsA0); %K + (1-ALPH*BETTA)*A_^RHOA*K_^ALPH*exp(SIGA*epsA0); %C + A_^RHOA*exp(SIGA*epsA0); %A + XSS*exp(SIGX*0)*exp(DUMA*A_)*exp(DUMK*K_); %W + XSS*exp(SIGX*0)*exp(DUMEPSA*epsA0)*exp(DUMEPSX*epsX0); %Z + ]; + SYM.gs = [A_^RHOA*K_^ALPH*exp(SIGA*sig*epsA0) + sig*epsY0; %Y + XSS*exp(SIGX*sig*epsX0); %X + ALPH*BETTA*A_^RHOA*K_^ALPH*exp(SIGA*sig*epsA0); %K + (1-ALPH*BETTA)*A_^RHOA*K_^ALPH*exp(SIGA*sig*epsA0); %C + A_^RHOA*exp(SIGA*sig*epsA0); %A + XSS*(1+1/2*SIGX^2*sig^2*SE_X^2)*exp(DUMA*A_)*exp(DUMK*K_); %W + XSS*(1+1/2*SIGX^2*sig^2*SE_X^2)*exp(DUMEPSA*epsA0)*exp(DUMEPSX*epsX0); %Z + ]; + %put into in DR-order + SYM.g = SYM.g(oo_.dr.order_var); + SYM.gs = SYM.gs(oo_.dr.order_var); + SYM.endo_DR_ = SYM.endo_decl_(oo_.dr.order_var); + SYM.endo_DR0 = SYM.endo_decl0(oo_.dr.order_var); + SYM.endo_DRp = SYM.endo_declp(oo_.dr.order_var); + SYM.Yss = SYM.endo_bar_decl(oo_.dr.order_var); + SYM.yy0 = [SYM.endo_decl_(M_.lead_lag_incidence(1,:)~=0) SYM.endo_decl0(M_.lead_lag_incidence(2,:)~=0) SYM.endo_declp(M_.lead_lag_incidence(3,:)~=0)]; + SYM.yy0ex0 = [SYM.yy0 SYM.ex0]; + SYM.yy0ex0bar = [SYM.endo_bar_decl(I) SYM.ex0bar]; + SYM.x = SYM.endo_DR_(M_.nstatic + (1:M_.nspred)); + SYM.xbar = SYM.Yss(M_.nstatic + (1:M_.nspred)); + SYM.stderr_params = SYM.stderr_params_decl(indpstderr); + SYM.modparams = SYM.modparams_decl(indpmodel); + SYM.params = [SYM.stderr_params SYM.corr_params SYM.modparams]; + SYM.yy0ex0_nbr = length(SYM.yy0ex0); + + %% Parameter derivatives + SYM.dYss = jacobian(SYM.Yss,SYM.modparams); + SYM.d2Yss = jacobian(SYM.dYss(:),SYM.modparams); + SYM.g1 = jacobian(SYM.model_eqs,SYM.yy0ex0); + SYM.g2 = reshape(jacobian(vec(SYM.g1),SYM.yy0ex0),M_.endo_nbr,SYM.yy0ex0_nbr^2); + for j = 1:M_.endo_nbr + SYM.g3(j,:) = vec(transpose(jacobian(vec(SYM.g2(j,:)),SYM.yy0ex0))); %dynare ordering + end + SYM.dg1 = jacobian(vec(subs(SYM.g1,SYM.yy0ex0,SYM.yy0ex0bar)),SYM.modparams); + SYM.dg2 = jacobian(vec(subs(SYM.g2,SYM.yy0ex0,SYM.yy0ex0bar)),SYM.modparams); + SYM.dg3 = jacobian(vec(subs(SYM.g3,SYM.yy0ex0,SYM.yy0ex0bar)),SYM.modparams); + SYM.dSigma_e = jacobian(SYM.Sigma_e(:),SYM.params); + SYM.dCorrelation_matrix = jacobian(SYM.Correlation_matrix(:),SYM.params); + SYM.ghx = jacobian(SYM.g,SYM.x); + SYM.KalmanA = sym(zeros(M_.endo_nbr,M_.endo_nbr)); + SYM.KalmanA(:,M_.nstatic + (1:M_.nspred)) = SYM.ghx; + SYM.dghx = jacobian(vec(subs(SYM.ghx, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.dKalmanA = jacobian(vec(subs(SYM.KalmanA, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.d2KalmanA = jacobian(SYM.dKalmanA(:),SYM.params); + SYM.ghu = jacobian(SYM.g,SYM.ex0); + SYM.dghu = jacobian(vec(subs(SYM.ghu, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.Om = SYM.ghu*SYM.Sigma_e*transpose(SYM.ghu); + SYM.dOm = jacobian(vec(subs(SYM.Om,[SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.d2Om = jacobian(SYM.dOm(:),SYM.params); + SYM.ghxx = jacobian(SYM.ghx(:),SYM.x); + SYM.ghxx = reshape(SYM.ghxx,M_.endo_nbr,M_.nspred^2); + SYM.dghxx = jacobian(vec(subs(SYM.ghxx, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.ghxu = jacobian(SYM.ghu(:),SYM.x); + SYM.ghxu = reshape(SYM.ghxu,M_.endo_nbr,M_.nspred*M_.exo_nbr); + SYM.dghxu = jacobian(vec(subs(SYM.ghxu, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.ghuu = jacobian(SYM.ghu(:),SYM.ex0); + SYM.ghuu = reshape(SYM.ghuu,M_.endo_nbr,M_.exo_nbr*M_.exo_nbr); + SYM.dghuu = jacobian(vec(subs(SYM.ghuu, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.ghs2 = jacobian(jacobian(SYM.gs,sig),sig); + SYM.dghs2 = jacobian(vec(subs(SYM.ghs2, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + for j = 1:M_.endo_nbr + SYM.ghxxx(j,:) = vec(transpose(jacobian(vec(SYM.ghxx(j,:)),SYM.x))); %dynare ordering + SYM.ghxxu(j,:) = vec(transpose(jacobian(vec(SYM.ghxx(j,:)),SYM.ex0))); %dynare ordering + SYM.ghxuu(j,:) = vec(transpose(jacobian(vec(SYM.ghxu(j,:)),SYM.ex0))); %dynare ordering + SYM.ghuuu(j,:) = vec(transpose(jacobian(vec(SYM.ghuu(j,:)),SYM.ex0))); %dynare ordering + SYM.ghxss(j,:) = vec(transpose(jacobian(vec(SYM.ghs2(j,:)),SYM.x))); %dynare ordering + SYM.ghuss(j,:) = vec(transpose(jacobian(vec(SYM.ghs2(j,:)),SYM.ex0))); %dynare ordering + end + SYM.dghxxx = jacobian(vec(subs(SYM.ghxxx, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.dghxxu = jacobian(vec(subs(SYM.ghxxu, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.dghxuu = jacobian(vec(subs(SYM.ghxuu, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.dghuuu = jacobian(vec(subs(SYM.ghuuu, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.dghxss = jacobian(vec(subs(SYM.ghxss, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + SYM.dghuss = jacobian(vec(subs(SYM.ghuss, [SYM.x SYM.ex0], [SYM.xbar SYM.ex0bar])),SYM.params); + + % Evaluate numerically + for jj = 1:2 + if jj == 1 + RHO_AX = @{prior_value_rho_AX}; + SE_A = @{prior_value_SE_A}; + SE_X = @{prior_value_SE_X}; + SE_Y = @{prior_value_SE_Y}; + ALPH = @{prior_value_alph}; + BETTA = @{prior_value_betta}; + RHOA = @{prior_value_rhoA}; + SIGA = @{prior_value_sigA}; + SIGX = @{prior_value_sigX}; + XSS = @{prior_value_Xss}; + DUMA = @{prior_value_dumA}; + DUMK = @{prior_value_dumK}; + DUMEPSA = @{prior_value_dumepsA}; + DUMEPSX = @{prior_value_dumepsX}; + elseif jj == 2 + RHO_AX = @{value_rho_AX}; + SE_A = @{value_SE_A}; + SE_X = @{value_SE_X}; + SE_Y = @{value_SE_Y}; + ALPH = @{value_alph}; + BETTA = @{value_betta}; + RHOA = @{value_rhoA}; + SIGA = @{value_sigA}; + SIGX = @{value_sigX}; + XSS = @{value_Xss}; + DUMA = @{value_dumA}; + DUMK = @{value_dumK}; + DUMEPSA = @{value_dumepsA}; + DUMEPSX = @{value_dumepsX}; + end + sig = 1; + + nSYM.Yss = transpose(double(subs(SYM.Yss))); + nSYM.dYss = reshape(double(subs(SYM.dYss)), M_.endo_nbr, length(SYM.modparams)); + nSYM.d2Yss = double(reshape(subs(SYM.d2Yss), [M_.endo_nbr length(SYM.modparams) length(SYM.modparams)])); + nSYM.g1 = double(subs(subs(SYM.g1, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dg1 = reshape(double(subs(SYM.dg1)),M_.endo_nbr, SYM.yy0ex0_nbr, length(SYM.modparams)); + nSYM.g2 = sparse(double(subs(subs(SYM.g2, SYM.yy0ex0, SYM.yy0ex0bar)))); + nSYM.dg2 = reshape(sparse(double(subs(SYM.dg2))), M_.endo_nbr, SYM.yy0ex0_nbr^2*length(SYM.modparams)); + nSYM.g3 = sparse(double(subs(subs(SYM.g3, SYM.yy0ex0, SYM.yy0ex0bar)))); + nSYM.dg3 = reshape(sparse(double(subs(SYM.dg3))), M_.endo_nbr, SYM.yy0ex0_nbr^3*length(SYM.modparams)); + nSYM.Sigma_e = double(subs(SYM.Sigma_e)); + nSYM.dSigma_e = double(reshape(subs(SYM.dSigma_e), M_.exo_nbr, M_.exo_nbr,length(SYM.params))); + nSYM.Correlation_matrix = double(subs(SYM.Correlation_matrix)); + nSYM.dCorrelation_matrix = double(reshape(subs(SYM.dCorrelation_matrix), M_.exo_nbr, M_.exo_nbr,length(SYM.params))); + nSYM.ghx = double(subs(subs(SYM.ghx, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghx = reshape(double(subs(SYM.dghx)), M_.endo_nbr, M_.nspred, length(SYM.params)); + nSYM.ghu = double(subs(subs(SYM.ghu, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghu = reshape(double(subs(SYM.dghu)), M_.endo_nbr, M_.exo_nbr, length(SYM.params)); + nSYM.Om = double(subs(subs(SYM.Om, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dOm = reshape(double(subs(SYM.dOm)), M_.endo_nbr, M_.endo_nbr, length(SYM.params)); + nSYM.d2Om = reshape(sparse(double(subs(SYM.d2Om))), M_.endo_nbr^2, length(SYM.params)^2); + SYM.indp2 = reshape(1:length(SYM.params)^2,length(SYM.params),length(SYM.params)); + SYM.indx2 = reshape(1:M_.endo_nbr^2, M_.endo_nbr, M_.endo_nbr); + nSYM.d2Om = nSYM.d2Om(dyn_vech(SYM.indx2),dyn_vech(SYM.indp2)); + nSYM.KalmanA = double(subs(subs(SYM.KalmanA, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dKalmanA = reshape(double(subs(SYM.dKalmanA)), M_.endo_nbr, M_.endo_nbr, length(SYM.params)); + nSYM.d2KalmanA = reshape(double(subs(SYM.d2KalmanA)), M_.endo_nbr^2, length(SYM.params)^2); + nSYM.d2KalmanA = nSYM.d2KalmanA(:,dyn_vech(SYM.indp2)); + nSYM.ghxx = double(subs(subs(SYM.ghxx, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghxx = reshape(double(subs(SYM.dghxx)), M_.endo_nbr, M_.nspred^2, length(SYM.params)); + nSYM.ghxu = double(subs(subs(SYM.ghxu, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghxu = reshape(double(subs(SYM.dghxu)), M_.endo_nbr, M_.nspred*M_.exo_nbr, length(SYM.params)); + nSYM.ghuu = double(subs(subs(SYM.ghuu, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghuu = reshape(double(subs(SYM.dghuu)), M_.endo_nbr, M_.exo_nbr^2, length(SYM.params)); + nSYM.ghs2 = double(subs(subs(SYM.ghs2, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghs2 = reshape(double(subs(SYM.dghs2)), M_.endo_nbr, length(SYM.params)); + nSYM.ghxxx = double(subs(subs(SYM.ghxxx, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghxxx = reshape(double(subs(SYM.dghxxx)), M_.endo_nbr, M_.nspred^3, length(SYM.params)); + nSYM.ghxxu = double(subs(subs(SYM.ghxxu, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghxxu = reshape(double(subs(SYM.dghxxu)), M_.endo_nbr, M_.nspred^2*M_.exo_nbr, length(SYM.params)); + nSYM.ghxuu = double(subs(subs(SYM.ghxuu, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghxuu = reshape(double(subs(SYM.dghxuu)), M_.endo_nbr, M_.nspred*M_.exo_nbr^2, length(SYM.params)); + nSYM.ghuuu = double(subs(subs(SYM.ghuuu, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghuuu = reshape(double(subs(SYM.dghuuu)), M_.endo_nbr, M_.exo_nbr^3, length(SYM.params)); + nSYM.ghxss = double(subs(subs(SYM.ghxss, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghxss = reshape(double(subs(SYM.dghxss)), M_.endo_nbr, M_.nspred, length(SYM.params)); + nSYM.ghuss = double(subs(subs(SYM.ghuss, SYM.yy0ex0, SYM.yy0ex0bar))); + nSYM.dghuss = reshape(double(subs(SYM.dghuss)), M_.endo_nbr, M_.exo_nbr, length(SYM.params)); + if jj == 1 + nSYMprior = nSYM; + save('nBrockMirmanSYM.mat','nSYMprior') + elseif jj==2 + nSYMcalib = nSYM; + save('nBrockMirmanSYM.mat','nSYMcalib','-append') + end + end +@#endif + + +clc; +tol_vars.Yss = 1e-14; +tol_vars.Sigma_e = 1e-15; +tol_vars.Correlation_matrix = 1e-16; +tol_vars.g1 = 1e-13; +tol_vars.ghx = 1e-13; +tol_vars.ghu = 1e-13; +@#if ORDER > 1 +tol_vars.g2 = 1e-12; +tol_vars.ghxx = 1e-12; +tol_vars.ghxu = 1e-12; +tol_vars.ghuu = 1e-12; +tol_vars.ghs2 = 1e-12; +@#endif +@#if ORDER > 2 +tol_vars.g3 = 1e-11; +tol_vars.ghxxx = 1e-11; +tol_vars.ghxxu = 1e-11; +tol_vars.ghxuu = 1e-11; +tol_vars.ghuuu = 1e-11; +tol_vars.ghxss = 1e-11; +tol_vars.ghuss = 1e-11; +@#endif + +tol_dvars.dYss = [1e-9 1e-9 1e-14 1e-14]; +tol_dvars.dSigma_e = [1e-9 1e-15 1e-14 1e-14]; +tol_dvars.dCorrelation_matrix = [1e-9 1e-15 1e-14 1e-14]; +tol_dvars.dg1 = [1e-6 1e-6 1e-13 1e-13]; +tol_dvars.dghx = [1e-8 1e-8 1e-13 1e-13]; +tol_dvars.dghu = [1e-8 1e-8 1e-13 1e-13]; +@#if ORDER > 1 +tol_dvars.dg2 = [1e-5 1e-5 1e-11 1e-11]; +tol_dvars.dghxx = [1e-6 1e-6 1e-12 1e-12]; +tol_dvars.dghxu = [1e-6 1e-6 1e-12 1e-12]; +tol_dvars.dghuu = [1e-6 1e-6 1e-12 1e-12]; +tol_dvars.dghs2 = [1e-6 1e-6 1e-12 1e-12]; +@#endif +@#if ORDER > 2 +tol_dvars.dg3 = [1e-3 1e-3 1e-9 1e-9]; +tol_dvars.dghxxx = [1e-5 1e-5 1e-11 1e-11]; +tol_dvars.dghxxu = [1e-5 1e-5 1e-11 1e-11]; +tol_dvars.dghxuu = [1e-5 1e-5 1e-11 1e-11]; +tol_dvars.dghuuu = [1e-5 1e-5 1e-11 1e-11]; +tol_dvars.dghxss = [1e-5 1e-5 1e-11 1e-11]; +tol_dvars.dghuss = [1e-5 1e-5 1e-11 1e-11]; +@#endif +tol_dvars.d2KalmanA = [1e-3 1e-3 1e-13 1e-13]; +tol_dvars.d2Om = [1e-3 1e-3 1e-13 1e-13]; +tol_dvars.d2Yss = [1e-3 1e-3 1e-13 1e-13]; + +options_.dynatol.x = eps.^(1/3); %set numerical differentiation step in fjaco.m + +for jj = 1:2 + lst_vars = {'Yss', 'Sigma_e', 'Correlation_matrix','g1','ghx','ghu'}; + @#if ORDER > 1 + lst_vars = [lst_vars, 'g2','ghxx','ghxu','ghuu','ghs2']; + @#endif + @#if ORDER > 2 + lst_vars = [lst_vars, 'g3','ghxxx','ghxxu','ghxuu','ghuuu','ghxss','ghuss']; + @#endif + lst_dvars = {'dYss','dSigma_e','dg1','dghx','dghu'}; + @#if ORDER > 1 + lst_dvars = [lst_dvars, 'dg2','dghxx','dghxu','dghuu','dghs2']; + @#endif + @#if ORDER > 2 + lst_dvars = [lst_dvars, 'dg3','dghxxx','dghxxu','dghxuu','dghuuu','dghxss','dghuss']; + @#endif + load('nBrockMirmanSYM.mat'); + if jj==1 + strparamset = 'PRIOR'; + nSYM = nSYMprior; + xparam_prior = set_prior(estim_params_,M_,options_); + M_ = set_all_parameters(xparam_prior,estim_params_,M_); + elseif jj==2 + strparamset = 'CALIBRATION'; + nSYM = nSYMcalib; + xparam1_calib = []; + for j = 1:length(indpstderr) + xparam1_calib = [xparam1_calib; sqrt(calib_Sigma_e(j,j))]; + end + for j = 1:size(indpcorr,1) + xparam1_calib = [xparam1_calib; calib_Sigma_e(indpcorr(j,1),indpcorr(j,2))/( sqrt(calib_Sigma_e(indpcorr(j,1),indpcorr(j,1))) * sqrt(calib_Sigma_e(indpcorr(j,2),indpcorr(j,2))) )]; + end + xparam1_calib = [xparam1_calib; calib_params(indpmodel)]; + M_ = set_all_parameters(xparam1_calib,estim_params_,M_); + end + [~,info,M_,options_,oo_] = resol(0,M_, options_, oo_); + %For convenience we save the objects to compare into oo_.dr. + oo_.dr.Yss = oo_.dr.ys(oo_.dr.order_var); + oo_.dr.Sigma_e = M_.Sigma_e; + oo_.dr.Correlation_matrix = M_.Correlation_matrix; + ex0 = oo_.exo_steady_state'; + [~, oo_.dr.g1, oo_.dr.g2, oo_.dr.g3] = feval([M_.fname,'.dynamic'], oo_.dr.ys(I), oo_.exo_steady_state', M_.params, oo_.dr.ys, 1); + oo_.dr.g3 = unfold_g3(oo_.dr.g3, length(oo_.dr.ys(I))+length(oo_.exo_steady_state')); %add symmetric elements to g3 + + fprintf('***** %s: SOME COMMON OBJECTS *****\n', strparamset) + for id_var = 1:size(lst_vars,2) + dx = norm( nSYM.(sprintf('%s',lst_vars{id_var})) - oo_.dr.(sprintf('%s',lst_vars{id_var})), Inf); + fprintf('Max absolute deviation for %s: %e\n', lst_vars{id_var}, dx); + if dx > tol_vars.(sprintf('%s',lst_vars{id_var})) + error('Something wrong in steady state computation, solution algorithm or preprocessor') + end + end + + + for d2flag = [0 1]; + if d2flag + lst_dvars = [lst_dvars {'d2KalmanA', 'd2Om', 'd2Yss'}]; + end + KRONFLAG = [-1 -2 0 1]; + for id_kronflag = 1:length(KRONFLAG) + fprintf('***** %s: d2flag=%d and kronflag=%d *****\n',strparamset, d2flag,KRONFLAG(id_kronflag)) + options_.analytic_derivation_mode = KRONFLAG(id_kronflag); + DERIVS = get_perturbation_params_derivs(M_, options_, estim_params_, oo_, indpmodel, indpstderr, indpcorr, d2flag); + for id_var = 1:size(lst_dvars,2) + dx = norm( vec(nSYM.(sprintf('%s',lst_dvars{id_var}))) - vec(DERIVS.(sprintf('%s',lst_dvars{id_var}))), Inf); + fprintf('Max absolute deviation for %s: %e\n', lst_dvars{id_var}, dx); + if dx > tol_dvars.(sprintf('%s',lst_dvars{id_var}))(id_kronflag) + error('Something wrong in get_perturbation_params_derivs.m') + end + end + end + end +end + +end % Skip test under old MATLAB diff --git a/tests/analytic_derivatives/burnside_3_order_PertParamsDerivs.mod b/tests/analytic_derivatives/burnside_3_order_PertParamsDerivs.mod new file mode 100644 index 000000000..c6285c24b --- /dev/null +++ b/tests/analytic_derivatives/burnside_3_order_PertParamsDerivs.mod @@ -0,0 +1,230 @@ +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= + + +/* + Check the policy functions obtained by perturbation at a high approximation + order, using the Burnside (1998, JEDC) model (for which the analytical form of + the policy function is known). + + As shown by Burnside, the policy function for yₜ is: + + yₜ = βⁱ exp[aᵢ+bᵢ(xₜ−xₛₛ)] + + + where: + θ² ⎛ 2ρ 1−ρ²ⁱ⎞ + — aᵢ = iθxₛₛ + σ² ─────── ⎢i − ────(1−ρⁱ) + ρ² ─────⎥ + 2(1−ρ)² ⎝ 1−ρ 1−ρ² ⎠ + + θρ + — bᵢ = ───(1−ρⁱ) + 1−ρ + + — xₛₛ is the steady state of x + — σ is the standard deviation of e. + + With some algebra, it can be shown that the derivative of yₜ at the deterministic + steady state is equal to: + + ∂ᵐ⁺ⁿ⁺²ᵖ yₜ ∞ (2p)! + ──────────────── = ∑ βⁱ bᵢᵐ⁺ⁿ ρᵐ ───── cᵢᵖ exp(iθxₛₛ) + ∂ᵐxₜ₋₁ ∂ⁿeₜ ∂²ᵖs ⁱ⁼¹ p! + + where: + — s is the stochastic scale factor + + θ² ⎛ 2ρ 1−ρ²ⁱ⎞ + — cᵢ = ─────── ⎢i − ────(1−ρⁱ) + ρ² ─────⎥ + 2(1−ρ)² ⎝ 1−ρ 1−ρ² ⎠ + + Note that derivatives with respect to an odd order for s (i.e. ∂²ᵖ⁺¹s) are always + equal to zero. + + The policy function as returned in the oo_.dr.g_* matrices has the following properties: + — its elements are pre-multiplied by the Taylor coefficients; + — derivatives w.r.t. the stochastic scale factor have already been summed up; + — symmetric elements are folded (and they are not pre-multiplied by the number of repetitions). + + As a consequence, the element gₘₙ corresponding to the m-th derivative w.r.t. + to xₜ₋₁ and the n-th derivative w.r.t. to eₜ is given by: + + 1 ∞ cᵢᵖ + gₘₙ = ────── ∑ ∑ βⁱ bᵢᵐ⁺ⁿ ρᵐ ──── exp(iθxₛₛ) + (m+n)! 0≤2p≤k-m-n ⁱ⁼¹ p! + + where k is the order of approximation. + + */ + +@#define ORDER = 3 + +var y x; +varobs y; +varexo e; + +parameters beta theta rho xbar; +xbar = 0.0179; +rho = -0.139; +theta = -1.5; +theta = -10; +beta = 0.95; + +model; +y = beta*exp(theta*x(+1))*(1+y(+1)); +x = (1-rho)*xbar + rho*x(-1)+e; +end; + +shocks; +var e; stderr 0.0348; +end; + +steady_state_model; +x = xbar; +y = beta*exp(theta*xbar)/(1-beta*exp(theta*xbar)); +end; + +estimated_params; +stderr e, normal_pdf, 0.0348,0.01; +beta, normal_pdf, 0.95, 0.01; +theta, normal_pdf, -10, 0.01; +rho, normal_pdf, -0.139, 0.01; +xbar, normal_pdf, 0.0179, 0.01; +end; + +steady;check;model_diagnostics; +stoch_simul(order=@{ORDER},k_order_solver,irf=0,drop=0,periods=0,nograph); +identification(order=@{ORDER},nograph,no_identification_strength); + +%make sure everything is computed at prior mean +xparam_prior = set_prior(estim_params_,M_,options_); +M_ = set_all_parameters(xparam_prior,estim_params_,M_); +[~,info,M_,options_,oo_] = resol(0,M_, options_, oo_); + +indpmodel = estim_params_.param_vals(:,1); +indpstderr = estim_params_.var_exo(:,1); +indpcorr = estim_params_.corrx(:,1:2); +totparam_nbr = length(indpmodel) + length(indpstderr) + size(indpcorr,1); + +%% Verify that the policy function coefficients are correct +i = 1:800; +SE_e=sqrt(M_.Sigma_e); +aux1 = rho*(1-rho.^i)/(1-rho); +aux2 = (1-rho.^(2*i))/(1-rho^2); +aux3 = 1/((1-rho)^2); +aux4 = (i-2*aux1+rho^2*aux2); +aux5=aux3*aux4; +b = theta*aux1; +c = 1/2*theta^2*SE_e^2*aux5; + +%derivatives wrt to rho only +daux1_drho = zeros(1,length(i)); +daux2_drho = zeros(1,length(i)); +daux3_drho = 2/((1-rho)^3); +daux4_drho = zeros(1,length(i)); +daux5_drho = zeros(1,length(i)); +for ii = 1:length(i) + if ii == 1 + daux1_drho(ii) = 1; + daux2_drho(ii) = 0; + else + daux1_drho(ii) = rho/(rho^2 - 2*rho + 1) - 1/(rho - 1) + ((ii+1)*rho^ii)/(rho - 1) - rho^(ii+1)/(rho^2 - 2*rho + 1); + daux2_drho(ii) = (2*rho)/(rho^4 - 2*rho^2 + 1) + (2*ii*rho^(2*ii-1))/(rho^2 - 1) - (2*rho^(2*ii+1))/(rho^4 - 2*rho^2 + 1); + end + daux4_drho(ii) = -2*daux1_drho(ii) + 2*rho*aux2(ii) + rho^2*daux2_drho(ii); + daux5_drho(ii) = daux3_drho*aux4(ii) + aux3*daux4_drho(ii); +end +%derivatives of b and c wrt to all parameters +db = zeros(size(b,1),size(b,2),M_.exo_nbr+M_.param_nbr); +db(:,:,3) = aux1;%wrt theta +db(:,:,4) = theta*daux1_drho;%wrt rho +dc = zeros(size(c,1),size(c,2),M_.exo_nbr+M_.param_nbr); +dc(:,:,1) = theta^2*SE_e*aux3*aux4;%wrt SE_e +dc(:,:,3) = theta*SE_e^2*aux3*aux4;%wrt theta +dc(:,:,4) = 1/2*theta^2*SE_e^2*daux5_drho; %wrt rho + +d2flag=0; +g_0 = 1/2*oo_.dr.ghs2; if ~isequal(g_0,oo_.dr.g_0); error('something wrong'); end +g_1 = [oo_.dr.ghx oo_.dr.ghu] +3/6*[oo_.dr.ghxss oo_.dr.ghuss]; if ~isequal(g_1,oo_.dr.g_1); error('something wrong'); end +g_2 = 1/2*[oo_.dr.ghxx oo_.dr.ghxu oo_.dr.ghuu]; if ~isequal(g_2,oo_.dr.g_2); error('something wrong'); end +g_3 = 1/6*[oo_.dr.ghxxx oo_.dr.ghxxu oo_.dr.ghxuu oo_.dr.ghuuu]; if ~isequal(g_3,oo_.dr.g_3); error('something wrong'); end + +tols = [1e-4 1e-4 1e-12 1e-12]; +KRONFLAGS = [-1 -2 0 1]; +for k = 1:length(KRONFLAGS) + fprintf('KRONFLAG=%d\n',KRONFLAGS(k)); + options_.analytic_derivation_mode = KRONFLAGS(k); + DERIVS = get_perturbation_params_derivs(M_, options_, estim_params_, oo_, indpmodel, indpstderr, indpcorr, d2flag); + oo_.dr.dg_0 = permute(1/2*DERIVS.dghs2,[1 3 2]); + oo_.dr.dg_1 = cat(2,DERIVS.dghx,DERIVS.dghu) + 3/6*cat(2,DERIVS.dghxss,DERIVS.dghuss); + oo_.dr.dg_2 = 1/2*cat(2,DERIVS.dghxx,DERIVS.dghxu,DERIVS.dghuu); + oo_.dr.dg_3 = 1/6*[DERIVS.dghxxx DERIVS.dghxxu DERIVS.dghxuu DERIVS.dghuuu]; + + for ord = 0:@{ORDER} + g = oo_.dr.(['g_' num2str(ord)])(2,:); % Retrieve computed policy function for variable y + dg = oo_.dr.(['dg_' num2str(ord)])(2,:,:); + for m = 0:ord % m is the derivation order with respect to x(-1) + v = 0; + dv = zeros(1,M_.exo_nbr + M_.param_nbr); + for p = 0:floor((@{ORDER}-ord)/2) % 2p is the derivation order with respect to s + if ord+2*p > 0 % Skip the deterministic steady state constant + v = v + sum(beta.^i.*exp(theta*xbar*i).*b.^ord.*rho^m.*c.^p)/factorial(ord)/factorial(p); + %derivatives + dv(:,1) = dv(:,1) + sum( beta.^i.*exp(theta*xbar*i).*ord.*b.^(ord-1).*db(:,:,1).*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*b.^ord.*rho^m.*p.*c.^(p-1).*dc(:,:,1)... + )/factorial(ord)/factorial(p);%wrt SE_E + dv(:,2) = dv(:,2) + sum( i.*beta.^(i-1).*exp(theta*xbar*i).*b.^ord.*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*ord.*b.^(ord-1).*db(:,:,2).*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*b.^ord.*rho^m.*p.*c.^(p-1).*dc(:,:,2)... + )/factorial(ord)/factorial(p);%wrt beta + dv(:,3) = dv(:,3) + sum( beta.^i.*exp(theta*xbar*i).*xbar.*i.*b.^ord.*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*ord.*b.^(ord-1).*db(:,:,3).*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*b.^ord.*rho^m.*p.*c.^(p-1).*dc(:,:,3)... + )/factorial(ord)/factorial(p);%wrt theta + dv(:,4) = dv(:,4) + sum( beta.^i.*exp(theta*xbar*i).*b.^ord.*m.*rho^(m-1).*c.^p... + +beta.^i.*exp(theta*xbar*i).*ord.*b.^(ord-1).*db(:,:,4).*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*b.^ord.*rho^m.*p.*c.^(p-1).*dc(:,:,4)... + )/factorial(ord)/factorial(p);%wrt rho + dv(:,5) = dv(:,5) + sum( beta.^i.*exp(theta*xbar*i).*theta.*i.*b.^ord.*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*ord.*b.^(ord-1).*db(:,:,5).*rho^m.*c.^p... + +beta.^i.*exp(theta*xbar*i).*b.^ord.*rho^m.*p.*c.^(p-1).*dc(:,:,5)... + )/factorial(ord)/factorial(p);%wrt xbar + end + end + if abs(v-g(ord+1-m)) > 1e-14 + error(['Error in matrix oo_.dr.g_' num2str(ord)]) + end + chk_dg = squeeze(dg(:,ord+1-m,:))'; + if isempty(indpstderr) + chk_dv = dv(:,M_.exo_nbr+indpmodel); + elseif isempty(indpmodel) + chk_dv = dv(:,1:M_.exo_nbr); + else + chk_dv = dv; + end + fprintf('Max absolute deviation for dg_%d(2,%d,:): %e\n',ord,ord+1-m,norm( chk_dv - chk_dg, Inf)); + if norm( chk_dv - chk_dg, Inf) > tols(k) + error(['Error in matrix dg_' num2str(ord)]) + chk_dv + chk_dg + end + end + end + fprintf('\n'); +end \ No newline at end of file diff --git a/tests/analytic_derivatives/ls2003.mod b/tests/analytic_derivatives/ls2003.mod deleted file mode 100644 index a6cb0e684..000000000 --- a/tests/analytic_derivatives/ls2003.mod +++ /dev/null @@ -1,66 +0,0 @@ -var y y_s R pie dq pie_s de A y_obs pie_obs R_obs; -varexo e_R e_q e_ys e_pies e_A; - -parameters psi1 psi2 psi3 rho_R tau alpha rr k rho_q rho_A rho_ys rho_pies; - -psi1 = 1.54; -psi2 = 0.25; -psi3 = 0.25; -rho_R = 0.5; -alpha = 0.3; -rr = 2.51; -k = 0.5; -tau = 0.5; -rho_q = 0.4; -rho_A = 0.2; -rho_ys = 0.9; -rho_pies = 0.7; - - -model(linear); -y = y(+1) - (tau +alpha*(2-alpha)*(1-tau))*(R-pie(+1))-alpha*(tau +alpha*(2-alpha)*(1-tau))*dq(+1) + alpha*(2-alpha)*((1-tau)/tau)*(y_s-y_s(+1))-A(+1); -pie = exp(-rr/400)*pie(+1)+alpha*exp(-rr/400)*dq(+1)-alpha*dq+(k/(tau+alpha*(2-alpha)*(1-tau)))*y+k*alpha*(2-alpha)*(1-tau)/(tau*(tau+alpha*(2-alpha)*(1-tau)))*y_s; -pie = de+(1-alpha)*dq+pie_s; -R = rho_R*R(-1)+(1-rho_R)*(psi1*pie+psi2*(y+alpha*(2-alpha)*((1-tau)/tau)*y_s)+psi3*de)+e_R; -dq = rho_q*dq(-1)+e_q; -y_s = rho_ys*y_s(-1)+e_ys; -pie_s = rho_pies*pie_s(-1)+e_pies; -A = rho_A*A(-1)+e_A; -y_obs = y-y(-1)+A; -pie_obs = 4*pie; -R_obs = 4*R; -end; - -shocks; - var e_R = 1.25^2; - var e_q = 2.5^2; - var e_A = 1.89; - var e_ys = 1.89; - var e_pies = 1.89; -end; - -varobs y_obs R_obs pie_obs dq de; - -estimated_params; -psi1 , gamma_pdf,1.5,0.5; -psi2 , gamma_pdf,0.25,0.125; -psi3 , gamma_pdf,0.25,0.125; -rho_R ,beta_pdf,0.5,0.2; -alpha ,beta_pdf,0.3,0.1; -rr ,gamma_pdf,2.5,1; -k , gamma_pdf,0.5,0.25; -tau ,gamma_pdf,0.5,0.2; -rho_q ,beta_pdf,0.4,0.2; -rho_A ,beta_pdf,0.5,0.2; -rho_ys ,beta_pdf,0.8,0.1; -rho_pies,beta_pdf,0.7,0.15; -stderr e_R,inv_gamma_pdf,1.2533,0.6551; -stderr e_q,inv_gamma_pdf,2.5066,1.3103; -stderr e_A,inv_gamma_pdf,1.2533,0.6551; -stderr e_ys,inv_gamma_pdf,1.2533,0.6551; -stderr e_pies,inv_gamma_pdf,1.88,0.9827; -end; - -estimation(datafile='../ls2003/data_ca1.m',first_obs=8,nobs=79,mh_nblocks=2, - prefilter=1,mh_jscale=0.5,mh_replic=0, mode_compute=1, analytic_derivation); - diff --git a/tests/analytic_derivatives/nBrockMirmanSYM.mat b/tests/analytic_derivatives/nBrockMirmanSYM.mat new file mode 100644 index 000000000..7bdc38ac0 Binary files /dev/null and b/tests/analytic_derivatives/nBrockMirmanSYM.mat differ diff --git a/tests/discretionary_policy/Gali_discretion.mod b/tests/discretionary_policy/Gali_discretion.mod index 4324a0f47..fc596311e 100644 --- a/tests/discretionary_policy/Gali_discretion.mod +++ b/tests/discretionary_policy/Gali_discretion.mod @@ -130,7 +130,7 @@ end %Compute theoretical objective function V=betta/(1-betta)*(var_pi_theoretical+alpha_x*var_y_gap_theoretical); %evaluate at steady state in first period -if abs(V-oo_.planner_objective_value)>1e-10 +if isnan(oo_.planner_objective_value) || abs(V-oo_.planner_objective_value)>1e-10 error('Computed welfare deviates from theoretical welfare') end end; @@ -144,6 +144,6 @@ end; V=var_pi_theoretical+alpha_x*var_y_gap_theoretical+ betta/(1-betta)*(var_pi_theoretical+alpha_x*var_y_gap_theoretical); %evaluate at steady state in first period discretionary_policy(instruments=(i),irf=20,discretionary_tol=1e-12,planner_discount=betta) y_gap pi p u; -if abs(V-oo_.planner_objective_value)>1e-10 +if isnan(oo_.planner_objective_value) || abs(V-oo_.planner_objective_value)>1e-10 error('Computed welfare deviates from theoretical welfare') end diff --git a/tests/discretionary_policy/dennis_1.mod b/tests/discretionary_policy/dennis_1.mod index 0dd883dc3..993b391d4 100644 --- a/tests/discretionary_policy/dennis_1.mod +++ b/tests/discretionary_policy/dennis_1.mod @@ -29,5 +29,7 @@ var e; stderr 1; end; planner_objective pi_c^2 + y^2; -discretionary_policy(instruments=(i),irf=0,planner_discount=beta); +discretionary_policy(instruments=(i),irf=0,planner_discount=beta, periods=200); +// Generate data used by dennis_1_estim.mod +datatomfile('dennis_simul', {'y'; 'i'; 'pi';}); diff --git a/tests/discretionary_policy/dennis_1_estim.mod b/tests/discretionary_policy/dennis_1_estim.mod new file mode 100644 index 000000000..f869a69e6 --- /dev/null +++ b/tests/discretionary_policy/dennis_1_estim.mod @@ -0,0 +1,43 @@ +/* Test for estimation under discretionary optimal policy. + Uses the data generated by dennis_1.mod */ + +var y i pi pi_c q; +varexo g u e; + +parameters omega kappa sigma beta alpha; + +alpha = 0.4; +beta = 0.99; +sigma = 1; +omega = 0.9; +kappa = 0.3; + +model(linear); +y = y(+1) -(omega/sigma)*(i-pi(+1))+g; +pi = beta*pi(+1)+kappa*y+u; +pi_c = pi+(alpha/(1-alpha))*(q-q(-1)); +q = q(+1)-(1-alpha)*(i-pi(+1))+(1-alpha)*e; +end; + +shocks; + var g; stderr 1; + var u; stderr 1; + var e; stderr 1; +end; + +planner_objective pi_c^2 + y^2; +discretionary_policy(instruments=(i),irf=0,planner_discount=beta); + +varobs y i pi; + +estimated_params; + omega, normal_pdf, 0.9, 0.1; + kappa, normal_pdf, 0.2, 0.1; +end; + +options_.plot_priors=0; +estimation(order = 1, datafile = dennis_simul, mh_replic = 2000, mh_nblocks=1,smoother,bayesian_irf,moments_varendo) y i pi pi_c q; + +if max(abs(oo_.posterior.optimization.mode - [1; 0.3433])) > 0.025 + error('Posterior mode too far from true parameter values'); +end diff --git a/tests/dynare-command-options/ramst.mod b/tests/dynare-command-options/ramst.mod index aa5cecb46..1f3da08e8 100644 --- a/tests/dynare-command-options/ramst.mod +++ b/tests/dynare-command-options/ramst.mod @@ -1,4 +1,4 @@ -// --+ options: json=compute, notmpterms, nolog +-- +// --+ options: json=compute notmpterms nolog +-- var c k; varexo x; diff --git a/tests/epilogue/example1.mod b/tests/epilogue/example1.mod index dc396023f..57fdd0f2f 100644 --- a/tests/epilogue/example1.mod +++ b/tests/epilogue/example1.mod @@ -56,4 +56,4 @@ end; ds = dseries(oo_.endo_simul', 2000Q1, M_.endo_names); ds = [ds dseries(randn(7,1), 2000Q1, 'x')]; -ds = example1.epilogue(M_.params, ds); +ds = example1.epilogue_dynamic(M_.params, ds); diff --git a/tests/estimation/tune_mh_jscale/fs2000.inc b/tests/estimation/tune_mh_jscale/fs2000.inc new file mode 100644 index 000000000..976c2c584 --- /dev/null +++ b/tests/estimation/tune_mh_jscale/fs2000.inc @@ -0,0 +1,97 @@ +/* + * Copyright © 2004-2020 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 . + */ + +var m P c e W R k d n l gy_obs gp_obs y dA; +varexo e_a e_m; + +parameters alp bet gam mst rho psi del; + +alp = 0.33; +bet = 0.99; +gam = 0.003; +mst = 1.011; +rho = 0.7; +psi = 0.787; +del = 0.02; + +model; +dA = exp(gam+e_a); +log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; +-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; +W = l/n; +-(psi/(1-psi))*(c*P/(1-n))+l/n = 0; +R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; +1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; +c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); +P*c = m; +m-1+d = l; +e = exp(e_a); +y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); +gy_obs = dA*y/y(-1); +gp_obs = (P/P(-1))*m(-1)/dA; +end; + +shocks; +var e_a; stderr 0.014; +var e_m; stderr 0.005; +end; + +steady_state_model; + dA = exp(gam); + gst = 1/dA; + m = mst; + khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1)); + xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1); + nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp ); + n = xist/(nust+xist); + P = xist + nust; + k = khst*n; + + l = psi*mst*n/( (1-psi)*(1-n) ); + c = mst/P; + d = l - mst + 1; + y = k^alp*n^(1-alp)*gst^alp; + R = mst/bet; + W = l/n; + ist = y-c; + q = 1 - d; + + e = 1; + + gp_obs = m/dA; + gy_obs = dA; +end; + +steady; + +check; + +estimated_params; +alp, beta_pdf, 0.356, 0.02; +bet, beta_pdf, 0.993, 0.002; +gam, normal_pdf, 0.0085, 0.003; +mst, normal_pdf, 1.0002, 0.007; +rho, beta_pdf, 0.129, 0.100; +psi, beta_pdf, 0.65, 0.05; +del, beta_pdf, 0.01, 0.005; +stderr e_a, inv_gamma_pdf, 0.035449, inf; +stderr e_m, inv_gamma_pdf, 0.008862, inf; +end; + +varobs gp_obs gy_obs; \ No newline at end of file diff --git a/tests/estimation/tune_mh_jscale/fs2000.mod b/tests/estimation/tune_mh_jscale/fs2000.mod index 7986745c2..402ca68a5 100644 --- a/tests/estimation/tune_mh_jscale/fs2000.mod +++ b/tests/estimation/tune_mh_jscale/fs2000.mod @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2018 Dynare Team + * Copyright © 2004-2020 Dynare Team * * This file is part of Dynare. * @@ -17,84 +17,7 @@ * along with Dynare. If not, see . */ -var m P c e W R k d n l gy_obs gp_obs y dA; -varexo e_a e_m; - -parameters alp bet gam mst rho psi del; - -alp = 0.33; -bet = 0.99; -gam = 0.003; -mst = 1.011; -rho = 0.7; -psi = 0.787; -del = 0.02; - -model; -dA = exp(gam+e_a); -log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; --P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; -W = l/n; --(psi/(1-psi))*(c*P/(1-n))+l/n = 0; -R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; -1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; -c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); -P*c = m; -m-1+d = l; -e = exp(e_a); -y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); -gy_obs = dA*y/y(-1); -gp_obs = (P/P(-1))*m(-1)/dA; -end; - -shocks; -var e_a; stderr 0.014; -var e_m; stderr 0.005; -end; - -steady_state_model; - dA = exp(gam); - gst = 1/dA; - m = mst; - khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1)); - xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1); - nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp ); - n = xist/(nust+xist); - P = xist + nust; - k = khst*n; - - l = psi*mst*n/( (1-psi)*(1-n) ); - c = mst/P; - d = l - mst + 1; - y = k^alp*n^(1-alp)*gst^alp; - R = mst/bet; - W = l/n; - ist = y-c; - q = 1 - d; - - e = 1; - - gp_obs = m/dA; - gy_obs = dA; -end; - -steady; - -check; - -estimated_params; -alp, beta_pdf, 0.356, 0.02; -bet, beta_pdf, 0.993, 0.002; -gam, normal_pdf, 0.0085, 0.003; -mst, normal_pdf, 1.0002, 0.007; -rho, beta_pdf, 0.129, 0.100; -psi, beta_pdf, 0.65, 0.05; -del, beta_pdf, 0.01, 0.005; -stderr e_a, inv_gamma_pdf, 0.035449, inf; -stderr e_m, inv_gamma_pdf, 0.008862, inf; -end; - -varobs gp_obs gy_obs; +@#include "fs2000.inc" estimation(order=1, datafile='../fsdat_simul', nobs=192, loglinear, mh_replic=20000, mh_nblocks=2, mh_tune_jscale=0.33); @@ -102,4 +25,4 @@ mhdata = load('fs2000/metropolis/fs2000_mh_history_0.mat'); if any(abs(mhdata.record.AcceptanceRatio-options_.mh_tune_jscale.target)>options_.mh_tune_jscale.c2) error('Automagic tuning of the MCMC proposal scale parameter did not work as expected!') -end \ No newline at end of file +end diff --git a/tests/estimation/tune_mh_jscale/fs2000_1_xfail.mod b/tests/estimation/tune_mh_jscale/fs2000_1_xfail.mod new file mode 100644 index 000000000..d8ee3d16f --- /dev/null +++ b/tests/estimation/tune_mh_jscale/fs2000_1_xfail.mod @@ -0,0 +1,22 @@ +/* + * Copyright © 2020 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 . + */ + +@#include "fs2000.inc" + +estimation(order=1, datafile='../fsdat_simul', nobs=192, loglinear, mh_jscale=0.2, mh_replic=20000, mh_nblocks=2, mh_tune_jscale=0.33); diff --git a/tests/estimation/tune_mh_jscale/fs2000_2_xfail.mod b/tests/estimation/tune_mh_jscale/fs2000_2_xfail.mod new file mode 100644 index 000000000..dfb311b0a --- /dev/null +++ b/tests/estimation/tune_mh_jscale/fs2000_2_xfail.mod @@ -0,0 +1,22 @@ +/* + * Copyright © 2020 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 . + */ + +@#include "fs2000.inc" + +estimation(order=1, datafile='../fsdat_simul', nobs=192, loglinear, mh_replic=20000, mh_nblocks=2, mh_tune_guess=0.33); diff --git a/tests/example1_macro.mod b/tests/example1_macro.mod index be5da189c..45ad345c4 100644 --- a/tests/example1_macro.mod +++ b/tests/example1_macro.mod @@ -40,7 +40,15 @@ phi = 0.1; @#define w = w + [ elt ] @#endfor @#if w != [ 1, "a", 1, 2:3] -@#error "For loop problem" +@#error "For loop problem 1" +@#endif + +@#define w = [ ] +@#for (i,j) in [(1,2),(1,3),(1,4)] +@#define w = w + [i, j] +@#endfor +@#if w != [ 1, 2, 1, 3, 1, 4] +@#error "For loop problem 2" @#endif @#define s = "abcde" @@ -169,8 +177,8 @@ stoch_simul; @#error "String comparison" @#endif -@#define A = "La crise conomique" -@#if A[1,8,3,7,4,10,13,2,5,16,12,9,11,14,15,6,17:19] != "Le scnario comique" +@#define A = "La crise economique" +@#if A[1,8,3,7,4,10,13,2,5,16,12,9,11,14,15,6,17:19] != "Le scenario comique" @#error "Problem with string indexing/comparison" @#endif @@ -218,5 +226,9 @@ stoch_simul; @#error "Error in cast of string to bool" @#endif +@#if !(true || "A") || (0 && "A") + @#error "problem with short circuit || or && operator" +@#endif + @#echomacrovars(save) @#echomacrovars diff --git a/tests/histval_predetermined.mod b/tests/histval_predetermined.mod new file mode 100644 index 000000000..51ac05cf8 --- /dev/null +++ b/tests/histval_predetermined.mod @@ -0,0 +1,60 @@ +/* Check that histval and predetermined_variables interact correctly, in the + case where no explicit lag appears in the model block (though lags appear + implicitly via the “predetermined_variables” statement). + + This is a regression test for preprocessor#47. +*/ + +var y, c, k, a, h, b; +varexo e, u; + +predetermined_variables a b k; + +parameters beta, rho, alpha, delta, theta, psi, tau; + +alpha = 0.36; +rho = 0.95; +tau = 0.025; +beta = 0.99; +delta = 0.025; +psi = 0; +theta = 2.95; + +phi = 0.1; + +model; +c*theta*h^(1+psi)=(1-alpha)*y; +k(+1) = beta*(((exp(b(+1))*c)/(exp(b(+2))*c(+1))) + *(exp(b(+2))*alpha*y(+1)+(1-delta)*k(+1))); +y = exp(a(+1))*(k^alpha)*(h^(1-alpha)); +k = exp(b(+1))*(y-c)+(1-delta)*k; +a(+1) = rho*a+ e; +b(+1) = rho*b+ u; +end; + +initval; +y = 1.08068253095672; +c = 0.80359242014163; +h = 0.29175631001732; +k = 11.08360443260358; +a = 0; +b = 0; +e = 0; +u = 0; +end; + +shocks; +var e; stderr 0.009; +var u; stderr 0.009; +var e, u = phi*0.009*0.009; +end; + +histval; +b(0) = 0.1; +a(0) = 0.3; +end; + +stoch_simul(nograph, periods = 200); + +forecast; + diff --git a/tests/identification/BrockMirman/BrockMirman.mod b/tests/identification/BrockMirman/BrockMirman.mod index 92d09e2ab..dfb56bd7d 100644 --- a/tests/identification/BrockMirman/BrockMirman.mod +++ b/tests/identification/BrockMirman/BrockMirman.mod @@ -1,7 +1,22 @@ -% ========================================================================= % Stochastic growth model of Brock and Mirman (1972) with technology shock -% Willi Mutschler, January 2018 -% willi@mutschler.eu +% created by Willi Mutschler (@wmutschl, willi@mutschler.eu) +% ========================================================================= +% Copyright (C) 2019-2020 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 . % ========================================================================= var diff --git a/tests/identification/LindeTrabandt/LindeTrabandt2019_xfail.mod b/tests/identification/LindeTrabandt/LindeTrabandt2019_xfail.mod new file mode 100644 index 000000000..9494da438 --- /dev/null +++ b/tests/identification/LindeTrabandt/LindeTrabandt2019_xfail.mod @@ -0,0 +1,388 @@ +% Original model by: J. Linde, M. Trabandt (2019: Should We Use Linearized Models to Calculate Fiscal Multipliers? +% Journal of Applied Econometrics, 2018, 33: 937-965. http://dx.doi.org/10.1002/jae.2641 +% This version has some additional dynamics for capital and investment +% Created by Willi Mutschler (@wmutschl, willi@mutschler.eu) +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= +% ========================================================================= +% Declare endogenous variables +% ========================================================================= + +var + % Staggered-price economy + c ${c}$ (long_name='consumption') + lam ${\lambda}$ (long_name='lagrange multiplier budget') + n ${n}$ (long_name='labor') + w ${w}$ (long_name='real wage') + r ${r}$ (long_name='interest rate') + pie ${\pi}$ (long_name='inflation') + y ${y}$ (long_name='output') + pstar ${p^\ast}$ (long_name='price dispersion') + vartheta ${\vartheta}$ (long_name='aggregate price index') + mc ${mc}$ (long_name='marginal costs') + s ${s}$ (long_name='auxiliary variable for nonlinear pricing 1') + f ${f}$ (long_name='auxiliary variable for nonlinear pricing 2') + a ${a}$ (long_name='auxiliary variable for nonlinear pricing 3') + ptilde ${\tilde{p}}$ (long_name='reoptimized price') + delta1 ${\Delta_1}$ (long_name='price dispersion 1') + delta2 ${\Delta_2}$ (long_name='price dispersion 2') + delta3 ${\Delta_3}$ (long_name='price dispersion 3') + b ${b}$ (long_name='bonds') + tau ${\tau}$ (long_name='lump-sum tax') + g + nu %consumption preference shock + + % Flex-price economy + cpot ${c^{pot}}$ (long_name='flex-price consumption') + npot ${n^{pot}}$ (long_name='flex-price labor') + wpot ${w^{pot}}$ (long_name='flex-price real wage') + rrpot ${r^{pot}}$ (long_name='flex-price interest rate') + ypot ${y^{pot}}$ (long_name='flex-price output') + bpot ${b^{pot}}$ (long_name='flex-price bonds') + taupot ${\tau^{pot}}$ (long_name='flex-price lump-sum tax') + + % Added variables for capital and investment + k ${k}$ (long_name='capital') + rk ${r^{K}}$ (long_name='rental rate on capital') + iv ${i}$ (long_name='investment') + q ${q}$ (long_name='Tobins Q') + kpot ${k^{pot}}$ (long_name='flex-price capital') + rkpot ${r^{K,pot}}$ (long_name='flex-price rental rate on capital') + ivpot ${i^{pot}}$ (long_name='flex-price investment') +; + +% ========================================================================= +% Declare observable variables +% ========================================================================= +varobs c y; + +% ========================================================================= +% Declare exogenous variables +% ========================================================================= +varexo +epsg +epsnu + ; + +% ========================================================================= +% Declare parameters +% ========================================================================= +parameters + ALPHA ${\alpha}$ (long_name='capital share') + BETA ${\beta}$ (long_name='discount rate') + PIEBAR ${\bar{\pi}}$ (long_name='target inflation rate') + IOTA ${\iota}$ (long_name='indexation') + CHI ${\chi}$ (long_name='inverse frisch elasticity') + THETAP ${\theta_p}$ (long_name='net markup') + XIP ${\xi_p}$ (long_name='Calvo probability') + PSI ${\psi}$ (long_name='Kimbal curvature') + GAMMAPIE ${\gamma_\pi}$ (long_name='Taylor rule parameter inflation') + GAMMAX ${\gamma_x}$ (long_name='Taylor rule parameter output') + DELTA ${\delta}$ (long_name='depreciation rate') + QBAR ${\bar{Q}}$ (long_name='steady state Q') + NUBAR ${\bar{\nu}}$ (long_name='steady state consumption preference shock') + BBAR %government debt to annualized output ratio + GBAR_o_YBAR % government consumption ratio + TAUBAR + TAUNBAR + PHI + RHONU + RHOG + SIGNU + SIGG +; + + +% ========================================================================= +% Calibration +% ========================================================================= +BETA = 0.995; +PIEBAR = 1 + 0.005; +ALPHA = 0.3; +NUBAR = 0;%0.01; +BBAR = 0;%0.6; +GBAR_o_YBAR = 0;%0.2; +TAUBAR = 0; +PHI = 0.0101; +IOTA = 0.5; +CHI = 1/0.4; +XIP = 2/3; +PSI = -12.2; +THETAP = 0.1; +GAMMAPIE = 1.5; +GAMMAX = 0.125; +QBAR=1; +DELTA = 0;%0.025; +RHONU = 0.95; +RHOG = 0.95; +SIGG = 0.6/100; +SIGNU = 0.6/100; +TAUNBAR = 0; + +% ======================================================================== +% Model equations +% ========================================================================= +model; +% ------------------------------------------------------------------------- +% Auxiliary expressions +% ------------------------------------------------------------------------- +#OMEGAP = (1+THETAP)*(1+PSI)/(1+PSI+THETAP*PSI); %gross markup +#gammap = pie^IOTA*PIEBAR^(1-IOTA); %indexation rule +%#gammap = PIEBAR; +% ------------------------------------------------------------------------- +% Added equations for capital and investment +% ------------------------------------------------------------------------- +[name='foc household wrt i'] +lam = lam*q; +[name='foc household wrt k'] +lam*q = BETA*lam(+1)*(rk(+1)+ (1-DELTA)*q(+1) ); +[name='capital accumulation'] +k = (1-DELTA)*k(-1) + iv; +[name='capital demand'] +rk=ALPHA*mc*y/k(-1); + +[name='flex price foc household wrt k'] +(cpot-steady_state(cpot)*nu)^(-1) = BETA*(cpot(+1)-steady_state(cpot)*nu(+1))^(-1)*(rkpot(+1) + (1-DELTA) ); +[name='flex price capital accumulation'] +kpot = (1-DELTA)*kpot(-1) + ivpot; +[name='flex price capital demand'] +rkpot=ALPHA/(1+THETAP)*(npot/kpot(-1))^(1-ALPHA); + +% ------------------------------------------------------------------------- +% Actual model equations +% ------------------------------------------------------------------------- +[name='foc household wrt c (marginal utility)'] +(c-steady_state(c)*nu)^(-1) = lam; + +[name='foc household wrt l (leisure vs. labor)'] +n^CHI = (1-TAUNBAR)*lam*w; + +[name='foc household wrt b (Euler equation)'] +lam = BETA*r/pie(+1)*lam(+1); + +[name='aggregate resource constraint'] +y = c + g + iv; + +[name='production function'] +y=pstar^(-1)*k(-1)^ALPHA*n^(1-ALPHA); + +[name='Nonlinear pricing 1'] +s = OMEGAP*lam*y*vartheta^(OMEGAP/(OMEGAP-1))*mc + BETA*XIP*(gammap/pie(+1))^(OMEGAP/(1-OMEGAP))*s(+1); + +[name='Nonlinear pricing 2'] +f = lam*y*vartheta^(OMEGAP/(OMEGAP-1)) + BETA*XIP*(gammap/pie(+1))^(1/(1-OMEGAP))*f(+1); + +[name='Nonlinear pricing 3'] +a = PSI*(OMEGAP-1)*lam*y + BETA*XIP*(gammap/pie(+1))*a(+1); + +[name='Nonlinear pricing 4'] +s = f*ptilde -a*ptilde^(1+OMEGAP/(OMEGAP-1)); + +[name='zero profit condition'] +vartheta = 1 + PSI - PSI*delta2; + +[name='aggregate price index'] +vartheta = delta3; + +[name='overall price dispersion'] +pstar = 1/(1+PSI)*vartheta^(OMEGAP/(OMEGAP-1))*delta1^(OMEGAP/(1-OMEGAP)) + PSI/(1+PSI); + +[name='price dispersion 1'] +delta1^(OMEGAP/(1-OMEGAP)) = (1-XIP)*ptilde^(OMEGAP/(1-OMEGAP)) + XIP*(gammap/pie*delta1(-1))^(OMEGAP/(1-OMEGAP)); + +[name='price dispersion 2'] +delta2 = (1-XIP)*ptilde+XIP*gammap/pie*delta2(-1); + +[name='price dispersion 3'] +delta3^(1/(1-OMEGAP)) = (1-XIP)*ptilde^(1/(1-OMEGAP)) + XIP*(gammap/pie*delta3(-1))^(1/(1-OMEGAP)); + +[name='marginal costs'] +(1-ALPHA)*mc = w*k(-1)^(-ALPHA)*n^ALPHA; + +[name='Taylor Rule'] +r = steady_state(r)*(pie/PIEBAR)^GAMMAPIE*( (y/steady_state(y))/(ypot/steady_state(ypot)) )^GAMMAX; + +[name='government budget'] +b = r(-1)/pie*b(-1) + g/steady_state(y) -TAUNBAR*w*n/steady_state(y) - tau; + +[name='fiscal rule'] +tau = TAUBAR + PHI*(b(-1)-BBAR); + +[name='flex price Euler equation'] +(cpot-steady_state(cpot)*nu)^(-1) = BETA*rrpot*(cpot(+1)-steady_state(cpot)*nu(+1))^(-1); + +[name='flex price foc household wrt l (leisure vs. labor)'] +npot^CHI = (1-TAUNBAR)*(cpot-steady_state(cpot)*nu)^(-1)*wpot; + +[name='flex price wage'] +(1-ALPHA)/(1+THETAP)*kpot(-1)^ALPHA = wpot*npot^ALPHA; + +[name='flex price aggregate resource constraint'] +ypot = cpot + g + ivpot; + +[name='flex price production function'] +ypot=kpot(-1)^ALPHA*npot^(1-ALPHA); + +[name='flex price government budget'] +bpot = rrpot(-1)*bpot(-1) + g/steady_state(y) -TAUNBAR*wpot*npot/steady_state(y) - taupot; + +[name='fiscal rule '] +taupot = TAUBAR + PHI*(bpot(-1)-BBAR); + +g/steady_state(y) - GBAR_o_YBAR = RHOG*(g(-1)/steady_state(y) - GBAR_o_YBAR) + epsg; +nu - NUBAR = RHONU*(nu(-1) - NUBAR) + epsnu; +end; + + +% ========================================================================= +% Steady state using a steady_state_model block +% ========================================================================= + +steady_state_model; +OMEGP = (1+THETAP)*(1+PSI)/(1+PSI+THETAP*PSI); +q = QBAR; +pie = PIEBAR; +GAMMAP = PIEBAR^IOTA*PIEBAR^(1-IOTA); +b = BBAR; +tau = TAUBAR; +taun = TAUNBAR; +nu = NUBAR; +r = pie/BETA; +RK = (1/BETA+DELTA-1)*q; % foc k +aux1 = ( (1-XIP)/(1-XIP*(GAMMAP/pie)^(1/(1-OMEGP)) ) )^(1-OMEGP); +aux2 = (1-XIP)/(1-XIP*(GAMMAP/pie)); +ptilde = (1+PSI)/ ( aux1 + PSI*aux2 ); +delta2 = aux2*ptilde; +delta3 = aux1*ptilde; +vartheta = delta3; +delta1 = ( (1-XIP)/(1-XIP*(GAMMAP/pie)^(OMEGP/(1-OMEGP) )) )^((1-OMEGP)/OMEGP)*ptilde; +pstar = 1/(1+PSI)*vartheta^(OMEGP/(OMEGP-1))*delta1^(OMEGP/(1-OMEGP)) + PSI/(1+PSI); +f_o_a = ( vartheta^(OMEGP/(OMEGP-1)) / (1-BETA*XIP*(GAMMAP/pie)^(1/(1-OMEGP))) ) / ( PSI*(OMEGP-1) /(1-BETA*XIP*GAMMAP/pie) ); +s_o_a = ( OMEGP*vartheta^(OMEGP/(OMEGP-1)) / (1-BETA*XIP*(GAMMAP/pie)^(OMEGP/(1-OMEGP))) ) / ( PSI*(OMEGP-1) /(1-BETA*XIP*GAMMAP/pie) ); +mc = (f_o_a*ptilde-ptilde^(1+OMEGP/(OMEGP-1)))*s_o_a^(-1); + +k_o_n = (RK/(mc*ALPHA))^(1/(ALPHA-1)); +w = (1-ALPHA)*mc*k_o_n^ALPHA; % labor demand +y_o_n = pstar^(-1)*k_o_n^ALPHA; % production function +iv_o_n = DELTA*k_o_n; +iv_o_y = iv_o_n / y_o_n; +g_o_y = GBAR_o_YBAR; +c_o_n = y_o_n - iv_o_n - g_o_y; % market clearing + +% The labor level, closed-form solution for labor +n = (c_o_n^(-1)*w)^(1/(CHI+1)) ; +% Value of remaining variables +c = c_o_n*n; +rk = RK; + + +iv = iv_o_n *n; +k = k_o_n*n; +y = y_o_n*n; +lam = n^CHI/w; +g = g_o_y*y; +a = PSI*(OMEGP-1)*y*lam/(1-BETA*XIP*GAMMAP/pie); +f = f_o_a*a; +s = f*ptilde - a*ptilde^(1+OMEGP/(OMEGP-1)); + +%flex price economy +bpot = BBAR; +taupot = TAUBAR; +taun = TAUNBAR; + +rrpot = 1/BETA; +RKpot = (1/BETA+DELTA-1)*QBAR; % foc k +rkpot = RKpot; + +kpot_o_npot = (RKpot/(ALPHA/(1+THETAP)))^(1/(ALPHA-1)); +wpot = (1-ALPHA)/(1+THETAP)*kpot_o_npot^ALPHA; % labor demand +ypot_o_npot = kpot_o_npot^ALPHA; % production function +ivpot_o_npot = DELTA*kpot_o_npot; +ivpot_o_ypot = ivpot_o_npot / ypot_o_npot; +cpot_o_npot = ypot_o_npot - ivpot_o_npot - g_o_y; % market clearing +% The labor level, closed-form solution for labor +npot = (cpot_o_npot^(-1)*wpot)^(1/(CHI+1)) ; +% Value of remaining variables +cpot = cpot_o_npot*npot; +ivpot = ivpot_o_npot *npot; +kpot = kpot_o_npot*npot; +ypot = ypot_o_npot*npot; + +end; + + + +% ========================================================================= +% Declare settings for shocks +% ========================================================================= +shocks; +var epsg = 1; +var epsnu = 1; +end; + +estimated_params; +ALPHA, 0.3, normal_pdf, 0.3 , 0.1; +BETA, 0.995, normal_pdf, 0.995, 0.1; +PIEBAR, 1.005, normal_pdf, 1.005, 0.1; +IOTA, 0.5, normal_pdf, 0.5, 0.1; +CHI, 1/0.4, normal_pdf, 1/0.4, 0.1; +THETAP, 0.1, normal_pdf, 0.1, 0.1; +XIP, 2/3, normal_pdf, 2/3, 0.1; +PSI, -12.2, normal_pdf, -12.2, 0.1; +GAMMAPIE, 1.5, normal_pdf, 1.5, 0.1; +GAMMAX, 0.125, normal_pdf, 0.125, 0.1; +DELTA, 0, normal_pdf, 0, 0.1; +QBAR, 1, normal_pdf, 1, 0.1; +NUBAR, 0, normal_pdf, 0, 0.1; +BBAR, 0, normal_pdf, 0, 0.1; +GBAR_o_YBAR, 0, normal_pdf, 0, 0.1; %commenting this solves the analytic_derivation_mode=-2|-1 problem +TAUBAR, 0, normal_pdf, 0, 0.1; +TAUNBAR, 0, normal_pdf, 0, 0.1; +PHI, 0.0101, normal_pdf, 0.0101, 0.1; +RHONU, 0.95, normal_pdf, 0.95, 0.1; +RHOG, 0.95, normal_pdf, 0.95, 0.1; +SIGNU, 0.6/100, normal_pdf, 0.6/100, 0.1; +SIGG, 0.6/100, normal_pdf, 0.6/100, 0.1; +end; + + +% ========================================================================= +% Computations +% ========================================================================= +model_diagnostics; +steady; +resid; +check; + +/* Skip test under MATLAB R2009b + MATLAB crashes, most likely due to an internal bug */ +if isoctave || ~matlab_ver_less_than('7.10') + +identification(order=1,no_identification_strength,analytic_derivation_mode= 0,ar=5); %works +%identification(no_identification_strength,analytic_derivation_mode= 1,ar=5); %works, this takes the longest due to Kronecker products +options_.dynatol.x = 1e-9; +identification(order=1,no_identification_strength,analytic_derivation_mode=-1,ar=5); %works, but tolerance is way too small +identification(order=1,no_identification_strength,analytic_derivation_mode=-2,ar=5); %works, but tolerance is way to small +options_.dynatol.x = 1e-5; %this is the default value +identification(order=1,no_identification_strength,analytic_derivation_mode=-1,ar=5); %works only if GBAR_o_YBAR is uncommented +identification(order=1,no_identification_strength,analytic_derivation_mode=-2,ar=5); %works only if GBAR_o_YBAR is uncommented + +else % Skip test under old MATLAB + error('Test failed as expected') +end diff --git a/tests/identification/as2007/G_QT.mat b/tests/identification/as2007/G_QT.mat new file mode 100644 index 000000000..74b7e7399 Binary files /dev/null and b/tests/identification/as2007/G_QT.mat differ diff --git a/tests/identification/as2007/as2007.mod b/tests/identification/as2007/as2007.mod index f33a937e3..bdae07a4b 100644 --- a/tests/identification/as2007/as2007.mod +++ b/tests/identification/as2007/as2007.mod @@ -1,3 +1,24 @@ +% Model of An and Schorfheide (2007) +% Created by Marco Ratto (@rattoma, marco.ratto@ec.europa.eu) +% ========================================================================= +% Copyright (C) 2010-2020 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 . +% ========================================================================= + var pie y R g z YGR INFL INT; varexo e_R e_g e_z; parameters tau kap psi1 psi2 rhoR rhog rhoz rr_steady pi_steady gam_steady std_R std_g std_z; diff --git a/tests/identification/as2007/as2007_QT.mod b/tests/identification/as2007/as2007_QT.mod index 8b7cfa35e..4f0d9d3db 100644 --- a/tests/identification/as2007/as2007_QT.mod +++ b/tests/identification/as2007/as2007_QT.mod @@ -1,7 +1,28 @@ % this is the exact model Qu and Tkachenk (2012, Quantitative Economics) % used in their replication file. % This file is used to check whether the G matrix is computed correctly. -% Created by Willi Mutschler (willi@mutschler.eu) +% Created by Willi Mutschler (@wmutschl, willi@mutschler.eu) +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= + +@#define TOL_RANK = 1e-10 + var z g R y pie c piep yp; varexo e_z e_g e_R ; parameters tau betta nu phi pistar psi1 psi2 rhor rhog rhoz sig2r sig2g sig2z; @@ -72,26 +93,26 @@ identification(parameter_set=calibration, no_identification_reducedform, no_identification_moments, checks_via_subsets=1, + tol_rank=@{TOL_RANK}, max_dim_subsets_groups=4); -% load('G_QT'); %note that this is computed using replication files of Qu and Tkachenko (2012) -% temp = load([M_.dname filesep 'identification' filesep M_.fname '_identif']); -% G_dynare = temp.ide_spectrum_point.G; -% -% % Compare signs -% if ~isequal(sign(G_dynare),sign(G_QT)) -% error('signs of normalized G are note equal'); -% end -% -% % Compare normalized versions -% tilda_G_dynare = temp.ide_spectrum_point.tilda_G; -% ind_G_QT = (find(max(abs(G_QT'),[],1) > temp.store_options_ident.tol_deriv)); -% tilda_G_QT = zeros(size(G_QT)); -% delta_G_QT = sqrt(diag(G_QT(ind_G_QT,ind_G_QT))); -% tilda_G_QT(ind_G_QT,ind_G_QT) = G_QT(ind_G_QT,ind_G_QT)./((delta_G_QT)*(delta_G_QT')); -% if ~isequal(rank(tilda_G_QT,temp.store_options_ident.tol_rank),rank(tilda_G_dynare,temp.store_options_ident.tol_rank)) -% error('ranks are not the same for normalized version') -% end -% -% max(max(abs(abs(tilda_G_dynare)-abs(tilda_G_QT)))) -% norm(tilda_G_dynare - tilda_G_QT) +load('G_QT'); %note that this is computed using replication files of Qu and Tkachenko (2012) +temp = load([M_.dname filesep 'identification' filesep M_.fname '_identif']); +G_dynare = temp.ide_spectrum_point.dSPECTRUM; +% Compare signs +if ~isequal(sign(G_dynare),sign(G_QT)) + error('signs of normalized G are note equal'); +end + +% Compare normalized versions +tilda_G_dynare = temp.ide_spectrum_point.tilda_dSPECTRUM; +ind_G_QT = (find(max(abs(G_QT'),[],1) > temp.store_options_ident.tol_deriv)); +tilda_G_QT = zeros(size(G_QT)); +delta_G_QT = sqrt(diag(G_QT(ind_G_QT,ind_G_QT))); +tilda_G_QT(ind_G_QT,ind_G_QT) = G_QT(ind_G_QT,ind_G_QT)./((delta_G_QT)*(delta_G_QT')); +if ~isequal(rank(tilda_G_QT,@{TOL_RANK}),rank(tilda_G_dynare,@{TOL_RANK})) + error('ranks are not the same for normalized version') +end + +max(max(abs(abs(tilda_G_dynare)-abs(tilda_G_QT)))) +norm(tilda_G_dynare - tilda_G_QT) diff --git a/tests/identification/as2007/as2007_kronflags.mod b/tests/identification/as2007/as2007_kronflags.mod index ff1bb4de4..33ff9a0b8 100644 --- a/tests/identification/as2007/as2007_kronflags.mod +++ b/tests/identification/as2007/as2007_kronflags.mod @@ -1,7 +1,25 @@ %this is the mod file used in replication files of An and Schorfheide (2007) % modified to include some obvious and artificial identification failures % and to check whether all kronflags are working -% created by Willi Mutschler (willi@mutschler.eu) +% created by Willi Mutschler (@wmutschl, willi@mutschler.eu) +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= var y R g z c dy p YGR INFL INT; varobs y R p; diff --git a/tests/identification/as2007/as2007_order3_no_stoch_simul.mod b/tests/identification/as2007/as2007_order3_no_stoch_simul.mod new file mode 100644 index 000000000..b01d36e5e --- /dev/null +++ b/tests/identification/as2007/as2007_order3_no_stoch_simul.mod @@ -0,0 +1,106 @@ +% This is a regression test for issue preprocessor#40 +% (“identification” without “stoch_simul”) + +%this is the mod file used in replication files of An and Schorfheide (2007) +% modified to include some obvious and artificial identification failures +% and to check whether all kronflags are working +% created by Willi Mutschler (willi@mutschler.eu) + +var y R g z c dy p YGR INFL INT; +varobs y R g z c dy p YGR INFL INT; +varexo e_r e_g e_z; +parameters sigr sigg sigz tau phi psi1 psi2 rhor rhog rhoz rrst pist gamst nu cyst dumpy dumpyrhog; + +rrst = 1.0000; +pist = 3.2000; +gamst= 0.5500; +tau = 2.0000; +nu = 0.1000; +kap = 0.3300; +phi = tau*(1-nu)/nu/kap/exp(pist/400)^2; +cyst = 0.8500; +psi1 = 1.5000; +psi2 = 0.1250; +rhor = 0.7500; +rhog = 0.9500; +rhoz = 0.9000; +sigr = 0.2; +sigg = 0.6; +sigz = 0.3; +dumpy = 0; +dumpyrhog = 1; + +model; +#pist2 = exp(pist/400); +#rrst2 = exp(rrst/400); +#bet = 1/rrst2; +#gst = 1/cyst; +#cst = (1-nu)^(1/tau); +#yst = cst*gst; +1 = exp(-tau*c(+1)+tau*c+R-z(+1)-p(+1)); +(1-nu)/nu/phi/(pist2^2)*(exp(tau*c)-1) = (exp(p)-1)*((1-1/2/nu)*exp(p)+1/2/nu) - bet*(exp(p(+1))-1)*exp(-tau*c(+1)+tau*c+dy(+1)+p(+1)); +exp(c-y) = exp(-g) - phi*pist2^2*gst/2*(exp(p)-1)^2; +R = rhor*R(-1) + (1-rhor)*psi1*p + (1-rhor)*psi2*(y-g) + sigr*e_r; +g = dumpyrhog*rhog*g(-1) + sigg*e_g; +z = rhoz*z(-1) + sigz*e_z; +YGR = gamst+100*(dy+z); +INFL = pist+400*p; +INT = pist+rrst+4*gamst+400*R; +dy = y - y(-1); +end; + +shocks; +var e_r = 0.6^2; +var e_g = 0.5^2; +var e_z = 0.4^2; +corr e_r, e_g = 0.3; +corr e_r, e_z = 0.2; +corr e_z, e_g = 0.1; +end; + +steady_state_model; +z=0; g=0; c=0; y=0; p=0; R=0; dy=0; +YGR=gamst; INFL=pist; INT=pist+rrst+4*gamst; +end; + +estimated_params; +tau, 2, 1e-5, 10, gamma_pdf, 2, 0.5; + +%these parameters do not enter the linearized solution +cyst, 0.85, 1e-5, 0.99999, beta_pdf, 0.85, 0.1; +sigg, 0.6, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +rhoz, 0.9, 1e-5, 0.99999, beta_pdf, 0.66, 0.15; +corr e_r,e_g, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +corr e_z,e_g, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +corr e_z,e_r, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; + +%these parameters could only be identified from the steady state of YGR INFL and INT, however, we observer y pi R instead +rrst, 1, 1e-5, 10, gamma_pdf, 0.8, 0.5; +gamst, 0.55, -5, 5, normal_pdf, 0.4, 0.2; +dumpy, 0, -10, 10, normal_pdf, 0, 1; + +%these parameters jointly determine the slope kappa of the linearized new keynesian phillips curve +pist, 3.2, 1e-5, 20, gamma_pdf, 4, 2; +nu, 0.1, 1e-5, 0.99999, beta_pdf, 0.1, .05; +phi, 50, 1e-5, 100, gamma_pdf, 50, 20; + +%these parameters are pairwise collinear as one should not use both formulations for the standard error of a shock +sigz, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +stderr e_z, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; + +%these parameters are pairwise collinear as they are multiplicative +rhog, 0.95, 1e-5, 0.99999, beta_pdf, 0.8, 0.1; +dumpyrhog, 1, -10, 10, normal_pdf, 1, 1; + +%these parameters are jointly not identified due to the specification of the Taylor rule +psi1, 1.5, 1e-5, 10, gamma_pdf, 1.5, 0.25; +psi2, 0.125, 1e-5, 10, gamma_pdf, 0.5, 0.25; +rhor, 0.75, 1e-5, 0.99999, beta_pdf, 0.5, 0.2; +stderr e_r, 0.2, 1e-8, 5, inv_gamma_pdf, 0.3, 4; + +end; + +steady; +check; + +identification(order=3, parameter_set=calibration, grid_nbr=10); diff --git a/tests/identification/as2007/as2007_order_1_2_3.mod b/tests/identification/as2007/as2007_order_1_2_3.mod new file mode 100644 index 000000000..012c7e00d --- /dev/null +++ b/tests/identification/as2007/as2007_order_1_2_3.mod @@ -0,0 +1,127 @@ +%this is the mod file used in replication files of An and Schorfheide (2007) +% modified to include some obvious and artificial identification failures +% and to check whether all kronflags are working +% created by Willi Mutschler (@wmutschl, willi@mutschler.eu) +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= + +var y R g z c dy p YGR INFL INT; +varobs y R g z c dy p YGR INFL INT; +varexo e_r e_g e_z; +parameters sigr sigg sigz tau phi psi1 psi2 rhor rhog rhoz rrst pist gamst nu cyst dumpy dumpyrhog; + +rrst = 1.0000; +pist = 3.2000; +gamst= 0.5500; +tau = 2.0000; +nu = 0.1000; +kap = 0.3300; +phi = tau*(1-nu)/nu/kap/exp(pist/400)^2; +cyst = 0.8500; +psi1 = 1.5000; +psi2 = 0.1250; +rhor = 0.7500; +rhog = 0.9500; +rhoz = 0.9000; +sigr = 0.2; +sigg = 0.6; +sigz = 0.3; +dumpy = 0; +dumpyrhog = 1; + +model; +#pist2 = exp(pist/400); +#rrst2 = exp(rrst/400); +#bet = 1/rrst2; +#gst = 1/cyst; +#cst = (1-nu)^(1/tau); +#yst = cst*gst; +1 = exp(-tau*c(+1)+tau*c+R-z(+1)-p(+1)); +(1-nu)/nu/phi/(pist2^2)*(exp(tau*c)-1) = (exp(p)-1)*((1-1/2/nu)*exp(p)+1/2/nu) - bet*(exp(p(+1))-1)*exp(-tau*c(+1)+tau*c+dy(+1)+p(+1)); +exp(c-y) = exp(-g) - phi*pist2^2*gst/2*(exp(p)-1)^2; +R = rhor*R(-1) + (1-rhor)*psi1*p + (1-rhor)*psi2*(y-g) + sigr*e_r; +g = dumpyrhog*rhog*g(-1) + sigg*e_g; +z = rhoz*z(-1) + sigz*e_z; +YGR = gamst+100*(dy+z); +INFL = pist+400*p; +INT = pist+rrst+4*gamst+400*R; +dy = y - y(-1); +end; + +shocks; +var e_r = 0.6^2; +var e_g = 0.5^2; +var e_z = 0.4^2; +corr e_r, e_g = 0.3; +corr e_r, e_z = 0.2; +corr e_z, e_g = 0.1; +end; + +steady_state_model; +z=0; g=0; c=0; y=0; p=0; R=0; dy=0; +YGR=gamst; INFL=pist; INT=pist+rrst+4*gamst; +end; + +estimated_params; +tau, 2, 1e-5, 10, gamma_pdf, 2, 0.5; + +%these parameters do not enter the linearized solution +cyst, 0.85, 1e-5, 0.99999, beta_pdf, 0.85, 0.1; +sigg, 0.6, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +rhoz, 0.9, 1e-5, 0.99999, beta_pdf, 0.66, 0.15; +corr e_r,e_g, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +corr e_z,e_g, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +corr e_z,e_r, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; + +%these parameters could only be identified from the steady state of YGR INFL and INT, however, we observer y pi R instead +rrst, 1, 1e-5, 10, gamma_pdf, 0.8, 0.5; +gamst, 0.55, -5, 5, normal_pdf, 0.4, 0.2; +dumpy, 0, -10, 10, normal_pdf, 0, 1; + +%these parameters jointly determine the slope kappa of the linearized new keynesian phillips curve +pist, 3.2, 1e-5, 20, gamma_pdf, 4, 2; +nu, 0.1, 1e-5, 0.99999, beta_pdf, 0.1, .05; +phi, 50, 1e-5, 100, gamma_pdf, 50, 20; + +%these parameters are pairwise collinear as one should not use both formulations for the standard error of a shock +sigz, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; +stderr e_z, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4; + +%these parameters are pairwise collinear as they are multiplicative +rhog, 0.95, 1e-5, 0.99999, beta_pdf, 0.8, 0.1; +dumpyrhog, 1, -10, 10, normal_pdf, 1, 1; + +%these parameters are jointly not identified due to the specification of the Taylor rule +psi1, 1.5, 1e-5, 10, gamma_pdf, 1.5, 0.25; +psi2, 0.125, 1e-5, 10, gamma_pdf, 0.5, 0.25; +rhor, 0.75, 1e-5, 0.99999, beta_pdf, 0.5, 0.2; +stderr e_r, 0.2, 1e-8, 5, inv_gamma_pdf, 0.3, 4; + +end; + +steady; +check; +stoch_simul(order=3,irf=0); %needed for identification(order=3) + +@#for ORDER in [1, 2, 3] +@#for KRONFLAG in [-1, -2, 0] +fprintf('*** ORDER = @{ORDER} WITH ANALYTIC_DERIVATION_MODE=@{KRONFLAG} ***\n') +identification(order=@{ORDER}, parameter_set=calibration, grid_nbr=10,analytic_derivation_mode=@{KRONFLAG}); +@#endfor +@#endfor \ No newline at end of file diff --git a/tests/identification/cgg/cgg_criteria_differ.mod b/tests/identification/cgg/cgg_criteria_differ.mod index dd4aa34b4..bc6f58876 100644 --- a/tests/identification/cgg/cgg_criteria_differ.mod +++ b/tests/identification/cgg/cgg_criteria_differ.mod @@ -1,7 +1,26 @@ % This is the Clarida, Gali and Gertler Basic New Keynesian model % This mod file illustrates that due to numerical errors and numerical % settings the identification criteria might differ -% created by Willi Mutschler (willi@mutschler.eu) +% created by Willi Mutschler (@wmutschl, willi@mutschler.eu) +% ========================================================================= +% Copyright (C) 2019-2020 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 . +% ========================================================================= + var y ${y}$ (long_name='output') c ${c}$ (long_name='consumption') diff --git a/tests/identification/correlated_errors/fs2000_corr.mod b/tests/identification/correlated_errors/fs2000_corr.mod index 5efd0cbf4..ac7e3e037 100644 --- a/tests/identification/correlated_errors/fs2000_corr.mod +++ b/tests/identification/correlated_errors/fs2000_corr.mod @@ -14,7 +14,7 @@ */ /* - * Copyright (C) 2004-2013 Dynare Team + * Copyright (C) 2004-2020 Dynare Team * * This file is part of Dynare. * diff --git a/tests/identification/ident_unit_root/ident_unit_root.mod b/tests/identification/ident_unit_root/ident_unit_root.mod index b5be20170..0a3b105ee 100644 --- a/tests/identification/ident_unit_root/ident_unit_root.mod +++ b/tests/identification/ident_unit_root/ident_unit_root.mod @@ -1,5 +1,23 @@ -//Tests Identification command with ML and unit roots/diffuse filter option - +% Tests Identification command with ML and unit roots/diffuse filter option +% Created by Johannes Pfeifer (@JohannesPfeifer, jpfeifer@gmx.de) +% ========================================================================= +% Copyright (C) 2015-2020 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 . +% ========================================================================= var y delta_y x z; varexo eps_x eps_z; diff --git a/tests/identification/ident_unit_root/ident_unit_root_xfail.mod b/tests/identification/ident_unit_root/ident_unit_root_xfail.mod index 45186c261..029b11e41 100644 --- a/tests/identification/ident_unit_root/ident_unit_root_xfail.mod +++ b/tests/identification/ident_unit_root/ident_unit_root_xfail.mod @@ -1,7 +1,25 @@ -//Tests Identification command with ML and unit roots/diffuse filter option; -//Should not work because of observed unit root variable - -var y delta_y x z; +% Tests Identification command with ML and unit roots/diffuse filter option; +% Should not work because of observed unit root variable +% Created by Johannes Pfeifer (@JohannesPfeifer, jpfeifer@gmx.de) +% ========================================================================= +% Copyright (C) 2015-2020 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 . +% ========================================================================= +var y x z delta_y; varexo eps_x eps_z; diff --git a/tests/identification/kim/kim2.mod b/tests/identification/kim/kim2.mod index 172a8fa3f..48697badd 100644 --- a/tests/identification/kim/kim2.mod +++ b/tests/identification/kim/kim2.mod @@ -1,3 +1,23 @@ +% Created by Marco Ratto (@rattoma, marco.ratto@ec.europa.eu) +% ========================================================================= +% Copyright (C) 2010-2020 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 . +% ========================================================================= + var c k i a lam; varexo ea; @@ -60,6 +80,11 @@ dumpy ,uniform_pdf, , ,0,10; end; varobs c i; + +/* Skip test under MATLAB R2009b + MATLAB crashes, most likely due to an internal bug */ +if isoctave || ~matlab_ver_less_than('7.10') + identification(advanced=1,max_dim_cova_group=3); //varobs c i lam; //to check if observing lam identifies phi and theta //identification(ar=1,advanced=1,max_dim_cova_group=3,prior_mc=250); @@ -68,3 +93,5 @@ identification(advanced=1,max_dim_cova_group=3); estim_params_=[]; identification(advanced=1,max_dim_cova_group=3); + +end diff --git a/tests/identification/rbc_ident/rbc_ident_std_as_structural_par.mod b/tests/identification/rbc_ident/rbc_ident_std_as_structural_par.mod index 60ec3406f..15faf7403 100644 --- a/tests/identification/rbc_ident/rbc_ident_std_as_structural_par.mod +++ b/tests/identification/rbc_ident/rbc_ident_std_as_structural_par.mod @@ -1,4 +1,23 @@ % Real Business Cycle Model +% Created by Johannes Pfeifer (@JohannesPfeifer, jpfeifer@gmx.de) +% ========================================================================= +% Copyright (C) 2015-2020 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 . +% ========================================================================= close all; diff --git a/tests/identification/rbc_ident/rbc_ident_varexo_only.mod b/tests/identification/rbc_ident/rbc_ident_varexo_only.mod index f66beb54c..c78bff3c7 100644 --- a/tests/identification/rbc_ident/rbc_ident_varexo_only.mod +++ b/tests/identification/rbc_ident/rbc_ident_varexo_only.mod @@ -1,4 +1,23 @@ % Real Business Cycle Model +% Created by Johannes Pfeifer (@JohannesPfeifer, jpfeifer@gmx.de) +% ========================================================================= +% Copyright (C) 2015-2020 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 . +% ========================================================================= close all; @@ -96,7 +115,7 @@ identification(advanced=1); temp=load([M_.dname filesep 'identification' filesep M_.fname '_ML_Starting_value_identif']) temp_comparison=load(['rbc_ident_std_as_structural_par' filesep 'identification' filesep 'rbc_ident_std_as_structural_par' '_ML_Starting_value_identif']) -if max(abs(temp.ide_hess_point.ide_strength_J - temp_comparison.ide_hess_point.ide_strength_J))>1e-8 ||... +if max(abs(temp.ide_hess_point.ide_strength_dMOMENTS - temp_comparison.ide_hess_point.ide_strength_dMOMENTS))>1e-8 ||... max(abs(temp.ide_hess_point.deltaM - temp_comparison.ide_hess_point.deltaM))>1e-8 ||... max(abs(temp.ide_moments_point.MOMENTS- temp_comparison.ide_moments_point.MOMENTS))>1e-8 ||... max(abs(temp.ide_moments_point.MOMENTS- temp_comparison.ide_moments_point.MOMENTS))>1e-8 diff --git a/tests/initval_file/ramst_datafile.mod b/tests/initval_file/ramst_datafile.mod new file mode 100644 index 000000000..47df52175 --- /dev/null +++ b/tests/initval_file/ramst_datafile.mod @@ -0,0 +1,36 @@ +/* Verify that the “datafile” option of “perfect_foresight_setup” behaves as + “initval_file” (see #1663) */ + +var c k; +varexo x; + +parameters alph gam delt bet aa; +alph=0.5; +gam=0.5; +delt=0.02; +bet=0.05; +aa=0.5; + + +model; +c + k - aa*x*k(-1)^alph - (1-delt)*k(-1); +c^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k^(alph-1) + 1 - delt)*c(+1)^(-gam); +end; + +initval; +x = 1; +k = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1)); +c = aa*k^alph-delt*k; +end; + +steady; + +perfect_foresight_setup(periods=200, datafile = ramst_initval_file_data_col_vec_mat); +if oo_.exo_simul(2) ~= 1.2 + error('datafile option problem with exogenous variable'); +end +if oo_.endo_simul(2, 2) ~= 13 + error('datafile option problem with endogenous variable'); +end + +perfect_foresight_solver; diff --git a/tests/initval_file/ramst_initval_file.mod b/tests/initval_file/ramst_initval_file.mod index f6afae20b..2cc8f91ed 100644 --- a/tests/initval_file/ramst_initval_file.mod +++ b/tests/initval_file/ramst_initval_file.mod @@ -22,26 +22,34 @@ k = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1)); c = aa*k^alph-delt*k; end; -initval_file(filename = ramst_initval_file_data); steady; -perfect_foresight_setup(periods=200); -perfect_foresight_solver; - initval_file(filename = ramst_initval_file_data_row_vec_mat); -steady; +if oo_.exo_simul(2) ~= 1.2 + error('initval_file problem with exogenous variable'); +end +if oo_.endo_simul(2, 2) ~= 13 + error('initval_file option problem with endogenous variable'); +end perfect_foresight_setup(periods=200); perfect_foresight_solver; +oo_.exo_simul = []; +oo_.endo_simul = []; initval_file(filename = ramst_initval_file_data_col_vec_mat); -steady; +if oo_.exo_simul(2) ~= 1.2 + error('initval_file problem with exogenous variable'); +end +if oo_.endo_simul(2, 2) ~= 13 + error('initval_file problem with endogenous variable'); +end + perfect_foresight_setup(periods=200); perfect_foresight_solver; if ispc() initval_file(filename = ramst_initval_file_excel); - steady; perfect_foresight_setup(periods=200); perfect_foresight_solver; end diff --git a/tests/initval_file/ramst_initval_file_data.m b/tests/initval_file/ramst_initval_file_data.m index 16c389781..cc1914ca1 100644 --- a/tests/initval_file/ramst_initval_file_data.m +++ b/tests/initval_file/ramst_initval_file_data.m @@ -1,6 +1,6 @@ x = vertcat([ 1; 1.2 ], repmat(1, 200, 1)); -k = repmat(12.7551, 202, 1); -c = repmat(1.53061, 202, 1); +k = repmat(13, 202, 1); +c = repmat(1.5, 202, 1); save('ramst_initval_file_data_col_vec_mat.mat','c','k','x'); if ispc() @@ -11,4 +11,4 @@ end c=c'; k=k'; x=x'; -save('ramst_initval_file_data_row_vec_mat.mat','c','k','x'); \ No newline at end of file +save('ramst_initval_file_data_row_vec_mat.mat','c','k','x'); diff --git a/tests/kalman/lik_init/fs2000_ns_common.inc b/tests/kalman/lik_init/fs2000_ns_common.inc index 1406f6ffe..b756771c0 100644 --- a/tests/kalman/lik_init/fs2000_ns_common.inc +++ b/tests/kalman/lik_init/fs2000_ns_common.inc @@ -120,5 +120,7 @@ end; data(file='../../fs2000/fsdat_simul.m'); options_.diffuse_filter=1; +options_.order=1; + [dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_, bayestopt_, bounds] = ... dynare_estimation_init(char(), M_.fname, [], M_, options_, oo_, estim_params_, bayestopt_); \ No newline at end of file diff --git a/tests/kalman/likelihood_from_dynare/fs2000ns_uncorr_ME.mod b/tests/kalman/likelihood_from_dynare/fs2000ns_uncorr_ME.mod index b16a37dff..61072d20f 100644 --- a/tests/kalman/likelihood_from_dynare/fs2000ns_uncorr_ME.mod +++ b/tests/kalman/likelihood_from_dynare/fs2000ns_uncorr_ME.mod @@ -1,5 +1,12 @@ @#include "fs2000ns_model.inc" +% Under Octave, the default seed leads to a generated dataset that makes +% fs2000ns_corr_ME.mod and fs2000ns_corr_ME_missing.mod fail (due to a large +% difference between univariate and multivariate diffuse filters). +if isoctave + set_dynare_seed(2); +end + stoch_simul(periods=200, order=1,irf=0); temp=oo_.endo_simul; %add measurement error diff --git a/tests/kalman_steady_state/test1.m b/tests/kalman_steady_state/test1.m index d928d2b37..895aeb9f6 100644 --- a/tests/kalman_steady_state/test1.m +++ b/tests/kalman_steady_state/test1.m @@ -17,8 +17,7 @@ for i=1:100 Z(1,1) = 1; Z(2,3) = 1; Z(3,6) = 1; - [err P] = kalman_steady_state(transpose(T),QQ,transpose(Z),H); - mexErrCheck('kalman_steady_state',err); + P = kalman_steady_state(transpose(T),QQ,transpose(Z),H); end % Without measurment errors. @@ -35,6 +34,5 @@ for i=1:100 Z(1,1) = 1; Z(2,3) = 1; Z(3,6) = 1; - [err P] = kalman_steady_state(transpose(T),QQ,transpose(Z),H); - mexErrCheck('kalman_steady_state',err); + P = kalman_steady_state(transpose(T),QQ,transpose(Z),H); end diff --git a/tests/kronecker/test_kron.m b/tests/kronecker/test_kron.m index a25b20668..27e80877e 100644 --- a/tests/kronecker/test_kron.m +++ b/tests/kronecker/test_kron.m @@ -1,5 +1,5 @@ function info = test_kron(test,number_of_threads) -% Copyright (C) 2007-2010 Dynare Team +% Copyright (C) 2007-2020 Dynare Team % % This file is part of Dynare. % @@ -52,14 +52,12 @@ if test == 1 disp('') disp('Computation of A*kron(B,B) with the mex file (v1):') tic - [err, D1] = sparse_hessian_times_B_kronecker_C(A,B,number_of_threads); - mexErrCheck('sparse_hessian_times_B_kronecker_C', err); + D1 = sparse_hessian_times_B_kronecker_C(A,B,number_of_threads); toc disp('') disp('Computation of A*kron(B,B) with the mex file (v2):') tic - [err, D2] = sparse_hessian_times_B_kronecker_C(A,B,B,number_of_threads); - mexErrCheck('sparse_hessian_times_B_kronecker_C', err); + D2 = sparse_hessian_times_B_kronecker_C(A,B,B,number_of_threads); toc disp(''); disp(['Difference between D1 and D2 = ' num2str(max(max(abs(D1-D2))))]); @@ -120,14 +118,12 @@ if test==2 disp(' ') disp('Computation of A*kron(B,B) with the mex file (v1):') tic - [err, D1] = sparse_hessian_times_B_kronecker_C(hessian,zx,number_of_threads); - mexErrCheck('sparse_hessian_times_B_kronecker_C', err); + D1 = sparse_hessian_times_B_kronecker_C(hessian,zx,number_of_threads); toc disp(' ') disp('Computation of A*kron(B,B) with the mex file (v2):') tic - [err, D2] = sparse_hessian_times_B_kronecker_C(hessian,zx,zx,number_of_threads); - mexErrCheck('sparse_hessian_times_B_kronecker_C', err); + D2 = sparse_hessian_times_B_kronecker_C(hessian,zx,zx,number_of_threads); toc disp(' '); disp(['Difference between D1 and D2 = ' num2str(max(max(abs(D1-D2))))]); @@ -167,8 +163,7 @@ if test==3 disp('Test with full format matrix -- 1(a)') D1 = A*kron(B,C); tic - [err, D2] = A_times_B_kronecker_C(A,B,C,number_of_threads); - mexErrCheck('A_times_B_kronecker_C', err); + D2 = A_times_B_kronecker_C(A,B,C,number_of_threads); toc disp(['Difference between D1 and D2 = ' num2str(max(max(abs(D1-D2))))]); if max(max(abs(D1-D2)))>1e-10 @@ -177,8 +172,7 @@ if test==3 disp('Test with full format matrix -- 1(b)') D1 = A*kron(B,B); tic - [err, D2] = A_times_B_kronecker_C(A,B,number_of_threads); - mexErrCheck('A_times_B_kronecker_C', err); + D2 = A_times_B_kronecker_C(A,B,number_of_threads); toc disp(['Difference between D1 and D2 = ' num2str(max(max(abs(D1-D2))))]); if max(max(abs(D1-D2)))>1e-10 @@ -187,4 +181,4 @@ if test==3 if ~(test3_1 && test3_2) info = 0; end -end \ No newline at end of file +end diff --git a/tests/lmmcp/rbcii.mod b/tests/lmmcp/rbcii.mod index 84ca64539..149cea325 100644 --- a/tests/lmmcp/rbcii.mod +++ b/tests/lmmcp/rbcii.mod @@ -53,7 +53,11 @@ end; steady; perfect_foresight_setup(periods=400); -perfect_foresight_solver(lmmcp, maxit=200); +perfect_foresight_solver(lmmcp, maxit=200, no_homotopy); + +if ~oo_.deterministic_simulation.status + error('Convergence not obtained') +end n = 40; diff --git a/tests/minimal_state_space_system/as2007_minimal.mod b/tests/minimal_state_space_system/as2007_minimal.mod new file mode 100644 index 000000000..788a70ca0 --- /dev/null +++ b/tests/minimal_state_space_system/as2007_minimal.mod @@ -0,0 +1,100 @@ +% this is the Smets and Wouters (2007) model for which Komunjer and Ng (2011) +% derived the minimal state space system. In Dynare, however, we use more +% powerful minreal function +% created by Willi Mutschler (@wmutschl, willi@mutschler.eu) +% ========================================================================= +% Copyright (C) 2020 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 . +% ========================================================================= + +var y R g z c dy p YGR INFL INT; +varobs y R p c YGR INFL INT; +varexo e_r e_g e_z; +parameters tau phi psi1 psi2 rhor rhog rhoz rrst pist gamst nu cyst; + +rrst = 1.0000; +pist = 3.2000; +gamst= 0.5500; +tau = 2.0000; +nu = 0.1000; +kap = 0.3300; +phi = tau*(1-nu)/nu/kap/exp(pist/400)^2; +cyst = 0.8500; +psi1 = 1.5000; +psi2 = 0.1250; +rhor = 0.7500; +rhog = 0.9500; +rhoz = 0.9000; + + +model; +#pist2 = exp(pist/400); +#rrst2 = exp(rrst/400); +#bet = 1/rrst2; +#gst = 1/cyst; +#cst = (1-nu)^(1/tau); +#yst = cst*gst; +1 = exp(-tau*c(+1)+tau*c+R-z(+1)-p(+1)); +(1-nu)/nu/phi/(pist2^2)*(exp(tau*c)-1) = (exp(p)-1)*((1-1/2/nu)*exp(p)+1/2/nu) - bet*(exp(p(+1))-1)*exp(-tau*c(+1)+tau*c+dy(+1)+p(+1)); +exp(c-y) = exp(-g) - phi*pist2^2*gst/2*(exp(p)-1)^2; +R = rhor*R(-1) + (1-rhor)*psi1*p + (1-rhor)*psi2*(y-g) + e_r; +g = rhog*g(-1) + e_g; +z = rhoz*z(-1) + e_z; +YGR = gamst+100*(dy+z); +INFL = pist+400*p; +INT = pist+rrst+4*gamst+400*R; +dy = y - y(-1); +end; + +shocks; +var e_r; stderr 0.2/100; +var e_g; stderr 0.6/100; +var e_z; stderr 0.3/100; +end; + +steady_state_model; +z=0; g=0; c=0; y=0; p=0; R=0; dy=0; +YGR=gamst; INFL=pist; INT=pist+rrst+4*gamst; +end; +stoch_simul(order=1,irf=0,periods=0); +options_.qz_criterium = 1; + +indx = [M_.nstatic+(1:M_.nspred)]'; +indy = 1:M_.endo_nbr'; + +SS.A = oo_.dr.ghx(indx,:); +SS.B = oo_.dr.ghu(indx,:); +SS.C = oo_.dr.ghx(indy,:); +SS.D = oo_.dr.ghu(indy,:); + +[CheckCO,minnx,minSS] = get_minimal_state_representation(SS,0); + +Sigmax_full = lyapunov_symm(SS.A, SS.B*M_.Sigma_e*SS.B', options_.lyapunov_fixed_point_tol, options_.qz_criterium, options_.lyapunov_complex_threshold, 1, options_.debug); +Sigmay_full = SS.C*Sigmax_full*SS.C' + SS.D*M_.Sigma_e*SS.D'; + +Sigmax_min = lyapunov_symm(minSS.A, minSS.B*M_.Sigma_e*minSS.B', options_.lyapunov_fixed_point_tol, options_.qz_criterium, options_.lyapunov_complex_threshold, 1, options_.debug); +Sigmay_min = minSS.C*Sigmax_min*minSS.C' + minSS.D*M_.Sigma_e*minSS.D'; + +([Sigmay_full(:) - Sigmay_min(:)]') +sqrt(([diag(Sigmay_full), diag(Sigmay_min)]')) +dx = norm( Sigmay_full - Sigmay_min, Inf); +if dx > 1e-12 + error('something wrong with minimal state space computations') +else + fprintf('numerical error for moments computed from minimal state system is %d\n',dx) +end + diff --git a/tests/minimal_state_space_system/sw_minimal.mod b/tests/minimal_state_space_system/sw_minimal.mod new file mode 100644 index 000000000..844fdb214 --- /dev/null +++ b/tests/minimal_state_space_system/sw_minimal.mod @@ -0,0 +1,432 @@ +% this is the Smets and Wouters (2007) model for which Komunjer and Ng (2011) +% derived the minimal state space system. In Dynare, however, we use more +% powerful minreal function +/* + * This file provides replication files for + * Smets, Frank and Wouters, Rafael (2007): "Shocks and Frictions in US Business Cycles: A Bayesian + * DSGE Approach", American Economic Review, 97(3), 586-606, that are compatible with Dynare 4.5 onwards + * + * To replicate the full results, you have to get back to the original replication files available at + * https://www.aeaweb.org/articles.php?doi=10.1257/aer.97.3.586 and include the respective estimation commands and mode-files. + * + * Notes: + * - The consumption Euler equation in the paper, equation (2), premultiplies the risk premium process \varepsilon_t^b, + * denoted by b in this code, by the coefficient c_3. In the code this prefactor is omitted by setting the + * coefficient to 1. As a consequence, b in this code actually is b:=c_3*\varepsilon_t^b. As a consequence, in + * the arbitrage equation for the value of capital in the paper, equation (4), the term 1*\varepsilon_t^b + * is replaced by 1/c_3*b, which is equal to \varepsilon_t^b given the above redefinition. This rescaling also explains why the + * standard deviation of the risk premium shock in the AR(1)-process for b has a different standard deviation than reported + * in the paper. However, the results are unaffected by this scaling factor (except for the fact that the posterior distribution + * reported in the paper cannot be directly translated to the present mod-file due to parameter correlation in the posterior. + * - As pointed out in Del Negro/Schorfheide (2012): "Notes on New-Keynesian Models" + * in the code implementation of equation (8) for both the flex price and the sticky price/wage economy, + * there is a (1/(1+cbetabar*cgamma)) missing in the i_2 in front of q_t (denoted qs in the code). + * Equation (8) in the paper reads: + * (1-(1-delta)/gamma)*(1+beta*gamma^(1-sigma))*gamma^2*varphi + * which translates to the code snippet: + * (1-(1-ctou)/cgamma)*(1+cbetabar*cgamma)*cgamma^2*csadjcost + * But the code implements + * (1-(1-ctou)/cgamma)*cgamma^2*csadjcost + * which corresponds to an equation reading + * (1-(1-delta)/gamma)*gamma^2*varphi + * - Chib/Ramamurthy (2010): "Tailored randomized block MCMC methods with application to DSGE models", Journal of Econometrics, 155, pp. 19-38 + * have pointed out that the mode reported in the original Smets/Wouters (2007) paper is not actually the mode. \bar \pi (constepinf) is estimated lower + * while \bar \l (constelab) is higher. + * - Note that at the prior mean, [cmap,crhopinf] and [cmaw,crhow] are pairwise collinear. Thus, running identification at the prior + * mean will return a warning. But this is only a local issue. These parameters are only indistinguishable at the prior mean, but not + * at different points. + * - In the prior Table 1A in the paper, the + * - habit parameter $\lambda$ is erroneously labeled h + * - the fixed cost parameter $\phi_p$ is labeled $\Phi$ + * - Table 1B claims that $\rho_{ga}$ follows a beta prior with B(0.5,0.2^2), but the code shows that it actually + * follows a normal distribution with N(0.5,0.25^2) + * + * This file was originally written by Frank Smets and Rafeal Wouters and has been updated by + * Johannes Pfeifer. + * + * Please note that the following copyright notice only applies to this Dynare + * implementation of the model + */ + +/* + * Copyright (C) 2007-2013 Frank Smets and Raf Wouters + * Copyright (C) 2013-15 Johannes Pfeifer + * Copyright (C) 2020 Dynare Team + * + * This 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. + * + * This file 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 can receive a copy of the GNU General Public License + * at . + */ + +var labobs ${lHOURS}$ (long_name='log hours worked') + robs ${FEDFUNDS}$ (long_name='Federal funds rate') + pinfobs ${dlP}$ (long_name='Inflation') + dy ${dlGDP}$ (long_name='Output growth rate') + dc ${dlCONS}$ (long_name='Consumption growth rate') + dinve ${dlINV}$ (long_name='Investment growth rate') + dw ${dlWAG}$ (long_name='Wage growth rate') + ewma ${\eta^{w,aux}}$ (long_name='Auxiliary wage markup moving average variable') + epinfma ${\eta^{p,aux}}$ (long_name='Auxiliary price markup moving average variable') + zcapf ${z^{flex}}$ (long_name='Capital utilization rate flex price economy') + rkf ${r^{k,flex}}$ (long_name='rental rate of capital flex price economy') + kf ${k^{s,flex}}$ (long_name='Capital services flex price economy') + pkf ${q^{flex}}$ (long_name='real value of existing capital stock flex price economy') + cf ${c^{flex}}$ (long_name='Consumption flex price economy') + invef ${i^{flex}}$ (long_name='Investment flex price economy') + yf ${y^{flex}}$ (long_name='Output flex price economy') + labf ${l^{flex}}$ (long_name='hours worked flex price economy') + wf ${w^{flex}}$ (long_name='real wage flex price economy') + rrf ${r^{flex}}$ (long_name='real interest rate flex price economy') + mc ${\mu_p}$ (long_name='gross price markup') + zcap ${z}$ (long_name='Capital utilization rate') + rk ${r^{k}}$ (long_name='rental rate of capital') + k ${k^{s}}$ (long_name='Capital services') + pk ${q}$ (long_name='real value of existing capital stock') + c ${c}$ (long_name='Consumption') + inve ${i}$ (long_name='Investment') + y ${y}$ (long_name='Output') + lab ${l}$ (long_name='hours worked') + pinf ${\pi}$ (long_name='Inflation') + w ${w}$ (long_name='real wage') + r ${r}$ (long_name='nominal interest rate') + a ${\varepsilon_a}$ (long_name='productivity process') + b ${c_2*\varepsilon_t^b}$ (long_name='Scaled risk premium shock') + g ${\varepsilon^g}$ (long_name='Exogenous spending') + qs ${\varepsilon^i}$ (long_name='Investment-specific technology') + ms ${\varepsilon^r}$ (long_name='Monetary policy shock process') + spinf ${\varepsilon^p}$ (long_name='Price markup shock process') + sw ${\varepsilon^w}$ (long_name='Wage markup shock process') + kpf ${k^{flex}}$ (long_name='Capital stock flex price economy') + kp ${k}$ (long_name='Capital stock') + ; + +varexo ea ${\eta^a}$ (long_name='productivity shock') + eb ${\eta^b}$ (long_name='Investment-specific technology shock') + eg ${\eta^g}$ (long_name='Spending shock') + eqs ${\eta^i}$ (long_name='Investment-specific technology shock') + em ${\eta^m}$ (long_name='Monetary policy shock') + epinf ${\eta^{p}}$ (long_name='Price markup shock') + ew ${\eta^{w}}$ (long_name='Wage markup shock') + ; + +parameters curvw ${\varepsilon_w}$ (long_name='Curvature Kimball aggregator wages') + cgy ${\rho_{ga}}$ (long_name='Feedback technology on exogenous spending') + curvp ${\varepsilon_p}$ (long_name='Curvature Kimball aggregator prices') + constelab ${\bar l}$ (long_name='steady state hours') + constepinf ${\bar \pi}$ (long_name='steady state inflation rate') + constebeta ${100(\beta^{-1}-1)}$ (long_name='time preference rate in percent') + cmaw ${\mu_w}$ (long_name='coefficient on MA term wage markup') + cmap ${\mu_p}$ (long_name='coefficient on MA term price markup') + calfa ${\alpha}$ (long_name='capital share') + czcap ${\psi}$ (long_name='capacity utilization cost') + csadjcost ${\varphi}$ (long_name='investment adjustment cost') + ctou ${\delta}$ (long_name='depreciation rate') + csigma ${\sigma_c}$ (long_name='risk aversion') + chabb ${\lambda}$ (long_name='external habit degree') + ccs ${d_4}$ (long_name='Unused parameter') + cinvs ${d_3}$ (long_name='Unused parameter') + cfc ${\phi_p}$ (long_name='fixed cost share') + cindw ${\iota_w}$ (long_name='Indexation to past wages') + cprobw ${\xi_w}$ (long_name='Calvo parameter wages') + cindp ${\iota_p}$ (long_name='Indexation to past prices') + cprobp ${\xi_p}$ (long_name='Calvo parameter prices') + csigl ${\sigma_l}$ (long_name='Frisch elasticity') + clandaw ${\phi_w}$ (long_name='Gross markup wages') + crdpi ${r_{\Delta \pi}}$ (long_name='Unused parameter') + crpi ${r_{\pi}}$ (long_name='Taylor rule inflation feedback') + crdy ${r_{\Delta y}}$ (long_name='Taylor rule output growth feedback') + cry ${r_{y}}$ (long_name='Taylor rule output level feedback') + crr ${\rho}$ (long_name='interest rate persistence') + crhoa ${\rho_a}$ (long_name='persistence productivity shock') + crhoas ${d_2}$ (long_name='Unused parameter') + crhob ${\rho_b}$ (long_name='persistence risk premium shock') + crhog ${\rho_g}$ (long_name='persistence spending shock') + crhols ${d_1}$ (long_name='Unused parameter') + crhoqs ${\rho_i}$ (long_name='persistence risk premium shock') + crhoms ${\rho_r}$ (long_name='persistence monetary policy shock') + crhopinf ${\rho_p}$ (long_name='persistence price markup shock') + crhow ${\rho_w}$ (long_name='persistence wage markup shock') + ctrend ${\bar \gamma}$ (long_name='net growth rate in percent') + cg ${\frac{\bar g}{\bar y}}$ (long_name='steady state exogenous spending share') + ; + +// fixed parameters +ctou=.025; +clandaw=1.5; +cg=0.18; +curvp=10; +curvw=10; + +// estimated parameters initialisation +calfa=.24; +cbeta=.9995; +csigma=1.5; +cfc=1.5; +cgy=0.51; + +csadjcost= 6.0144; +chabb= 0.6361; +cprobw= 0.8087; +csigl= 1.9423; +cprobp= 0.6; +cindw= 0.3243; +cindp= 0.47; +czcap= 0.2696; +crpi= 1.488; +crr= 0.8762; +cry= 0.0593; +crdy= 0.2347; + +crhoa= 0.9977; +crhob= 0.5799; +crhog= 0.9957; +crhols= 0.9928; +crhoqs= 0.7165; +crhoas=1; +crhoms=0; +crhopinf=0; +crhow=0; +cmap = 0; +cmaw = 0; + +constelab=0; + +%% Added by JP to provide full calibration of model before estimation +constepinf=0.7; +constebeta=0.7420; +ctrend=0.3982; + +model(linear); +//deal with parameter dependencies; taken from usmodel_stst.mod +#cpie=1+constepinf/100; %gross inflation rate +#cgamma=1+ctrend/100 ; %gross growth rate +#cbeta=1/(1+constebeta/100); %discount factor + +#clandap=cfc; %fixed cost share/gross price markup +#cbetabar=cbeta*cgamma^(-csigma); %growth-adjusted discount factor in Euler equation +#cr=cpie/(cbeta*cgamma^(-csigma)); %steady state net real interest rate +#crk=(cbeta^(-1))*(cgamma^csigma) - (1-ctou); %R^k_{*}: steady state rental rate +#cw = (calfa^calfa*(1-calfa)^(1-calfa)/(clandap*crk^calfa))^(1/(1-calfa)); %steady state real wage +//cw = (calfa^calfa*(1-calfa)^(1-calfa)/(clandap*((cbeta^(-1))*(cgamma^csigma) - (1-ctou))^calfa))^(1/(1-calfa)); +#cikbar=(1-(1-ctou)/cgamma); %k_1 in equation LOM capital, equation (8) +#cik=(1-(1-ctou)/cgamma)*cgamma; %i_k: investment-capital ratio +#clk=((1-calfa)/calfa)*(crk/cw); %labor to capital ratio +#cky=cfc*(clk)^(calfa-1); %k_y: steady state output ratio +#ciy=cik*cky; %consumption-investment ratio +#ccy=1-cg-cik*cky; %consumption-output ratio +#crkky=crk*cky; %z_y=R_{*}^k*k_y +#cwhlc=(1/clandaw)*(1-calfa)/calfa*crk*cky/ccy; %W^{h}_{*}*L_{*}/C_{*} used in c_2 in equation (2) +#cwly=1-crk*cky; %unused parameter + +#conster=(cr-1)*100; %steady state federal funds rate ($\bar r$) + +// flexible economy + + [name='FOC labor with mpl expressed as function of rk and w, flex price economy'] + 0*(1-calfa)*a + 1*a = calfa*rkf+(1-calfa)*(wf) ; + [name='FOC capacity utilization, flex price economy'] + zcapf = (1/(czcap/(1-czcap)))* rkf ; + [name='Firm FOC capital, flex price economy'] + rkf = (wf)+labf-kf ; + [name='Definition capital services, flex price economy'] + kf = kpf(-1)+zcapf ; + [name='Investment Euler Equation, flex price economy'] + invef = (1/(1+cbetabar*cgamma))* ( invef(-1) + cbetabar*cgamma*invef(1)+(1/(cgamma^2*csadjcost))*pkf ) +qs ; + [name='Arbitrage equation value of capital, flex price economy'] + pkf = -rrf-0*b+(1/((1-chabb/cgamma)/(csigma*(1+chabb/cgamma))))*b +(crk/(crk+(1-ctou)))*rkf(1) + ((1-ctou)/(crk+(1-ctou)))*pkf(1) ; + [name='Consumption Euler Equation, flex price economy'] + cf = (chabb/cgamma)/(1+chabb/cgamma)*cf(-1) + (1/(1+chabb/cgamma))*cf(+1) +((csigma-1)*cwhlc/(csigma*(1+chabb/cgamma)))*(labf-labf(+1)) - (1-chabb/cgamma)/(csigma*(1+chabb/cgamma))*(rrf+0*b) + b ; + [name='Aggregate Resource Constraint, flex price economy'] + yf = ccy*cf+ciy*invef+g + crkky*zcapf ; + [name='Aggregate Production Function, flex price economy'] + yf = cfc*( calfa*kf+(1-calfa)*labf +a ); + [name='Wage equation, flex price economy'] + wf = csigl*labf +(1/(1-chabb/cgamma))*cf - (chabb/cgamma)/(1-chabb/cgamma)*cf(-1) ; + [name='Law of motion for capital, flex price economy (see header notes)'] + kpf = (1-cikbar)*kpf(-1)+(cikbar)*invef + (cikbar)*(cgamma^2*csadjcost)*qs ; + +// sticky price - wage economy + [name='FOC labor with mpl expressed as function of rk and w, SW Equation (9)'] + mc = calfa*rk+(1-calfa)*(w) - 1*a - 0*(1-calfa)*a ; + [name='FOC capacity utilization, SW Equation (7)'] + zcap = (1/(czcap/(1-czcap)))* rk ; + [name='Firm FOC capital, SW Equation (11)'] + rk = w+lab-k ; + [name='Definition capital services, SW Equation (6)'] + k = kp(-1)+zcap ; + [name='Investment Euler Equation, SW Equation (3)'] + inve = (1/(1+cbetabar*cgamma))* (inve(-1) + cbetabar*cgamma*inve(1)+(1/(cgamma^2*csadjcost))*pk ) +qs ; + [name='Arbitrage equation value of capital, SW Equation (4)'] + pk = -r+pinf(1)-0*b + + (1/((1-chabb/cgamma)/(csigma*(1+chabb/cgamma))))*b + + (crk/(crk+(1-ctou)))*rk(1) + + ((1-ctou)/(crk+(1-ctou)))*pk(1) ; + [name='Consumption Euler Equation, SW Equation (2)'] + c = (chabb/cgamma)/(1+chabb/cgamma)*c(-1) + + (1/(1+chabb/cgamma))*c(+1) + +((csigma-1)*cwhlc/(csigma*(1+chabb/cgamma)))*(lab-lab(+1)) + - (1-chabb/cgamma)/(csigma*(1+chabb/cgamma))*(r-pinf(+1) + 0*b) +b ; + [name='Aggregate Resource Constraint, SW Equation (1)'] + y = ccy*c+ciy*inve+g + 1*crkky*zcap ; + [name='Aggregate Production Function, SW Equation (5)'] + y = cfc*( calfa*k+(1-calfa)*lab +a ); + [name='New Keynesian Phillips Curve, SW Equation (10)'] + pinf = (1/(1+cbetabar*cgamma*cindp)) * ( cbetabar*cgamma*pinf(1) +cindp*pinf(-1) + +((1-cprobp)*(1-cbetabar*cgamma*cprobp)/cprobp)/((cfc-1)*curvp+1)*(mc) ) + spinf ; + [name='Wage Phillips Curve, SW Equation (13), with (12) plugged for mu_w'] + w = (1/(1+cbetabar*cgamma))*w(-1) + +(cbetabar*cgamma/(1+cbetabar*cgamma))*w(1) + +(cindw/(1+cbetabar*cgamma))*pinf(-1) + -(1+cbetabar*cgamma*cindw)/(1+cbetabar*cgamma)*pinf + +(cbetabar*cgamma)/(1+cbetabar*cgamma)*pinf(1) + +(1-cprobw)*(1-cbetabar*cgamma*cprobw)/((1+cbetabar*cgamma)*cprobw)*(1/((clandaw-1)*curvw+1))* + (csigl*lab + (1/(1-chabb/cgamma))*c - ((chabb/cgamma)/(1-chabb/cgamma))*c(-1) -w) + + 1*sw ; + [name='Taylor rule, SW Equation (14)'] + r = crpi*(1-crr)*pinf + +cry*(1-crr)*(y-yf) + +crdy*(y-yf-y(-1)+yf(-1)) + +crr*r(-1) + +ms ; + [name='Law of motion for productivity'] + a = crhoa*a(-1) + ea; + [name='Law of motion for risk premium'] + b = crhob*b(-1) + eb; + [name='Law of motion for spending process'] + g = crhog*(g(-1)) + eg + cgy*ea; + [name='Law of motion for investment specific technology shock process'] + qs = crhoqs*qs(-1) + eqs; + [name='Law of motion for monetary policy shock process'] + ms = crhoms*ms(-1) + em; + [name='Law of motion for price markup shock process'] + spinf = crhopinf*spinf(-1) + epinfma - cmap*epinfma(-1); + epinfma=epinf; + [name='Law of motion for wage markup shock process'] + sw = crhow*sw(-1) + ewma - cmaw*ewma(-1) ; + ewma=ew; + [name='Law of motion for capital, SW Equation (8) (see header notes)'] + kp = (1-cikbar)*kp(-1)+cikbar*inve + cikbar*cgamma^2*csadjcost*qs ; + +// measurement equations +[name='Observation equation output'] +dy=y-y(-1)+ctrend; +[name='Observation equation consumption'] +dc=c-c(-1)+ctrend; +[name='Observation equation investment'] +dinve=inve-inve(-1)+ctrend; +[name='Observation equation real wage'] +dw=w-w(-1)+ctrend; +[name='Observation equation inflation'] +pinfobs = 1*(pinf) + constepinf; +[name='Observation equation interest rate'] +robs = 1*(r) + conster; +[name='Observation equation hours worked'] +labobs = lab + constelab; + +end; + +steady_state_model; +dy=ctrend; +dc=ctrend; +dinve=ctrend; +dw=ctrend; +pinfobs = constepinf; +robs = (((1+constepinf/100)/((1/(1+constebeta/100))*(1+ctrend/100)^(-csigma)))-1)*100; +labobs = constelab; +end; + +shocks; +var ea; +stderr 0.4618; +var eb; +stderr 1.8513; +var eg; +stderr 0.6090; +var eqs; +stderr 0.6017; +var em; +stderr 0.2397; +var epinf; +stderr 0.1455; +var ew; +stderr 0.2089; +end; + + +estimated_params; +// PARAM NAME, INITVAL, LB, UB, PRIOR_SHAPE, PRIOR_P1, PRIOR_P2, PRIOR_P3, PRIOR_P4, JSCALE +// PRIOR_SHAPE: BETA_PDF, GAMMA_PDF, NORMAL_PDF, INV_GAMMA_PDF +stderr ea,0.4618,0.01,3,INV_GAMMA_PDF,0.1,2; +stderr eb,0.1818513,0.025,5,INV_GAMMA_PDF,0.1,2; +stderr eg,0.6090,0.01,3,INV_GAMMA_PDF,0.1,2; +stderr eqs,0.46017,0.01,3,INV_GAMMA_PDF,0.1,2; +stderr em,0.2397,0.01,3,INV_GAMMA_PDF,0.1,2; +stderr epinf,0.1455,0.01,3,INV_GAMMA_PDF,0.1,2; +stderr ew,0.2089,0.01,3,INV_GAMMA_PDF,0.1,2; +crhoa,.9676 ,.01,.9999,BETA_PDF,0.5,0.20; +crhob,.2703,.01,.9999,BETA_PDF,0.5,0.20; +crhog,.9930,.01,.9999,BETA_PDF,0.5,0.20; +crhoqs,.5724,.01,.9999,BETA_PDF,0.5,0.20; +crhoms,.3,.01,.9999,BETA_PDF,0.5,0.20; +crhopinf,.8692,.01,.9999,BETA_PDF,0.5,0.20; +crhow,.9546,.001,.9999,BETA_PDF,0.5,0.20; +cmap,.7652,0.01,.9999,BETA_PDF,0.5,0.2; +cmaw,.8936,0.01,.9999,BETA_PDF,0.5,0.2; +csadjcost,6.3325,2,15,NORMAL_PDF,4,1.5; +csigma,1.2312,0.25,3,NORMAL_PDF,1.50,0.375; +chabb,0.7205,0.001,0.99,BETA_PDF,0.7,0.1; +cprobw,0.7937,0.3,0.95,BETA_PDF,0.5,0.1; +csigl,2.8401,0.25,10,NORMAL_PDF,2,0.75; +cprobp,0.7813,0.5,0.95,BETA_PDF,0.5,0.10; +cindw,0.4425,0.01,0.99,BETA_PDF,0.5,0.15; +cindp,0.3291,0.01,0.99,BETA_PDF,0.5,0.15; +czcap,0.2648,0.01,1,BETA_PDF,0.5,0.15; +cfc,1.4672,1.0,3,NORMAL_PDF,1.25,0.125; +crpi,1.7985,1.0,3,NORMAL_PDF,1.5,0.25; +crr,0.8258,0.5,0.975,BETA_PDF,0.75,0.10; +cry,0.0893,0.001,0.5,NORMAL_PDF,0.125,0.05; +crdy,0.2239,0.001,0.5,NORMAL_PDF,0.125,0.05; +constepinf,0.7,0.1,2.0,GAMMA_PDF,0.625,0.1;//20; +constebeta,0.7420,0.01,2.0,GAMMA_PDF,0.25,0.1;//0.20; +constelab,1.2918,-10.0,10.0,NORMAL_PDF,0.0,2.0; +ctrend,0.3982,0.1,0.8,NORMAL_PDF,0.4,0.10; +cgy,0.05,0.01,2.0,NORMAL_PDF,0.5,0.25; +calfa,0.24,0.01,1.0,NORMAL_PDF,0.3,0.05; +end; + +stoch_simul(order=1,irf=0,periods=0); +options_.qz_criterium = 1; + +indx = [M_.nstatic+(1:M_.nspred)]'; +indy = 1:M_.endo_nbr'; + +SS.A = oo_.dr.ghx(indx,:); +SS.B = oo_.dr.ghu(indx,:); +SS.C = oo_.dr.ghx(indy,:); +SS.D = oo_.dr.ghu(indy,:); + +[CheckCO,minnx,minSS] = get_minimal_state_representation(SS,0); + +Sigmax_full = lyapunov_symm(SS.A, SS.B*M_.Sigma_e*SS.B', options_.lyapunov_fixed_point_tol, options_.qz_criterium, options_.lyapunov_complex_threshold, 1, options_.debug); +Sigmay_full = SS.C*Sigmax_full*SS.C' + SS.D*M_.Sigma_e*SS.D'; + +Sigmax_min = lyapunov_symm(minSS.A, minSS.B*M_.Sigma_e*minSS.B', options_.lyapunov_fixed_point_tol, options_.qz_criterium, options_.lyapunov_complex_threshold, 1, options_.debug); +Sigmay_min = minSS.C*Sigmax_min*minSS.C' + minSS.D*M_.Sigma_e*minSS.D'; + +([Sigmay_full(:) - Sigmay_min(:)]') +sqrt(([diag(Sigmay_full), diag(Sigmay_min)]')) +dx = norm( Sigmay_full - Sigmay_min, Inf); +if dx > 2e-8 + error(sprintf('something wrong with minimal state space computations, as numerical error is %d',dx)) +else + fprintf('numerical error for moments computed from minimal state system is %d\n',dx) +end diff --git a/tests/moments/example1_bp_test.mod b/tests/moments/example1_bp_test.mod index 43c2c8747..429040b1c 100644 --- a/tests/moments/example1_bp_test.mod +++ b/tests/moments/example1_bp_test.mod @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2001-2010 Dynare Team + * Copyright (C) 2001-2020 Dynare Team * * This file is part of Dynare. * @@ -67,7 +67,7 @@ end; steady(solve_algo=4,maxit=1000); -stoch_simul(order=1,nofunctions,irf=0,bandpass_filter=[6 32],hp_ngrid=8192); +stoch_simul(order=1,nofunctions,irf=0,bandpass_filter=[6 32],filtered_theoretical_moments_grid=8192); oo_filtered_all_shocks_theoretical=oo_; stoch_simul(order=1,nofunctions,periods=1000000); diff --git a/tests/moments/example1_hp_test.mod b/tests/moments/example1_hp_test.mod index d2ae7a4eb..be200e606 100644 --- a/tests/moments/example1_hp_test.mod +++ b/tests/moments/example1_hp_test.mod @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2001-2010 Dynare Team + * Copyright (C) 2001-2020 Dynare Team * * This file is part of Dynare. * @@ -67,7 +67,7 @@ end; steady(solve_algo=4,maxit=1000); -stoch_simul(order=1,nofunctions,hp_filter=1600,irf=0,hp_ngrid=8192); +stoch_simul(order=1,nofunctions,hp_filter=1600,irf=0,filtered_theoretical_moments_grid=8192); total_var_filtered=diag(oo_.var); oo_filtered_all_shocks=oo_; diff --git a/tests/moments/example1_one_sided_hp_test.mod b/tests/moments/example1_one_sided_hp_test.mod index 9da0798b5..1e61f23d2 100644 --- a/tests/moments/example1_one_sided_hp_test.mod +++ b/tests/moments/example1_one_sided_hp_test.mod @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2001-2010 Dynare Team + * Copyright (C) 2001-2020 Dynare Team * * This file is part of Dynare. * @@ -66,6 +66,5 @@ var e, u = phi*0.009*0.009; end; steady(solve_algo=4,maxit=1000); -options_.hp_ngrid=2048*4; -stoch_simul(order=1,nofunctions,one_sided_hp_filter=1600,irf=0,periods=5000); \ No newline at end of file +stoch_simul(order=1,nofunctions,one_sided_hp_filter=1600,irf=0,periods=5000,filtered_theoretical_moments_grid=8192); diff --git a/tests/moments/fs2000_post_moments.mod b/tests/moments/fs2000_post_moments.mod index f25a60b38..3ea15dcef 100644 --- a/tests/moments/fs2000_post_moments.mod +++ b/tests/moments/fs2000_post_moments.mod @@ -130,7 +130,7 @@ par=load([M_.fname filesep 'metropolis' filesep M_.fname '_posterior_draws1']); for par_iter=1:size(par.pdraws,1) M_=set_parameters_locally(M_,par.pdraws{par_iter,1}); - [info, oo_, options_]=stoch_simul(M_, options_, oo_, var_list_); + [info, oo_, options_, M_]=stoch_simul(M_, options_, oo_, var_list_); correlation(:,:,par_iter)=cell2mat(oo_.autocorr); covariance(:,:,par_iter)=oo_.var; conditional_variance_decomposition(:,:,:,par_iter)=oo_.conditional_variance_decomposition; diff --git a/tests/moments/test_AR1_spectral_density.mod b/tests/moments/test_AR1_spectral_density.mod index 334776b98..3e95fd570 100644 --- a/tests/moments/test_AR1_spectral_density.mod +++ b/tests/moments/test_AR1_spectral_density.mod @@ -18,9 +18,8 @@ end; options_.SpectralDensity.trigger=1; options_.bandpass.indicator=0; -options_.hp_ngrid=2048; -stoch_simul(order=1,nofunctions,hp_filter=0,irf=0,periods=1000000); +stoch_simul(order=1,nofunctions,hp_filter=0,irf=0,periods=1000000,filtered_theoretical_moments_grid=2048); white_noise_sample=white_noise; @@ -50,7 +49,7 @@ end options_.hp_filter=0; stoch_simul(order=1,nofunctions,bandpass_filter=[6 32],irf=0); -theoretical_spectrum_white_noise=repmat(theoretical_spectrum_white_noise,1,options_.hp_ngrid); +theoretical_spectrum_white_noise=repmat(theoretical_spectrum_white_noise,1,options_.filtered_theoretical_moments_grid); passband=oo_.SpectralDensity.freqs>=2*pi/options_.bandpass.passband(2) & oo_.SpectralDensity.freqs<=2*pi/options_.bandpass.passband(1); if max(abs(oo_.SpectralDensity.density(strmatch('white_noise',M_.endo_names,'exact'),passband)-theoretical_spectrum_white_noise(passband)))>1e-10 error('Spectral Density is wrong') @@ -73,4 +72,4 @@ end % % % figure % % [pow,f]=psd(a_sample,1000,1,[],500); -% % plot(f(3:end)*2*pi,pow(3:end)/(2*pi)); \ No newline at end of file +% % plot(f(3:end)*2*pi,pow(3:end)/(2*pi)); diff --git a/tests/optimal_policy/Ramsey/Gali_commitment.mod b/tests/optimal_policy/Ramsey/Gali_commitment.mod index 029b2b33c..ce68001b9 100644 --- a/tests/optimal_policy/Ramsey/Gali_commitment.mod +++ b/tests/optimal_policy/Ramsey/Gali_commitment.mod @@ -3,7 +3,7 @@ * in Jordi Gal (2008): Monetary Policy, Inflation, and the Business Cycle, * Princeton University Press, Chapter 5.1.2 * - * It demonstrates how to use the ramsey_policy command of Dynare. + * It demonstrates how to use the ramsey_model command of Dynare. * * Notes: * - all model variables are expressed in deviations from steady state, i.e. @@ -18,7 +18,7 @@ */ /* - * Copyright (C) 2015 Johannes Pfeifer + * Copyright (C) 2015-19 Johannes Pfeifer * * This is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -168,7 +168,8 @@ end; //planner objective using alpha_x expressed as function of deep parameters planner_objective pi^2 +(((1-theta)*(1-betta*theta)/theta*((1-alppha)/(1-alppha+alppha*epsilon)))*(siggma+(phi+alppha)/(1-alppha)))/epsilon*y_gap^2; -ramsey_policy(instruments=(i),irf=13,planner_discount=betta) x pi p u; +ramsey_model(instruments=(i),planner_discount=betta); +stoch_simul(order=1,irf=13) x pi p u; verbatim; %% Check correctness diff --git a/tests/optimal_policy/Ramsey/Ramsey_Example_estimation.mod b/tests/optimal_policy/Ramsey/Ramsey_Example_estimation.mod new file mode 100644 index 000000000..b51233fc1 --- /dev/null +++ b/tests/optimal_policy/Ramsey/Ramsey_Example_estimation.mod @@ -0,0 +1,249 @@ +/* + * This file replicates the model studied in: + * Lawrence J. Christiano, Roberto Motto and Massimo Rostagno (2007): + * "Notes on Ramsey-Optimal Monetary Policy", Section 2 + * The paper is available at http://faculty.wcas.northwestern.edu/~lchrist/d16/d1606/ramsey.pdf + * + * Notes: + * - This mod-files allows to simulate a simple New Keynesian Model with Rotemberg price + * adjustment costs under three different monetary policy arrangements: + * 1. a Taylor rule with a fixed inflation feedback coefficient alpha + * -> set the Optimal_policy switch to 0 + * 2. a Taylor rule where the inflation feedback coefficient alpha is chosen + * optimally to minimize a quadratic loss function (optimal simple rule (OSR)) + * -> set the Optimal_policy switch to 1 and the Ramsey switch to 0 + * 3. fully optimal monetary under commitment (Ramsey) + * -> set the Optimal_policy switch to 1 and the Ramsey switch to 1 + * + * - The Efficent_steady_state switch can be used to switch from an distorted steady state + * due to a monopolistic distortion to one where a labor subsidy counteracts this + * distortion. Note that the purely quadratic loss function in the OSR case does not capture + * the full welfare losses with a distorted steady state as there would be a linear term + * appearing. + * + * - This files shows how to use a conditional steady state file in the Ramsey case. It takes + * the value of the defined instrument R as given and then computes the rest of the steady + * state, including the steady state inflation rate, based on this value. The initial value + * of the instrument for steady state search must then be defined in an initval-block. + * + * - The optim_weights in the OSR case are based on a second order approximation to the welfare function + * as in Gali (2015). The relative weight between inflation and output gap volatility is essentially + * given by the slope of the New Keynesian Phillips Curve. Note that the linear terms that would be + * present in case of a distorted steady state need to be dropped for OSR. + * + * - Due to divine coincidence, the first best policy involves fully stabilizing inflation + * and thereby the output gap. As a consequence, the optimal inflation feedback coefficient + * in a Taylor rule would be infinity. The OSR command therefore estimates it to be at the + * upper bound defined via osr_params_bounds. + * + * - The mod-file also allows to conduct estimation under Ramsey policy by setting the + * Estimation_under_Ramsey switch to 1. + * + * This implementation was written by Johannes Pfeifer. + * + * If you spot mistakes, email me at jpfeifer@gmx.de + * + * Please note that the following copyright notice only applies to this Dynare + * implementation of the model. + */ + +/* + * Copyright (C) 2019 Dynare Team + * + * This 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. + * + * It 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. + * + * For a copy of the GNU General Public License, + * see . + */ + +//**********Define which monetary policy setup to use *********** + +@#ifndef Optimal_policy + @#define Optimal_policy=1 + @#ifndef Ramsey + @#define Ramsey=1 + @#endif +@#endif + +//**********Define whether to use distorted steady state*********** + +@#ifndef Efficent_steady_state + @#define Efficent_steady_state=0 +@#endif + +@#ifndef Estimation_under_Ramsey + @#define Estimation_under_Ramsey=1 +@#endif + +var C $C$ (long_name='Consumption') + pi $\pi$ (long_name='Gross inflation') + h $h$ (long_name='hours worked') + Z $Z$ (long_name='TFP') + R $R$ (long_name='Net nominal interest rate') + log_C ${\ln C}$ (long_name='Log Consumption') + log_h ${\ln h}$ (long_name='Log hours worked') + pi_ann ${\pi^{ann}}$ (long_name='Annualized net inflation') + R_ann ${R^{ann}}$ (long_name='Annualized net nominal interest rate') + r_real ${r^{ann,real}}$ (long_name='Annualized net real interest rate') + y_nat ${y^{nat}}$ (long_name='Natural (flex price) output') + y_gap ${r^{gap}}$ (long_name='Output gap') +; + +varexo epsilon ${\varepsilon}$ (long_name='TFP shock') + ; + +parameters beta ${\beta}$ (long_name='discount factor') + theta ${\theta}$ (long_name='substitution elasticity') + tau ${\tau}$ (long_name='labor subsidy') + chi ${\chi}$ (long_name='labor disutility') + phi ${\phi}$ (long_name='price adjustment costs') + rho ${\rho}$ (long_name='TFP autocorrelation') + @# if !defined(Ramsey) || Ramsey==0 + pi_star ${\pi^*}$ (long_name='steady state inflation') + alpha ${\alpha}$ (long_name='inflation feedback Taylor rule') + @# endif + ; + +beta=0.99; +theta=5; +phi=100; +rho=0.9; +@# if !defined(Ramsey) || Ramsey==0 + alpha=1.5; + pi_star=1; +@# endif +@# if Efficent_steady_state + tau=1/(theta-1); +@# else + tau=0; +@# endif +chi=1; + +model; + [name='Euler equation'] + 1/(1+R)=beta*C/(C(+1)*pi(+1)); + [name='Firm FOC'] + (tau-1/(theta-1))*(1-theta)+theta*(chi*h*C/(exp(Z))-1)=phi*(pi-1)*pi-beta*phi*(pi(+1)-1)*pi(+1); + [name='Resource constraint'] + C*(1+phi/2*(pi-1)^2)=exp(Z)*h; + [name='TFP process'] + Z=rho*Z(-1)+epsilon; + @#if !defined(Ramsey) || Ramsey==0 + [name='Taylor rule'] + R=pi_star/beta-1+alpha*(pi-pi_star); + @#endif + [name='Definition log consumption'] + log_C=log(C); + [name='Definition log hours worked'] + log_h=log(h); + [name='Definition annualized inflation rate'] + pi_ann=4*log(pi); + [name='Definition annualized nominal interest rate'] + R_ann=4*R; + [name='Definition annualized real interest rate'] + r_real=4*log((1+R)/pi(+1)); + [name='Definition natural output'] + y_nat=exp(Z)*sqrt((theta-1)/theta*(1+tau)/chi); + [name='output gap'] + y_gap=log_C-log(y_nat); +end; + +steady_state_model; + Z=0; + @# if !defined(Ramsey) || Ramsey==0 + R=pi_star/beta-1; %only set this if not conditional steady state file for Ramsey + @# endif + pi=(R+1)*beta; + C=sqrt((1+1/theta*((1-beta)*(pi-1)*pi-(tau-1/(theta-1))*(1-theta)))/(chi*(1+phi/2*(pi-1)^2))); + h=C*(1+phi/2*(pi-1)^2); + log_C=log(C); + log_h=log(h); + pi_ann=4*log(pi); + R_ann=4*R; + r_real=4*log((1+R)/pi); + y_nat=sqrt((theta-1)/theta*(1+tau)/chi); + y_gap=log_C-log(y_nat); +end; + +@# if defined(Ramsey) && Ramsey==1 + //define initial value of instrument for Ramsey + initval; + R=1/beta-1; + end; +@# endif + +shocks; + var epsilon = 0.01^2; +end; + +@#if Optimal_policy==0 + //use Taylor rule + stoch_simul(order=2) pi_ann log_h R_ann log_C Z r_real y_nat; +@#else + @# if !defined(Ramsey) || Ramsey==0 + //use OSR Taylor rule + + //set weights on (co-)variances for OSR + optim_weights; + pi theta/((theta-1)/phi); + y_gap 1; + end; + + //define OSR parameters to be optimized + osr_params alpha; + + //starting value for OSR parameter + alpha = 1.5; + + //define bounds for OSR during optimization + osr_params_bounds; + alpha, 0, 100; + end; + + //compute OSR and provide output + osr(opt_algo=9) pi_ann log_h R_ann log_C Z r_real; + + @# else + //use Ramsey optimal policy + + //define planner objective, which corresponds to utility function of agents + planner_objective log(C)-chi/2*h^2; + + //set up Ramsey optimal policy problem with interest rate R as the instrument,... + // defining the discount factor in the planner objective to be the one of private agents + ramsey_model(instruments=(R),planner_discount=beta,planner_discount_latex_name=$\beta$); + + //conduct stochastic simulations of the Ramsey problem + stoch_simul(order=1,irf=20,periods=500) pi_ann log_h R_ann log_C Z r_real; + evaluate_planner_objective; + + @# if Estimation_under_Ramsey==1 + datatomfile('ramsey_simulation',{'log_C'}) + + estimated_params; + rho,0.5,uniform_pdf, , ,0,1; + end; + varobs log_C; + + estimation(datafile=ramsey_simulation,mode_compute=5,mh_nblocks=1,mh_replic=0); + @# endif + @# endif +@# endif + +write_latex_static_model(write_equation_tags); +write_latex_dynamic_model(write_equation_tags); +write_latex_original_model(write_equation_tags); +write_latex_steady_state_model; + +collect_latex_files; +if system(['pdflatex -halt-on-error -interaction=batchmode ' M_.fname '_TeX_binder.tex']) + error('TeX-File did not compile.') +end \ No newline at end of file diff --git a/tests/optimal_policy/Ramsey/ramsey_ex_aux.mod b/tests/optimal_policy/Ramsey/ramsey_ex_aux.mod index bcf066974..bd44e8082 100644 --- a/tests/optimal_policy/Ramsey/ramsey_ex_aux.mod +++ b/tests/optimal_policy/Ramsey/ramsey_ex_aux.mod @@ -49,4 +49,6 @@ var u; stderr 0.008; end; planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); -ramsey_policy(planner_discount=0.99,order=1,instruments=(r)); +ramsey_model(planner_discount=0.99,instruments=(r)); +stoch_simul(order=1,periods=500); +evaluate_planner_objective; \ No newline at end of file diff --git a/tests/optimal_policy/Ramsey/ramsey_ex_wrong_ss_file_xfail.mod b/tests/optimal_policy/Ramsey/ramsey_ex_wrong_ss_file_xfail.mod index 3b44bad17..d77b7566a 100644 --- a/tests/optimal_policy/Ramsey/ramsey_ex_wrong_ss_file_xfail.mod +++ b/tests/optimal_policy/Ramsey/ramsey_ex_wrong_ss_file_xfail.mod @@ -38,4 +38,6 @@ var u; stderr 0.008; end; planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); -ramsey_policy(planner_discount=0.99,order=1,instruments=(r)); \ No newline at end of file +ramsey_model(planner_discount=0.99,order=1,instruments=(r)); +stoch_simul(order=1,periods=500); +evaluate_planner_objective; \ No newline at end of file diff --git a/tests/optimal_policy/Ramsey/ramsey_histval.mod b/tests/optimal_policy/Ramsey/ramsey_histval.mod index bb9cdb0f8..09ee4c689 100644 --- a/tests/optimal_policy/Ramsey/ramsey_histval.mod +++ b/tests/optimal_policy/Ramsey/ramsey_histval.mod @@ -41,4 +41,5 @@ values 1; end; options_.dr_display_tol=0; planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); -ramsey_policy(planner_discount=0.99,order=1,instruments=(r),periods=500); \ No newline at end of file +ramsey_model(planner_discount=0.99,instruments=(r)); +stoch_simul(order=1,periods=500); \ No newline at end of file diff --git a/tests/optimal_policy/Ramsey/ramsey_histval_xfail.mod b/tests/optimal_policy/Ramsey/ramsey_histval_xfail.mod index 0af81202d..24a68adc7 100644 --- a/tests/optimal_policy/Ramsey/ramsey_histval_xfail.mod +++ b/tests/optimal_policy/Ramsey/ramsey_histval_xfail.mod @@ -41,4 +41,6 @@ values 1; end; options_.dr_display_tol=0; planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); -ramsey_policy(planner_discount=0.99,order=1,instruments=(r),periods=500); \ No newline at end of file +ramsey_model(planner_discount=0.99,instruments=(r)); +stoch_simul(order=1,periods=500); +evaluate_planner_objective; \ No newline at end of file diff --git a/tests/optimal_policy/mult_elimination_test.mod b/tests/optimal_policy/mult_elimination_test.mod index b1523248a..63b4f9305 100644 --- a/tests/optimal_policy/mult_elimination_test.mod +++ b/tests/optimal_policy/mult_elimination_test.mod @@ -45,7 +45,8 @@ end; planner_objective 0.25*pie_obs^2+y^2+0.1*dR^2; -ramsey_policy(order=1,irf=0,planner_discount=0.95); +ramsey_model(planner_discount=0.95); +stoch_simul(order=1,irf=0); dr2 = mult_elimination({'R'},M_,options_,oo_); diff --git a/tests/optimal_policy/nk_ramsey.mod b/tests/optimal_policy/nk_ramsey.mod index 3b35cf51c..c6f79c77f 100644 --- a/tests/optimal_policy/nk_ramsey.mod +++ b/tests/optimal_policy/nk_ramsey.mod @@ -84,7 +84,8 @@ planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); write_latex_static_model; -ramsey_policy(planner_discount=0.99); - +ramsey_model(planner_discount=0.99, planner_discount_latex_name = $\delta$); +stoch_simul(order=1,irf=20); +evaluate_planner_objective; diff --git a/tests/optimal_policy/nk_ramsey_det.mod b/tests/optimal_policy/nk_ramsey_det.mod index 772e69a66..8d1bd2ae8 100644 --- a/tests/optimal_policy/nk_ramsey_det.mod +++ b/tests/optimal_policy/nk_ramsey_det.mod @@ -13,8 +13,6 @@ var pai, c, n, r, a; varexo u; - - //------------------------------------------------------------------------------------------------------------------------ // 2. Parameter declaration and calibration //------------------------------------------------------------------------------------------------------------------------- @@ -29,25 +27,16 @@ phi=1; //coefficient associated to labor effort disutility rho=0.95; //coefficient associated to productivity shock - //----------------------------------------------------------------------------------------------------------------------- // 3. The model //----------------------------------------------------------------------------------------------------------------------- - model; - - a=rho*(a(-1))+u; - 1/c=beta*(1/(c(+1)))*(r/(pai(+1))); //euler - - omega*pai*(pai-1)=beta*omega*(c/(c(+1)))*(pai(+1))*(pai(+1)-1)+epsilon*exp(a)*n*(c/exp(a)*phi*n^gamma-(epsilon-1)/epsilon); //NK pc //pai*(pai-1)/c = beta*pai(+1)*(pai(+1)-1)/c(+1)+epsilon*phi*n^(gamma+1)/omega-exp(a)*n*(epsilon-1)/(omega*c); //NK pc - (exp(a))*n=c+(omega/2)*((pai-1)^2); - end; //-------------------------------------------------------------------------------------------------------------------------- @@ -55,18 +44,14 @@ end; //--------------------------------------------------------------------------------------------------------------------------- initval; - pai=1; r=1/beta; c=0.9671684882; n=0.9671684882; a=0; - - end; - //--------------------------------------------------------------------------------------------------------------------------- // 5. shocks //--------------------------------------------------------------------------------------------------------------------------- @@ -86,11 +71,9 @@ planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); write_latex_static_model; ramsey_model(planner_discount=0.99); - -options_.ramsey_policy=1; steady; -options_.simul.maxit = 20; -simul(periods=100); +perfect_foresight_setup(periods=200); +perfect_foresight_solver(maxit=20); rplot r; diff --git a/tests/optimal_policy/nk_ramsey_expectation.mod b/tests/optimal_policy/nk_ramsey_expectation.mod index 00212c000..246d426c4 100644 --- a/tests/optimal_policy/nk_ramsey_expectation.mod +++ b/tests/optimal_policy/nk_ramsey_expectation.mod @@ -90,7 +90,7 @@ write_latex_static_model; write_latex_dynamic_model; options_.solve_tolf=1e-12; -ramsey_policy(planner_discount=0.99); - - +ramsey_model(planner_discount=0.99); +stoch_simul(order=1,irf=0); +evaluate_planner_objective; diff --git a/tests/optimal_policy/nk_ramsey_expectation_a.mod b/tests/optimal_policy/nk_ramsey_expectation_a.mod index 8755e7f36..fc7978937 100644 --- a/tests/optimal_policy/nk_ramsey_expectation_a.mod +++ b/tests/optimal_policy/nk_ramsey_expectation_a.mod @@ -89,7 +89,9 @@ end; planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); options_.solve_tolf=1e-12; -ramsey_policy(planner_discount=0.99); +ramsey_model(planner_discount=0.99); +stoch_simul(order=1,irf=0); +evaluate_planner_objective; o1=load('nk_ramsey_expectation_results'); if (norm(o1.oo_.dr.ghx-oo_.dr.ghx,inf) > 1e-12) diff --git a/tests/optimal_policy/nk_ramsey_model.mod b/tests/optimal_policy/nk_ramsey_model.mod index f2736f916..dbce8ecfe 100644 --- a/tests/optimal_policy/nk_ramsey_model.mod +++ b/tests/optimal_policy/nk_ramsey_model.mod @@ -85,6 +85,5 @@ planner_objective(ln(c)-phi*((n^(1+gamma))/(1+gamma))); write_latex_static_model; ramsey_model(planner_discount=0.99); -options_.ramsey_policy=1; stoch_simul(irf=0); - +evaluate_planner_objective; diff --git a/tests/optimal_policy/ramsey_.mod b/tests/optimal_policy/ramsey_.mod index 4242f3d19..93917e701 100644 --- a/tests/optimal_policy/ramsey_.mod +++ b/tests/optimal_policy/ramsey_.mod @@ -28,4 +28,6 @@ planner_objective inflation^2 + lambda1*y^2 + lambda2*r^2; write_latex_dynamic_model; -ramsey_policy(planner_discount=0.95, order = 1); +ramsey_model(planner_discount=0.95); +stoch_simul(order=1); +evaluate_planner_objective; \ No newline at end of file diff --git a/tests/optimizers/fs2000_3.mod b/tests/optimizers/fs2000_3.mod index 5efc98d2a..09d2c59a5 100644 --- a/tests/optimizers/fs2000_3.mod +++ b/tests/optimizers/fs2000_3.mod @@ -1,5 +1,7 @@ @#include "fs2000.common.inc" -if exist('fminunc','file') +% Skip the test under R2009b, because fminunc fails due to Inf value. +% It remains to be determined in which version it started to work. +if exist('fminunc','file') && (isoctave || ~matlab_ver_less_than('7.10')) estimation(mode_compute=3,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); end diff --git a/tests/particle/benchmark.m b/tests/particle/benchmark.m index 6531fa3bc..99a99cb64 100644 --- a/tests/particle/benchmark.m +++ b/tests/particle/benchmark.m @@ -155,4 +155,4 @@ y = series(:,1) + 0.00158*randn(size(series(:,1))); l = series(:,2) + 0.0011*randn(size(series(:,2))); i = series(:,3) + 0.000866*randn(size(series(:,3))); -ti = [1950:0.25:1997.75] ; \ No newline at end of file +clear series; \ No newline at end of file diff --git a/tests/particle/dsge_base2.mod b/tests/particle/dsge_base2.mod index 592d35675..8b259d60e 100644 --- a/tests/particle/dsge_base2.mod +++ b/tests/particle/dsge_base2.mod @@ -25,6 +25,9 @@ @#ifndef ALGO_APF @#define ALGO_APF = 0 @#endif +@#ifndef ALGO_CPF +@#define ALGO_CPF = 0 +@#endif @#ifndef ALGO_GPF @#define ALGO_GPF = 0 @#endif @@ -70,6 +73,19 @@ log(A) = rho*log(A(-1)) + e_a ; (((c^(tet))*((1-l)^(1-tet)))^(1-tau))/c - bet*((((c(+1)^(tet))*((1-l(+1))^(1-tet)))^(1-tau))/c(+1))*(1 -delt+alp*(A(1)*(k^alp)*(l(1)^(1-alp)))/k)=0 ; end; +steady_state_model; + + k = -(alp-1)*(alp^(1/(1-alp)))*(bet^(1/(1-alp)))*((bet*(delt-1)+1)^(alp/(alp-1)))*tet/(-alp*delt*bet+delt*bet+alp*tet*bet-bet-alp*tet+1); + l = (alp-1)*(bet*(delt-1)+1)*tet/(alp*tet+bet*((alp-1)*delt-alp*tet+1)-1) ; + y = (k^alp)*(l^(1-alp)) ; + i = delt*k ; + c = y - i ; + A = 1; + +end; + + + shocks; var e_a; stderr 0.035; end; @@ -160,6 +176,10 @@ options_.threads.local_state_space_iteration_2 = 4; estimation(order=2,nograph,filter_algorithm=apf,number_of_particles=10000,resampling=none,mh_replic=0,mode_compute=8,mode_check); @#endif +@#if ALGO_CPF + estimation(order=2,nograph,filter_algorithm=cpf,number_of_particles=10000,resampling=none,mh_replic=0,mode_compute=8,mode_check); +@#endif + @#if ALGO_GPF estimation(order=2,nograph,filter_algorithm=gf,distribution_approximation=montecarlo,number_of_particles=1000,mh_replic=0,mode_compute=8); estimation(order=2,nograph,filter_algorithm=gf,distribution_approximation=montecarlo,number_of_particles=1000,mode_file=dsge_base2_mode,mh_replic=0,mode_compute=4,mode_check); diff --git a/tests/particle/dsge_base2_steadystate.m b/tests/particle/dsge_base2_steadystate.m deleted file mode 100644 index e23166849..000000000 --- a/tests/particle/dsge_base2_steadystate.m +++ /dev/null @@ -1,48 +0,0 @@ -function [ys,check,penlt] = dsge_base2_steadystate(ys, exe) -global M_ - -persistent idx NumberOfParameters NumberOfEndogenousVariables -persistent load_parameters fill_ys - - -if isempty(idx) - NumberOfParameters = M_.param_nbr; - NumberOfEndogenousVariables = M_.orig_endo_nbr; - load_parameters = []; - for i = 1:NumberOfParameters - load_parameters = [ load_parameters M_.param_names{i} ' = M_.params(' int2str(i) '); ']; - end - fill_ys = []; - for i = 1:NumberOfEndogenousVariables - fill_ys = [fill_ys 'ys(' int2str(i) ') = ' M_.endo_names{i} '_ss' '; ']; - end - idx = 1; -end - - -% Do not call matlab's routine! - -eval(load_parameters); - -ys = zeros(NumberOfEndogenousVariables,1); -check = 0; - -k_ss = -(alp-1)*(alp^(1/(1-alp)))*(bet^(1/(1-alp)))*((bet*(delt-1)+1)^(alp/(alp-1)))*tet; - -k_ss = k_ss/(-alp*delt*bet+delt*bet+alp*tet*bet-bet-alp*tet+1); - -l_ss = (alp-1)*(bet*(delt-1)+1)*tet; - -l_ss = l_ss/(alp*tet+bet*((alp-1)*delt-alp*tet+1)-1) ; - -y_ss = (k_ss^alp)*(l_ss^(1-alp)) ; - -i_ss = delt*k_ss ; - -c_ss = y_ss - i_ss ; - -A_ss = 1; - - -% Fill vector ys (steady state values). -eval(fill_ys); \ No newline at end of file diff --git a/tests/particle/extreme.m b/tests/particle/extreme.m index c6a7dba26..bb0919457 100644 --- a/tests/particle/extreme.m +++ b/tests/particle/extreme.m @@ -155,4 +155,4 @@ y = series(:,1) + 0.00158*randn(size(series(:,1))); l = series(:,2) + 0.0011*randn(size(series(:,2))); i = series(:,3) + 0.000866*randn(size(series(:,3))); -ti = [1950:0.25:1997.75] ; \ No newline at end of file +clear series; \ No newline at end of file diff --git a/tests/particle/local_state_space_iteration_k_test.mod b/tests/particle/local_state_space_iteration_k_test.mod new file mode 100644 index 000000000..5c805344f --- /dev/null +++ b/tests/particle/local_state_space_iteration_k_test.mod @@ -0,0 +1,76 @@ +/* + Tests that local_state_space_iteration_2 and local_state_space_iteration_k + (for k=2) return the same results. +*/ + +var y, k, a, h, b, c; +varexo e, u; + +parameters beta, rho, alpha, delta, theta, psi, tau; + +alpha = 0.36; +rho = 0.95; +tau = 0.025; +beta = 0.99; +delta = 0.025; +psi = 0; +theta = 2.95; + +phi = 0.1; + +model; +c*theta*h^(1+psi)=(1-alpha)*y; +k = beta*(((exp(b)*c)/(exp(b(+1))*c(+1))) + *(exp(b(+1))*alpha*y(+1)+(1-delta)*k)); +y = exp(a)*(k(-1)^alpha)*(h^(1-alpha)); +k = exp(b)*(y-c)+(1-delta)*k(-1); +a = rho*a(-1)+tau*b(-1) + e; +b = tau*a(-1)+rho*b(-1) + u; +end; + +initval; +y = 1.08068253095672; +c = 0.80359242014163; +h = 0.29175631001732; +k = 11.08360443260358; +a = 0; +b = 0; +e = 0; +u = 0; +end; + +shocks; +var e; stderr 0.009; +var u; stderr 0.009; +var e, u = phi*0.009*0.009; +end; + +stoch_simul(order=2, irf=0, k_order_solver); + +nparticles = 100; + +/* We generate particles using realistic distributions (though this is not + strictly needed) */ +state_idx = oo_.dr.order_var((M_.nstatic+1):(M_.nstatic+M_.npred+M_.nboth)); +yhat = chol(oo_.var(state_idx,state_idx))*randn(M_.npred+M_.nboth, nparticles); +epsilon = chol(M_.Sigma_e)*randn(M_.exo_nbr, nparticles); + +dr = oo_.dr; + +tStart1 = tic; for i=1:10000, ynext1 = local_state_space_iteration_2(yhat, epsilon, dr.ghx, dr.ghu, dr.ys(dr.order_var)+0.5*dr.ghs2, dr.ghxx, dr.ghuu, dr.ghxu, 1); end, tElapsed1 = toc(tStart1); + +tStart2 = tic; for i=1:10000, ynext2 = local_state_space_iteration_k(yhat, epsilon, dr, M_, options_); end, tElapsed2 = toc(tStart2); + +if max(max(abs(ynext1-ynext2))) > 1e-14 + error('Inconsistency between local_state_space_iteration_2 and local_state_space_iteration_k') +end + +if tElapsed1. +% ========================================================================= + +% set this to 1 if you want to recompute using the Andreasen et al toolbox +% otherwise the results are loaded from Andreasen_et_al_2018_Dynare44Pruning_v2.mat +@#define Andreasen_et_al_toolbox = 0 + +var YGR INFL INT + c p R g y z; %if ordering of var is changed comparison code below needs to be adapted +varexo e_r e_g e_z; +parameters tau nu kap cyst psi1 psi2 rhor rhog rhoz rrst pist gamst; + +tau = 2; +nu = 0.1; +kap = 0.33; +cyst = 0.85; +psi1 = 1.5; +psi2 = 0.125; +rhor = 0.75; +rhog = 0.95; +rhoz = 0.9; +rrst = 1; +pist = 3.2; +gamst = 0.55; +sig_r = .2; +sig_g = .6; +sig_z = .3; + +model; +#pist2 = exp(pist/400); +#rrst2 = exp(rrst/400); +#bet = 1/rrst2; +#phi = tau*(1-nu)/nu/kap/pist2^2; +#gst = 1/cyst; +#cst = (1-nu)^(1/tau); +#yst = cst*gst; +#dy = y-y(-1); +1 = exp(-tau*c(+1)+tau*c+R-z(+1)-p(+1)); +(1-nu)/nu/phi/(pist2^2)*(exp(tau*c)-1) = (exp(p)-1)*((1-1/2/nu)*exp(p)+1/2/nu) - bet*(exp(p(+1))-1)*exp(-tau*c(+1)+tau*c+y(+1)-y+p(+1)); +exp(c-y) = exp(-g) - phi*pist2^2*gst/2*(exp(p)-1)^2; +R = rhor*R(-1) + (1-rhor)*psi1*p + (1-rhor)*psi2*(y-g) + e_r; +g = rhog*g(-1) + e_g; +z = rhoz*z(-1) + e_z; +YGR = gamst+100*(dy+z); +INFL = pist+400*p; +INT = pist+rrst+4*gamst+400*R; +end; + +shocks; +var e_r = sig_r^2; +var e_g = sig_g^2; +var e_z = sig_z^2; +end; + +steady_state_model; +y = 0; +R = 0; +g = 0; +z = 0; +c = 0; +p = 0; +YGR = gamst; +INFL = pist; +INT = pist + rrst + 4*gamst; +end; + +steady; check; model_diagnostics; + +@#for orderApp in [1, 2, 3] + stoch_simul(order=@{orderApp},pruning,irf=0,periods=0); + pruned_state_space.order_@{orderApp} = pruned_state_space_system(M_, options_, oo_.dr, [], options_.ar, 1, 0); + @#if Andreasen_et_al_toolbox + addpath('Dynare44Pruning_v2/simAndMoments3order'); %provide path to toolbox + optPruning.orderApp = @{orderApp}; + outAndreasenetal.order_@{orderApp} = RunDynarePruning(optPruning,oo_,M_,[oo_.dr.ghx oo_.dr.ghu]); + rmpath('Dynare44Pruning_v2/simAndMoments3order'); + close all; + @#endif +@#endfor + +@#if Andreasen_et_al_toolbox + delete Andreasen_et_al_2018_Dynare44Pruning_v2.mat; + pause(3); + save('Andreasen_et_al_2018_Dynare44Pruning_v2.mat', 'outAndreasenetal') + pause(3); +@#endif + +load('Andreasen_et_al_2018_Dynare44Pruning_v2.mat') + +% Make comparisons only at orders 1 and 2 +for iorder = 1:3 + fprintf('ORDER %d:\n',iorder); + pruned = pruned_state_space.(sprintf('order_%d',iorder)); + outAndreasen = outAndreasenetal.(sprintf('order_%d',iorder)); + %make sure variable ordering is correct + if ~isequal(M_.endo_names,[outAndreasen.label_y; outAndreasen.label_v(1:M_.nspred)]) + error('variable ordering is not the same, change declaration order'); + end + norm_E_yx = norm(pruned.E_y(oo_.dr.inv_order_var) - [outAndreasen.Mean_y; outAndreasen.Mean_v(1:M_.nspred)] , Inf); + fprintf('max(sum(abs(E[y;x]''))): %d\n',norm_E_yx); + norm_Var_y = norm(pruned.Var_y(oo_.dr.inv_order_var(1:(M_.endo_nbr-M_.nspred)),oo_.dr.inv_order_var(1:(M_.endo_nbr-M_.nspred))) - outAndreasen.Var_y , Inf); + fprintf('max(sum(abs(Var[y]''))):: %d\n',norm_Var_y); + norm_Var_x = norm(pruned.Var_y(M_.nstatic+(1:M_.nspred),M_.nstatic+(1:M_.nspred)) - outAndreasen.Var_v(1:M_.nspred,1:M_.nspred) , Inf); + fprintf('max(sum(abs(Var[x]''))): %d\n',norm_Var_x); + norm_Corr_yi1 = norm(pruned.Corr_yi(oo_.dr.inv_order_var(1:(M_.endo_nbr-M_.nspred)),oo_.dr.inv_order_var(1:(M_.endo_nbr-M_.nspred)),1) - outAndreasen.Corr_y(:,:,1) , Inf); + fprintf('max(sum(abs(Corr[y,y(-1)]''))): %d\n',norm_Corr_yi1); + norm_Corr_yi2 = norm(pruned.Corr_yi(oo_.dr.inv_order_var(1:(M_.endo_nbr-M_.nspred)),oo_.dr.inv_order_var(1:(M_.endo_nbr-M_.nspred)),2) - outAndreasen.Corr_y(:,:,2) , Inf); + fprintf('max(sum(abs(Corr[y,y(-2)]''))): %d\n',norm_Corr_yi2); + norm_Corr_xi1 = norm(pruned.Corr_yi(M_.nstatic+(1:M_.nspred),M_.nstatic+(1:M_.nspred),1) - outAndreasen.Corr_v(1:M_.nspred,1:M_.nspred,1) , Inf); + fprintf('max(sum(abs(Corr[x,x(-1)]''))): %d\n',norm_Corr_xi1); + norm_Corr_xi2 = norm(pruned.Corr_yi(M_.nstatic+(1:M_.nspred),M_.nstatic+(1:M_.nspred),2) - outAndreasen.Corr_v(1:M_.nspred,1:M_.nspred,2) , Inf); + fprintf('max(sum(abs(Corr[x,x(-2)]''))): %d\n',norm_Corr_xi2); + + if iorder < 3 && any([norm_E_yx norm_Var_y norm_Var_x norm_Corr_yi1 norm_Corr_yi2 norm_Corr_xi1 norm_Corr_xi2] > 1e-5) + error('Something wrong with pruned_state_space.m compared to Andreasen et al 2018 Toolbox v2 at order %d.',iorder); + end +end +skipline(); +fprintf('Note that at third order, there is an error in the computation of Var_z in Andreasen et al (2018)''s toolbox, @wmutschl is in contact to clarify this.\n'); +fprintf('EXAMPLE:\n') +fprintf(' Consider Var[kron(kron(xf,xf),xf)] = E[kron(kron(kron(kron(kron(xf,xf),xf),xf),xf),xf)] - E[kron(kron(xf,xf),xf)]*E[kron(kron(xf,xf),xf)].''\n'); +fprintf(' Now note that xf=hx*xf(-1)+hu*u is Gaussian, that is E[kron(kron(xf,xf),xf)]=0, and Var[kron(kron(xf,xf),xf)] are the sixth-order product moments\n'); +fprintf(' which can be computed using the prodmom.m function by providing E[xf*xf''] as covariance matrix.\n'); +fprintf(' In order to replicate this you have to change UnconditionalMoments_3rd_Lyap.m to also output Var_z.\n') + +dynare_nx = M_.nspred; +dynare_E_xf2 = pruned_state_space.order_3.Var_z(1:dynare_nx,1:dynare_nx); +dynare_E_xf6 = pruned_state_space.order_3.Var_z((end-dynare_nx^3+1):end,(end-dynare_nx^3+1):end); +dynare_E_xf6 = dynare_E_xf6(:); + +Andreasen_nx = M_.nspred+M_.exo_nbr; +Andreasen_E_xf2 = outAndreasenetal.order_3.Var_z(1:Andreasen_nx,1:Andreasen_nx); +Andreasen_E_xf6 = outAndreasenetal.order_3.Var_z((end-Andreasen_nx^3+1):end,(end-Andreasen_nx^3+1):end); +Andreasen_E_xf6 = Andreasen_E_xf6(:); + +fprintf('Second-order product moments of xf and u are the same:\n') +norm_E_xf2 = norm(dynare_E_xf2-Andreasen_E_xf2(1:M_.nspred,1:M_.nspred),Inf) +norm_E_uu = norm(M_.Sigma_e-Andreasen_E_xf2(M_.nspred+(1:M_.exo_nbr),M_.nspred+(1:M_.exo_nbr)),Inf) + +% Compute unique sixth-order product moments of xf, i.e. unique(E[kron(kron(kron(kron(kron(xf,xf),xf),xf),xf),xf)],'stable') +dynare_nx6 = dynare_nx*(dynare_nx+1)/2*(dynare_nx+2)/3*(dynare_nx+3)/4*(dynare_nx+4)/5*(dynare_nx+5)/6; +dynare_Q6Px = Q6_plication(dynare_nx); +dynare_COMBOS6 = flipud(allVL1(dynare_nx, 6)); %all possible (unique) combinations of powers that sum up to six +dynare_true_E_xf6 = zeros(dynare_nx6,1); %only unique entries +for j6 = 1:size(dynare_COMBOS6,1) + dynare_true_E_xf6(j6) = prodmom(dynare_E_xf2, 1:dynare_nx, dynare_COMBOS6(j6,:)); +end +dynare_true_E_xf6 = dynare_Q6Px*dynare_true_E_xf6; %add duplicate entries +norm_dynare_E_xf6 = norm(dynare_true_E_xf6 - dynare_E_xf6, Inf); + +Andreasen_nx6 = Andreasen_nx*(Andreasen_nx+1)/2*(Andreasen_nx+2)/3*(Andreasen_nx+3)/4*(Andreasen_nx+4)/5*(Andreasen_nx+5)/6; +Andreasen_Q6Px = Q6_plication(Andreasen_nx); +Andreasen_COMBOS6 = flipud(allVL1(Andreasen_nx, 6)); %all possible (unique) combinations of powers that sum up to six +Andreasen_true_E_xf6 = zeros(Andreasen_nx6,1); %only unique entries +for j6 = 1:size(Andreasen_COMBOS6,1) + Andreasen_true_E_xf6(j6) = prodmom(Andreasen_E_xf2, 1:Andreasen_nx, Andreasen_COMBOS6(j6,:)); +end +Andreasen_true_E_xf6 = Andreasen_Q6Px*Andreasen_true_E_xf6; %add duplicate entries +norm_Andreasen_E_xf6 = norm(Andreasen_true_E_xf6 - Andreasen_E_xf6, Inf); + +fprintf('Sixth-order product moments of xf and u are not the same!\n'); +fprintf(' Dynare maximum absolute deviations of sixth-order product moments of xf: %d\n',norm_dynare_E_xf6) +fprintf(' Andreasen et al maximum absolute deviations of sixth-order product moments of xf: %d\n',norm_Andreasen_E_xf6) +skipline(); +fprintf('Note that the standard deviations are set quite high to make the numerical differences more apparent.\n'); diff --git a/tests/pruning/Andreasen_et_al_2018_Dynare44Pruning_v2.mat b/tests/pruning/Andreasen_et_al_2018_Dynare44Pruning_v2.mat new file mode 100644 index 000000000..7bfbab582 Binary files /dev/null and b/tests/pruning/Andreasen_et_al_2018_Dynare44Pruning_v2.mat differ diff --git a/tests/ramst2.mod b/tests/ramst2.mod index be2fe7a64..a9f92ccb2 100644 --- a/tests/ramst2.mod +++ b/tests/ramst2.mod @@ -36,6 +36,9 @@ end; simul(periods=200); +dynasave('myfile') c x k; +dynatype('myfile1.txt') c x k; + rplot c; rplot k; rplot dc; diff --git a/tests/run_all_unitary_tests.m b/tests/run_all_unitary_tests.m index 62238e728..a2d21ba65 100644 --- a/tests/run_all_unitary_tests.m +++ b/tests/run_all_unitary_tests.m @@ -1,4 +1,4 @@ -% Copyright (C) 2013-2019 Dynare Team +% Copyright (C) 2013-2020 Dynare Team % % This file is part of Dynare. % @@ -31,8 +31,19 @@ end mlist = get_directory_description('../matlab'); % Under Octave, do not run tests under matlab/missing/stats/ +% Also skip load_m_data_file_legacy.m: it fails in the first test, but +% this is impossible to reproduce outside the runners. if isoctave mlist = mlist(find(~strncmp('../matlab/missing/stats/', mlist, 24))); + mlist = mlist(find(~strcmp('../matlab/load_m_file_data_legacy.m', mlist))); +end + +% Set random seed, for reproducibility +if isoctave || matlab_ver_less_than('7.12') + randn('state',1); + rand('state',1); +else + rng(1); end failedtests = {}; @@ -72,4 +83,4 @@ fprintf(fid,':elapsed-time: %f\n',0.0); fclose(fid); if ~isoctave exit -end \ No newline at end of file +end diff --git a/tests/run_m_script.m b/tests/run_m_script.m index fe51168cc..6085fd5d0 100644 --- a/tests/run_m_script.m +++ b/tests/run_m_script.m @@ -1,4 +1,4 @@ -% Copyright (C) 2015 Dynare Team +% Copyright (C) 2015-2019 Dynare Team % % This file is part of Dynare. % @@ -24,7 +24,7 @@ addpath([top_test_dir filesep 'utils']); cd(directory); try - mscript; + eval(mscript); testFailed = false; catch exception printMakeCheckMatlabErrMsg(strtok(getenv('FILESTEM')), exception); @@ -51,4 +51,4 @@ else fprintf(fid,':list-of-passed-tests: %s\n', [name '.m']); end fclose(fid); -exit; \ No newline at end of file +exit; diff --git a/tests/run_o_script.m b/tests/run_o_script.m index 1db9ecbed..6e0ec09fb 100644 --- a/tests/run_o_script.m +++ b/tests/run_o_script.m @@ -1,4 +1,4 @@ -## Copyright (C) 2015-2016 Dynare Team +## Copyright (C) 2015-2019 Dynare Team ## ## This file is part of Dynare. ## @@ -26,7 +26,7 @@ addpath([top_test_dir filesep 'utils']); cd(directory); try - mscript; + eval(mscript); testFailed = false; catch printMakeCheckOctaveErrMsg(getenv('FILESTEM'), lasterror); diff --git a/tests/seeds.mod b/tests/seeds.mod index 467b80a0b..45e9b438d 100644 --- a/tests/seeds.mod +++ b/tests/seeds.mod @@ -86,7 +86,7 @@ if any(abs(t4(:))>1e-12) error('Test failure:: Problem with the seed of the random number algorithm') end -if ~isoctave && ~matlab_ver_less_than('7.7') +if ~isoctave set_dynare_seed('mlfg6331_64',0) stoch_simul(periods=1000,irf=0,nomoments); diff --git a/tests/shock_decomposition/ls2003_plot.mod b/tests/shock_decomposition/ls2003_plot.mod index 895de40e9..cbac0b73e 100644 --- a/tests/shock_decomposition/ls2003_plot.mod +++ b/tests/shock_decomposition/ls2003_plot.mod @@ -31,6 +31,13 @@ pie_obs = 4*pie; R_obs = 4*R; end; +epilogue; +// annualized level of y +ya = exp(y)+exp(y(-1))+exp(y(-2))+exp(y(-3)); +// annualized growth rate of y +gya = ya/ya(-4)-1; +end; + shocks; var e_R = 1.25^2; var e_q = 2.5^2; @@ -76,47 +83,67 @@ supply = e_A ; 'RoW shocks' = e_q e_ys e_pies ; monetary = e_R ; end; -options_.initial_date=dates('1989Q4'); % date arbitrarily set for testing purposes -shock_decomposition(use_shock_groups=trade) y_obs R_obs pie_obs dq de; -// various tests for plot_shock_decompositions -// standard plot [using trade group defined before] -plot_shock_decomposition; +init2shocks; +dq e_q; +A e_A; +end; + +options_.initial_date=dates('1989Q4'); % date arbitrarily set for testing purposes +shock_decomposition(nograph, with_epilogue); +// test for nothing to squeeze +squeeze_shock_decomposition; + +// standard plot +plot_shock_decomposition y_obs R_obs pie_obs dq de; +// grouped shocks +plot_shock_decomposition(use_shock_groups=trade) y_obs R_obs pie_obs dq de; // test datailed, custom name and yoy plots -plot_shock_decomposition(detail_plot, fig_name = MR, type = yoy); +plot_shock_decomposition(detail_plot, fig_name = MR, type = yoy) y_obs R_obs pie_obs dq de; +// testing init2shocks +initial_condition_decomposition(detail_plot, type=aoa, steadystate, write_xls, plot_init_date=1991Q1, plot_end_date=1995Q4) R_obs; +plot_shock_decomposition(init2shocks) y_obs R_obs pie_obs dq de; +plot_shock_decomposition(init2shocks,use_shock_groups=trade) y_obs R_obs pie_obs dq de; + +// testing flip and diff +plot_shock_decomposition(diff, use_shock_groups=trade) y_obs; +plot_shock_decomposition(flip, use_shock_groups=trade) de; close all, // testing realtime decomposition // first compute realtime decompositions [pre-processor not yet available] -realtime_shock_decomposition(forecast=8, save_realtime=[5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77]); +realtime_shock_decomposition(forecast=8, save_realtime=[5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77]) y_obs R_obs pie_obs dq de; + +// test squeeze +squeeze_shock_decomposition; //realtime pooled -plot_shock_decomposition(realtime = 1); +plot_shock_decomposition(realtime = 1) y_obs R_obs pie_obs dq de; //conditional pooled -plot_shock_decomposition(realtime = 2); +plot_shock_decomposition(realtime = 2) y_obs R_obs pie_obs dq de; // conditional 8-step ahead decomposition, given 1989q4 -plot_shock_decomposition(detail_plot, realtime = 2, vintage = 29); +plot_shock_decomposition(detail_plot, realtime = 2, vintage = 29) y_obs R_obs pie_obs dq de; close all, //forecast pooled -plot_shock_decomposition(realtime = 3); +plot_shock_decomposition(realtime = 3) y_obs R_obs pie_obs dq de; // forecast 8-step ahead decomposition, given 1989q4 -plot_shock_decomposition(detail_plot, realtime = 3, vintage = 29); +plot_shock_decomposition(detail_plot, realtime = 3, vintage = 29) y_obs R_obs pie_obs dq de; close all, // now I test annualized variables -options_.plot_shock_decomp.q2a=1; -options_.plot_shock_decomp.islog=1; + // this also triggers re-computing of decompositions since y was not present in squeeze set plot_shock_decomposition(detail_plot, type = aoa) y; +plot_shock_decomposition(detail_plot, type = aoa) ya; plot_shock_decomposition(realtime = 1) y; plot_shock_decomposition(realtime = 1, vintage = 29) y; @@ -126,14 +153,17 @@ plot_shock_decomposition(realtime = 3, vintage = 29) y; close all //test uimenu for groups -plot_shock_decomposition(detail_plot, interactive, use_shock_groups = row, type = qoq); -plot_shock_decomposition(detail_plot, interactive, realtime = 3, vintage = 29); +plot_shock_decomposition(detail_plot, interactive, use_shock_groups = row, type = qoq, plot_init_date=2004Q1) y_obs R_obs pie_obs dq de; +plot_shock_decomposition(detail_plot, interactive, realtime = 3, vintage = 29) y_obs R_obs pie_obs dq de; close all, // testing realtime decomposition with fast_realtime option -realtime_shock_decomposition(fast_realtime=75); +realtime_shock_decomposition(fast_realtime=75) y_obs R_obs pie_obs dq de; + +// re-test squeeze +squeeze_shock_decomposition; collect_latex_files; if system(['pdflatex -halt-on-error -interaction=batchmode ' M_.fname '_TeX_binder.tex']) diff --git a/tests/smoother2histval/fs2000_simul.mod b/tests/smoother2histval/fs2000_simul.mod index 1da3842be..eb65974e1 100644 --- a/tests/smoother2histval/fs2000_simul.mod +++ b/tests/smoother2histval/fs2000_simul.mod @@ -62,6 +62,8 @@ var e_a; stderr 0.014; var e_m; stderr 0.005; end; +results_estimation=load('fs2000_smooth_results'); +M_.params=results_estimation.M_.params; steady; histval_file(filename = 'fs2000_histval.mat'); diff --git a/tests/steady_state/Gali_2015_chapter_6_4.mod b/tests/steady_state/Gali_2015_chapter_6_4.mod new file mode 100644 index 000000000..64c5df3c0 --- /dev/null +++ b/tests/steady_state/Gali_2015_chapter_6_4.mod @@ -0,0 +1,277 @@ +/* + * This file implements the New Keynesian model with price and wage rigidities under optimal policy + * with commitment (Ramsey) of Jordi Gal (2015): Monetary Policy, Inflation, and the Business Cycle, Princeton + * University Press, Second Edition, Chapter 6.4 + * + * THIS MOD-FILE REQUIRES DYNARE 4.6 OR HIGHER + * + * Notes: + * - all model variables are expressed in deviations from steady state, i.e. in contrast to + * to the chapter, the nominal interest rate, natural output, and the natural real wage are not in log-levels, but rather mean 0 + * - in the LOM for the discount rate shock z the shock enters with a minus sign in this mod-file to generate the + * IRF to a -0.5% shock + * + * This implementation was written by Johannes Pfeifer. In case you spot mistakes, + * email me at jpfeifer@gmx.de + * + * Please note that the following copyright notice only applies to this Dynare + * implementation of the model. + */ + +/* + * Copyright (C) 2020 Dynare Team + * + * This 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. + * + * It 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. + * + * For a copy of the GNU General Public License, + * see . + */ + +%define whether to use interest rate or money growth rate rule +@#define money_growth_rule=1 + +var pi_p ${\pi^p}$ (long_name='price inflation') + y_gap ${\tilde y}$ (long_name='output gap') + y_nat ${y^{nat}}$ (long_name='natural output') //(in contrast to the textbook defined in deviation from steady state) + y ${y}$ (long_name='output') + yhat ${\hat y}$ (long_name='output deviation from steady state') + r_nat ${r^{nat}}$ (long_name='natural interest rate') + r_real ${r^r}$ (long_name='real interest rate') + i ${i}$ (long_name='nominal interrst rate') + n ${n}$ (long_name='hours worked') + m_real ${(m-p)}$ (long_name='real money stock') + m_growth_ann ${\Delta m}$ (long_name='money growth annualized') + m_nominal ${m}$ (long_name='nominal money stock') + nu ${\nu}$ (long_name='AR(1) monetary policy shock process') + a ${a}$ (long_name='AR(1) technology shock process') + r_real_ann ${r^{r,ann}}$ (long_name='annualized real interest rate') + i_ann ${i^{ann}}$ (long_name='annualized nominal interest rate') + r_nat_ann ${r^{nat,ann}}$ (long_name='annualized natural interest rate') + pi_p_ann ${\pi^{p,ann}}$ (long_name='annualized inflation rate') + z ${z}$ (long_name='AR(1) preference shock process') + p ${p}$ (long_name='price level') + w ${w}$ (long_name='nominal wage') + c ${c}$ (long_name='consumption') + w_real $\omega$ (long_name='real wage') + w_gap ${\tilde \omega}$ (long_name='real wage gap') + pi_w ${\pi^w}$ (long_name='wage inflation') + w_nat ${w^{nat}}$ (long_name='natural real wage') + mu_p ${\mu^p}$ (long_name='markup') + pi_w_ann ${\pi^{w,ann}}$ (long_name='annualized wage inflation rate') +; + +varexo eps_a ${\varepsilon_a}$ (long_name='technology shock') + eps_nu ${\varepsilon_\nu}$ (long_name='monetary policy shock') + eps_z ${\varepsilon_z}$ (long_name='preference shock innovation') + ; + +parameters alppha ${\alpha}$ (long_name='capital share') + betta ${\beta}$ (long_name='discount factor') + rho_a ${\rho_a}$ (long_name='autocorrelation technology shock') + rho_nu ${\rho_{\nu}}$ (long_name='autocorrelation monetary policy shock') + rho_z ${\rho_{z}}$ (long_name='autocorrelation monetary demand shock') + siggma ${\sigma}$ (long_name='inverse EIS') + varphi ${\varphi}$ (long_name='inverse Frisch elasticity') + phi_pi ${\phi_{\pi}}$ (long_name='inflation feedback Taylor Rule') + phi_y ${\phi_{y}}$ (long_name='output feedback Taylor Rule') + eta ${\eta}$ (long_name='semi-elasticity of money demand') + epsilon_p ${\epsilon_p}$ (long_name='demand elasticity goods') + theta_p ${\theta_p}$ (long_name='Calvo parameter prices') + epsilon_w ${\epsilon_w}$ (long_name='demand elasticity labor services') + theta_w ${\theta_w}$ (long_name='Calvo parameter wages') + lambda_p ${\lambda_p}$ (long_name='composite parameter Phillips Curve') + lambda_w ${\lambda_w}$ (long_name='composite parameter wage Phillips Curve') + ; +%---------------------------------------------------------------- +% Parametrization, p. 67 and p. 113-115 +%---------------------------------------------------------------- +siggma = 1; +varphi=5; +phi_pi = 1.5; +phi_y = 0.125; +theta_p=3/4; +rho_nu =0.5; +rho_z = 0.5; +rho_a = 0.9; +betta = 0.99; +eta =3.77; %footnote 11, p. 115 +alppha=1/4; +epsilon_p=9; + +epsilon_w=4.5; +theta_w=3/4; +%---------------------------------------------------------------- +% First Order Conditions +%---------------------------------------------------------------- + +model(linear); +//Composite parameters +#Omega=(1-alppha)/(1-alppha+alppha*epsilon_p); %defined on page 166 +#psi_n_ya=(1+varphi)/(siggma*(1-alppha)+varphi+alppha); %defined on page 171 +#psi_n_wa=(1-alppha*psi_n_ya)/(1-alppha); %defined on page 171 +#aleph_p=alppha*lambda_p/(1-alppha); %defined on page 172 +#aleph_w=lambda_w*(siggma+varphi/(1-alppha)); %defined on page 172 +[name='New Keynesian Phillips Curve eq. (18)'] +pi_p=betta*pi_p(+1)+aleph_p*y_gap+lambda_p*w_gap; +[name='New Keynesian Wage Phillips Curve eq. (22)'] +pi_w=betta*pi_w(+1)+aleph_w*y_gap-lambda_w*w_gap; +[name='Dynamic IS Curve eq. (22)'] +y_gap=-1/siggma*(i-pi_p(+1)-r_nat)+y_gap(+1); +[name='Definition natural rate of interest eq. (24)'] +r_nat=-siggma*psi_n_ya*(1-rho_a)*a+(1-rho_z)*z; +w_gap=w_gap(-1)+pi_w-pi_p-(w_nat-w_nat(-1)); +[name='Definition natural wage, eq (16)'] +w_nat=psi_n_wa*a; +[name='Definition markup'] +mu_p=-alppha/(1-alppha)*y_gap-w_gap; +[name='Definition real wage gap, p. 171'] +w_gap=w_real-w_nat; +[name='Definition real interest rate'] +r_real=i-pi_p(+1); +[name='Definition natural output, eq. (20)'] +y_nat=psi_n_ya*a; +[name='Definition output gap'] +y_gap=y-y_nat; +[name='Monetary policy shock'] +nu=rho_nu*nu(-1)+eps_nu; +[name='TFP shock'] +a=rho_a*a(-1)+eps_a; +[name='Production function, p. 171'] +y=a+(1-alppha)*n; +[name='Preference shock, p. 54'] +z = rho_z*z(-1) - eps_z; +[name='Money growth (derived from eq. (4))'] +m_growth_ann=4*(y-y(-1)-eta*(i-i(-1))+pi_p); +[name='Real money demand (eq. 4)'] +m_real=y-eta*i; +[name='Annualized nominal interest rate'] +i_ann=4*i; +[name='Annualized real interest rate'] +r_real_ann=4*r_real; +[name='Annualized natural interest rate'] +r_nat_ann=4*r_nat; +[name='Annualized inflation'] +pi_p_ann=4*pi_p; +[name='Annualized wage inflation'] +pi_w_ann=4*pi_w; +[name='Output deviation from steady state'] +yhat=y-steady_state(y); +[name='Definition price level'] +pi_p=p-p(-1); +[name='resource constraint, eq. (12)'] +y=c; +[name='definition real wage'] +w_real=w-p; +[name='definition real wage'] +m_nominal=m_real+p; + + +end; + +steady_state_model; +lambda_p=(1-theta_p)*(1-betta*theta_p)/theta_p*((1-alppha)/(1-alppha+alppha*epsilon_p)); %defined on page 166 +lambda_w=(1-theta_w)*(1-betta*theta_w)/(theta_w*(1+epsilon_w*varphi)); %defined on page 170 +end; +%---------------------------------------------------------------- +% define shock variances +%--------------------------------------------------------------- + + +shocks; + var eps_a = 1; + var eps_z = 1; +end; + + +%---------------------------------------------------------------- +% generate IRFs for technology shock under optimal policy, replicates Figures 6.3, p. 182 +%---------------------------------------------------------------- +//planner objective, uses lambda_w and lambda_p updated in steady_state_model-block +planner_objective 0.5*((siggma+(varphi+alppha)/(1-alppha))*y_gap^2+ epsilon_p/lambda_p*pi_p^2+epsilon_w*(1-alppha)/lambda_w*pi_w^2); + +ramsey_model(instruments=(i),planner_discount=betta, planner_discount_latex_name = $\delta$); +stoch_simul(order=1,irf=16,noprint) y_gap pi_p_ann pi_w_ann w_real; +evaluate_planner_objective; + +oo_baseline=oo_; + +%flexible wage case +set_param_value('theta_w',0.0000000001); +set_param_value('theta_p',3/4); +stoch_simul(order=1,irf=16,noprint) y_gap pi_p_ann pi_w_ann w_real; +evaluate_planner_objective; +oo_flexible_wages=oo_; + +%flexible price case +set_param_value('theta_w',3/4) +set_param_value('theta_p',0.000000001) +stoch_simul(order=1,irf=16,noprint) y_gap pi_p_ann pi_w_ann w_real; +evaluate_planner_objective; +oo_flexible_prices=oo_; + + +figure('Name','Dynamic Responses to a technology shock under optimal policy') +subplot(2,2,1) +plot(1:options_.irf,oo_baseline.irfs.y_gap_eps_a,'-o',1:options_.irf,oo_flexible_wages.irfs.y_gap_eps_a,'-d',1:options_.irf,oo_flexible_prices.irfs.y_gap_eps_a,'-s') +ylim([-0.1 0.1]) +title('Output gap') +ll=legend('baseline','flexible wages','flexible prices'); +set(ll,'Location','SouthEast'); +subplot(2,2,2) +plot(1:options_.irf,oo_baseline.irfs.pi_p_ann_eps_a,'-o',1:options_.irf,oo_flexible_wages.irfs.pi_p_ann_eps_a,'-d',1:options_.irf,oo_flexible_prices.irfs.pi_p_ann_eps_a,'-s') +title('Price Inflation') +subplot(2,2,3) +plot(1:options_.irf,oo_baseline.irfs.pi_w_ann_eps_a,'-o',1:options_.irf,oo_flexible_wages.irfs.pi_w_ann_eps_a,'-d',1:options_.irf,oo_flexible_prices.irfs.pi_w_ann_eps_a,'-s') +title('Wage inflation') +subplot(2,2,4) +plot(1:options_.irf,oo_baseline.irfs.w_real_eps_a,'-o',1:options_.irf,oo_flexible_wages.irfs.w_real_eps_a,'-d',1:options_.irf,oo_flexible_prices.irfs.w_real_eps_a,'-s') +title('Real wage') + + +%---------------------------------------------------------------- +% generate first row of Table 6.1, p. 186 +%---------------------------------------------------------------- +shocks; + var eps_a = 1; +end; +set_param_value('theta_w',3/4); +set_param_value('theta_p',3/4); + +stoch_simul(order=1,irf=16,noprint) y_gap y_gap pi_p pi_w; +oo_baseline=oo_; + +y_gap_pos=strmatch('y_gap',var_list_ ,'exact'); +pi_p_pos=strmatch('pi_p',var_list_ ,'exact'); +pi_w_pos=strmatch('pi_w',var_list_ ,'exact'); + +%read out current parameter values +par.alppha=M_.params(strmatch('alppha',M_.param_names,'exact')); +par.epsilon_p=M_.params(strmatch('epsilon_p',M_.param_names,'exact')); +par.epsilon_w=M_.params(strmatch('epsilon_w',M_.param_names,'exact')); +par.siggma=M_.params(strmatch('siggma',M_.param_names,'exact')); +par.varphi=M_.params(strmatch('varphi',M_.param_names,'exact')); +par.lambda_w=M_.params(strmatch('lambda_w',M_.param_names,'exact')); +par.lambda_p=M_.params(strmatch('lambda_p',M_.param_names,'exact')); + +variance.y_gap=oo_.var(y_gap_pos,y_gap_pos); +variance.pi_p=oo_.var(pi_p_pos,pi_p_pos); +variance.pi_w=oo_.var(pi_w_pos,pi_w_pos); +L=0.5*((par.siggma+(par.varphi+par.alppha)/(1-par.alppha))*variance.y_gap+ par.epsilon_p/par.lambda_p*variance.pi_p+par.epsilon_w*(1-par.alppha)/par.lambda_w*variance.pi_w) + +labels={'sigma(pi_p)';'sigma(pi_w)';'sigma(tilde y)';'L'}; +headers={' ';'Optimal'}; +values=[sqrt([variance.pi_p;variance.pi_w;variance.y_gap]);L]; +options_.noprint=0; +dyntable(options_,'Evaluation of Simple Rules',headers,labels,values,size(labels,2)+2,4,3) + +if any(isnan(values)) + error('Parameter updating in steady state went wrong') +end \ No newline at end of file diff --git a/tests/stochastic_purely_forward/stochastic_purely_forward.mod b/tests/stochastic_purely_forward/stochastic_purely_forward.mod index 1fd41ccb6..6dd03fcaf 100644 --- a/tests/stochastic_purely_forward/stochastic_purely_forward.mod +++ b/tests/stochastic_purely_forward/stochastic_purely_forward.mod @@ -19,9 +19,15 @@ end; steady; check; +% Skip test under Octave 5.1 +% ordeig() is buggy in that version (but is fixed in later ones; and in older +% ones it is absent, so we use our replacement) +if ~isoctave || octave_ver_less_than('5.1') || ~octave_ver_less_than('5.2') + stoch_simul(periods=0, irf=30, order=1); stoch_simul(periods=2000, irf=30, order=1); stoch_simul(periods=0, irf=30, order=1,hp_filter=1600); stoch_simul(periods=2000, irf=30, order=1,hp_filter=1600); +end diff --git a/tests/stochastic_purely_forward/stochastic_purely_forward_with_static.mod b/tests/stochastic_purely_forward/stochastic_purely_forward_with_static.mod index 537416bad..8622d890f 100644 --- a/tests/stochastic_purely_forward/stochastic_purely_forward_with_static.mod +++ b/tests/stochastic_purely_forward/stochastic_purely_forward_with_static.mod @@ -20,8 +20,15 @@ end; steady; check; +% Skip test under Octave 5.1 +% ordeig() is buggy in that version (but is fixed in later ones; and in older +% ones it is absent, so we use our replacement) +if ~isoctave || octave_ver_less_than('5.1') || ~octave_ver_less_than('5.2') + stoch_simul(periods=0, irf=30, order=1); stoch_simul(periods=2000, irf=30, order=1); stoch_simul(periods=0, irf=30, order=1,hp_filter=1600); stoch_simul(periods=2000, irf=30, order=1,hp_filter=1600); + +end diff --git a/tests/stochastic_simulations/example1_noprint.mod b/tests/stochastic_simulations/example1_noprint.mod new file mode 100644 index 000000000..11d48a0cf --- /dev/null +++ b/tests/stochastic_simulations/example1_noprint.mod @@ -0,0 +1,68 @@ +/* + * Example 1 from F. Collard (2001): "Stochastic simulations with DYNARE: + * A practical guide" (see "guide.pdf" in the documentation directory). + */ + +/* + * Copyright (C) 2001-2010 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 . + */ + + +var y, c, k, a, h, b; +varexo e, u; + +parameters beta, rho, alpha, delta, theta, psi, tau; + +alpha = -0.36; // changed "0.36" to "-0.36" to generate an error +rho = 0.95; +tau = 0.025; +beta = 0.99; +delta = 0.025; +psi = 0; +theta = 2.95; + +phi = 0.1; + +model; +c*theta*h^(1+psi)=(1-alpha)*y; +k = beta*(((exp(b)*c)/(exp(b(+1))*c(+1))) + *(exp(b(+1))*alpha*y(+1)+(1-delta)*k)); +y = exp(a)*(k(-1)^alpha)*(h^(1-alpha)); +k = exp(b)*(y-c)+(1-delta)*k(-1); +a = rho*a(-1)+tau*b(-1) + e; +b = tau*a(-1)+rho*b(-1) + u; +end; + +initval; +y = 1.08068253095672; +c = 0.80359242014163; +h = 0.29175631001732; +k = 11.08360443260358; +a = 0; +b = 0; +e = 0; +u = 0; +end; + +shocks; +var e; stderr 0.009; +var u; stderr 0.009; +var e, u = phi*0.009*0.009; +end; + +stoch_simul(noprint); // added "noprint" diff --git a/windows/README.txt b/windows/README.txt index bba5320cc..f7608c602 100644 --- a/windows/README.txt +++ b/windows/README.txt @@ -52,14 +52,14 @@ Using Dynare with Octave Dynare also works on top of GNU Octave, a free clone of MATLAB® (see ). -This version of Dynare is compiled for Octave 5.1.0 (MinGW, 32-bit and 64-bit), +This version of Dynare is compiled for Octave 5.2.0 (MinGW, 32-bit and 64-bit), and may not work with other versions of Octave. The recommended version of Octave can be downloaded at: — For 64-bit systems: - https://ftpmirror.gnu.org/gnu/octave/windows/octave-5.1.0-w64-installer.exe + https://ftpmirror.gnu.org/gnu/octave/windows/octave-5.2.0_1-w64-installer.exe — For 32-bit systems: - https://ftpmirror.gnu.org/gnu/octave/windows/octave-5.1.0-w32-installer.exe + https://ftpmirror.gnu.org/gnu/octave/windows/octave-5.2.0_1-w32-installer.exe Every time you run Octave, you should type the following command (assuming that you have installed Dynare at the standard location, and replacing ‘4.x.y’ by diff --git a/windows/build.sh b/windows/build.sh index e947def86..b402d1c2d 100755 --- a/windows/build.sh +++ b/windows/build.sh @@ -5,7 +5,7 @@ # The binaries are cross compiled for Windows (32/64bits), Octave and MATLAB # (all supported versions). -# Copyright © 2017-2019 Dynare Team +# Copyright © 2017-2020 Dynare Team # # This file is part of Dynare. # @@ -248,7 +248,7 @@ ZIPDIR="$TMP_DIRECTORY"/"$ZIPNAME" mkdir -p "$ZIPDIR" cd .. -cp -p NEWS "$ZIPDIR" +cp -p NEWS.md "$ZIPDIR" cp -p VERSION "$ZIPDIR" cp -p license.txt "$ZIPDIR" cp -p windows/README.txt "$ZIPDIR" @@ -270,7 +270,7 @@ cp -pr examples "$ZIPDIR" mkdir -p "$ZIPDIR"/scripts cp -p scripts/dynare.el "$ZIPDIR"/scripts mkdir "$ZIPDIR"/dynare++ -cp -pr dynare++/32-bit/ dynare++/64-bit/ "$ZIPDIR"/dynare++ +cp -pr dynare++/32-bit/ dynare++/64-bit/ dynare++/dynare_simul/dynare_simul.m "$ZIPDIR"/dynare++ mkdir -p "$ZIPDIR"/doc/dynare++ mkdir -p "$ZIPDIR"/doc/dynare-manual.html cp -pr doc/manual/build/html/* "$ZIPDIR"/doc/dynare-manual.html diff --git a/windows/deps/Makefile b/windows/deps/Makefile index 6723ed975..e51b9b9fb 100644 --- a/windows/deps/Makefile +++ b/windows/deps/Makefile @@ -148,15 +148,15 @@ clean-slicot-all: clean-slicot-src clean-slicot-tar clean-libslicot # Octave # -tarballs/octave-${OCTAVE_VERSION}-w32${OCTAVE_W32_BUILD}.7z: +tarballs/octave-${OCTAVE_VERSION}${OCTAVE_W32_BUILD}-w32.7z: mkdir -p tarballs wget $(WGET_OPTIONS) -O $@ https://ftp.gnu.org/gnu/octave/windows/$(notdir $@) -tarballs/octave-${OCTAVE_VERSION}-w64${OCTAVE_W64_BUILD}.7z: +tarballs/octave-${OCTAVE_VERSION}${OCTAVE_W64_BUILD}-w64.7z: mkdir -p tarballs wget $(WGET_OPTIONS) -O $@ https://ftp.gnu.org/gnu/octave/windows/$(notdir $@) -octave32: tarballs/octave-${OCTAVE_VERSION}-w32${OCTAVE_W32_BUILD}.7z +octave32: tarballs/octave-${OCTAVE_VERSION}${OCTAVE_W32_BUILD}-w32.7z rm -rf $@ 7zr x $< > /dev/null mv octave-${OCTAVE_VERSION}-w32 $@ @@ -165,7 +165,7 @@ octave32: tarballs/octave-${OCTAVE_VERSION}-w32${OCTAVE_W32_BUILD}.7z cd $@/mingw32/include && rm -f $$(grep -l "This file is part of the mingw-w64 runtime package" *.h) touch $@ -octave64: tarballs/octave-${OCTAVE_VERSION}-w64${OCTAVE_W64_BUILD}.7z +octave64: tarballs/octave-${OCTAVE_VERSION}${OCTAVE_W64_BUILD}-w64.7z rm -rf $@ 7zr x $< > /dev/null mv octave-${OCTAVE_VERSION}-w64 $@ @@ -179,8 +179,8 @@ octave: octave32 octave64 clean-octave: rm -rf octave32 rm -rf octave64 - rm -f tarballs/octave-${OCTAVE_VERSION}-w64${OCTAVE_W64_BUILD}.7z - rm -f tarballs/octave-${OCTAVE_VERSION}-w32${OCTAVE_W32_BUILD}.7z + rm -f tarballs/octave-${OCTAVE_VERSION}${OCTAVE_W64_BUILD}-w64.7z + rm -f tarballs/octave-${OCTAVE_VERSION}${OCTAVE_W32_BUILD}-w32.7z # # MATLAB @@ -234,12 +234,12 @@ lib64-msys2: tarballs/mingw-w64-x86_64-boost-$(MINGW64_BOOST_VERSION)-any.pkg.ta for f in $^; do tar xf $$f --directory $@ --strip-components 1 $(MSYS2_EXCLUDES); done touch $@ -mingw32: tarballs/mingw-w64-i686-gcc-$(MINGW32_GCC_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-gmp-$(MINGW32_GMP_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-binutils-$(MINGW32_BINUTILS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-headers-git-$(MINGW32_HEADERS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-crt-git-$(MINGW32_CRT_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-winpthreads-git-$(MINGW32_WINPTHREADS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-libwinpthread-git-$(MINGW32_LIBWINPTHREAD_VERSION)-any.pkg.tar.xz +mingw32: tarballs/mingw-w64-i686-gcc-$(MINGW32_GCC_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-gcc-libs-$(MINGW32_GCC_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-gmp-$(MINGW32_GMP_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-binutils-$(MINGW32_BINUTILS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-headers-git-$(MINGW32_HEADERS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-crt-git-$(MINGW32_CRT_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-winpthreads-git-$(MINGW32_WINPTHREADS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-libwinpthread-git-$(MINGW32_WINPTHREADS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-i686-zlib-$(MINGW32_ZLIB_VERSION)-any.pkg.tar.xz rm -rf $@ for f in $^; do tar xf $$f $(MSYS2_EXCLUDES); done touch $@ -mingw64: tarballs/mingw-w64-x86_64-gcc-$(MINGW64_GCC_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-gmp-$(MINGW64_GMP_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-binutils-$(MINGW64_BINUTILS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-headers-git-$(MINGW64_HEADERS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-crt-git-$(MINGW64_CRT_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-winpthreads-git-$(MINGW64_WINPTHREADS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-libwinpthread-git-$(MINGW64_LIBWINPTHREAD_VERSION)-any.pkg.tar.xz +mingw64: tarballs/mingw-w64-x86_64-gcc-$(MINGW64_GCC_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-gcc-libs-$(MINGW64_GCC_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-gmp-$(MINGW64_GMP_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-binutils-$(MINGW64_BINUTILS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-headers-git-$(MINGW64_HEADERS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-crt-git-$(MINGW64_CRT_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-winpthreads-git-$(MINGW64_WINPTHREADS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-libwinpthread-git-$(MINGW64_WINPTHREADS_VERSION)-any.pkg.tar.xz tarballs/mingw-w64-x86_64-zlib-$(MINGW64_ZLIB_VERSION)-any.pkg.tar.xz rm -rf $@ for f in $^; do tar xf $$f $(MSYS2_EXCLUDES); done touch $@ diff --git a/windows/deps/versions.mk b/windows/deps/versions.mk index 893de385d..811ee558f 100644 --- a/windows/deps/versions.mk +++ b/windows/deps/versions.mk @@ -1,9 +1,9 @@ SLICOT_VERSION = 5.0+20101122 X13AS_VERSION = 1.1_B39 -OCTAVE_VERSION = 5.1.0 -OCTAVE_W32_BUILD = -OCTAVE_W64_BUILD = +OCTAVE_VERSION = 5.2.0 +OCTAVE_W32_BUILD = _1 +OCTAVE_W64_BUILD = _1 MATLAB32_VERSION = 20181204 MATLAB64_VERSION = 20181204 @@ -20,22 +20,22 @@ MATLAB64_VERSION = 20181204 ## Build dependencies # pacman -Ss .*-boost$ -MINGW32_BOOST_VERSION = 1.71.0-3 -MINGW64_BOOST_VERSION = 1.71.0-3 +MINGW32_BOOST_VERSION = 1.72.0-1 +MINGW64_BOOST_VERSION = 1.72.0-1 # pacman -Ss .*-gsl$ MINGW32_GSL_VERSION = 2.6-1 MINGW64_GSL_VERSION = 2.6-1 # pacman -Ss .*-openblas$ -MINGW32_OPENBLAS_VERSION = 0.3.7-1 -MINGW64_OPENBLAS_VERSION = 0.3.7-1 +MINGW32_OPENBLAS_VERSION = 0.3.9-1 +MINGW64_OPENBLAS_VERSION = 0.3.9-1 # pacman -Ss .*-matio$ MINGW32_MATIO_VERSION = 1.5.17-1 MINGW64_MATIO_VERSION = 1.5.17-1 -# Dependency of matio +# Dependency of matio (and of the MinGW compiler) # pacman -Ss .*-zlib$ MINGW32_ZLIB_VERSION = 1.2.11-7 MINGW64_ZLIB_VERSION = 1.2.11-7 @@ -53,30 +53,25 @@ MINGW64_SZIP_VERSION = 2.1.1-2 ## MinGW packages for the embedded compiler # pacman -Ss mingw-w64-.*-gcc$ -MINGW32_GCC_VERSION = 9.2.0-2 -MINGW64_GCC_VERSION = 9.2.0-2 +MINGW32_GCC_VERSION = 9.3.0-1 +MINGW64_GCC_VERSION = 9.3.0-1 # pacman -Ss mingw-w64-.*-gmp$ -MINGW32_GMP_VERSION = 6.1.2-1 -MINGW64_GMP_VERSION = 6.1.2-1 +MINGW32_GMP_VERSION = 6.2.0-1 +MINGW64_GMP_VERSION = 6.2.0-1 # pacman -Ss mingw-w64-.*-binutils -MINGW32_BINUTILS_VERSION = 2.33.1-1 -MINGW64_BINUTILS_VERSION = 2.33.1-1 +MINGW32_BINUTILS_VERSION = 2.34-1 +MINGW64_BINUTILS_VERSION = 2.34-1 # pacman -Ss mingw-w64-.*-headers-git -MINGW32_HEADERS_VERSION = 8.0.0.5576.34082b63-1 -MINGW64_HEADERS_VERSION = 8.0.0.5576.34082b63-1 +MINGW32_HEADERS_VERSION = 8.0.0.5685.ef310786-1 +MINGW64_HEADERS_VERSION = 8.0.0.5685.ef310786-1 # pacman -Ss mingw-w64-.*-crt-git -MINGW32_CRT_VERSION = 8.0.0.5576.34082b63-1 -MINGW64_CRT_VERSION = 8.0.0.5576.34082b63-1 +MINGW32_CRT_VERSION = 8.0.0.5685.ef310786-1 +MINGW64_CRT_VERSION = 8.0.0.5685.ef310786-1 # pacman -Ss mingw-w64-.*-winpthreads-git -MINGW32_WINPTHREADS_VERSION = 8.0.0.5574.33e5a2ac-1 -MINGW64_WINPTHREADS_VERSION = 8.0.0.5574.33e5a2ac-1 - -# pacman -Ss mingw-w64-.*-libwinpthread-git -# NB: "thread" is singular here -MINGW32_LIBWINPTHREAD_VERSION = 8.0.0.5574.33e5a2ac-1 -MINGW64_LIBWINPTHREAD_VERSION = 8.0.0.5574.33e5a2ac-1 +MINGW32_WINPTHREADS_VERSION = 8.0.0.5680.0df6b89f-1 +MINGW64_WINPTHREADS_VERSION = 8.0.0.5680.0df6b89f-1 diff --git a/windows/dynare.nsi b/windows/dynare.nsi index b4e023cce..04a4278b6 100644 --- a/windows/dynare.nsi +++ b/windows/dynare.nsi @@ -50,7 +50,7 @@ Section "Dynare core (preprocessor and M-files)" SectionIn RO !insertmacro DETERMINE_CONTEXT SetOutPath $INSTDIR - File README.txt ..\NEWS ..\license.txt ..\VERSION + File README.txt ..\NEWS.md ..\license.txt ..\VERSION SetOutPath $INSTDIR\matlab File /r ..\matlab\*.m @@ -101,7 +101,7 @@ Section "MEX files for MATLAB 64-bit, version 9.4 to 9.8 (R2018a to R2020a)" File ..\mex\matlab\win64-9.4-9.8\*.mexw64 SectionEnd -Section "MEX files for Octave 5.1.0 (64-bit)" +Section "MEX files for Octave 5.2.0 (64-bit)" SetOutPath $INSTDIR\mex\octave\win64 File ..\mex\octave\win64\* SectionEnd @@ -121,7 +121,7 @@ Section "MEX files for MATLAB 32-bit, version 7.9 to 8.6 (R2009b to R2015b)" File ..\mex\matlab\win32-7.9-8.6\*.mexw32 SectionEnd -Section "MEX files for Octave 5.1.0 (32-bit)" +Section "MEX files for Octave 5.2.0 (32-bit)" SetOutPath $INSTDIR\mex\octave\win32 File ..\mex\octave\win32\* SectionEnd @@ -158,6 +158,9 @@ Section /o "Dynare++ (standalone executable)" SetOutPath $INSTDIR\dynare++\64-bit File ..\dynare++\64-bit\dynare++.exe + SetOutPath $INSTDIR\dynare++ + File ..\dynare++\dynare_simul\dynare_simul.m + SetOutPath $INSTDIR\doc\dynare++ File ..\dynare++\doc\*.pdf @@ -172,7 +175,7 @@ Section "Uninstall" # First delete the uninstaller Delete $INSTDIR\uninstall.exe Delete $INSTDIR\README.txt - Delete $INSTDIR\NEWS + Delete $INSTDIR\NEWS.md Delete $INSTDIR\license.txt Delete $INSTDIR\VERSION Rmdir /r $INSTDIR\matlab diff --git a/windows/install-packages.sh b/windows/install-packages.sh index 4ea28b0d0..5b53c511a 100755 --- a/windows/install-packages.sh +++ b/windows/install-packages.sh @@ -24,7 +24,7 @@ PACKAGES=(make xz-utils p7zip bzip2 zip patch wget autoconf automake libtool mingw-w64 gfortran-mingw-w64 parallel flex bison texlive - texlive-publishers texlive-latex-extra texlive-math-extra + texlive-publishers texlive-latex-extra texlive-science texlive-fonts-extra lmodern python3-sphinx latexmk nsis) apt install "${PACKAGES[@]}"