Compare commits

..

68 Commits
master ... 6.x

Author SHA1 Message Date
Johannes Pfeifer 779b45fd13
SMC: gracefully exit with unsupported options
(cherry picked from commit 5d47ac2aa9)
2024-02-20 08:51:42 +01:00
Sébastien Villemot 9a179a3949
🐛 Steady state computation with bytecode + Ramsey policy was broken
(cherry picked from commit 1ce40d4df5)
2024-02-16 19:00:02 +01:00
Sébastien Villemot b7540c40e3
Manual: cosmetics
(cherry picked from commit 3000e6d691)
2024-02-16 14:08:46 +01:00
Johannes Pfeifer 94b8204711
solve_block_decomposed_problem.m: add missing semicolon
(cherry picked from commit 73d54cea04)
2024-02-16 14:08:46 +01:00
Willi Mutschler edca9c8f45
Update Dockerfile and instructions for new meson build systems
[skip ci]
This creates the Docker containers for 5.5 and 6.0

(cherry picked from commit 1b3c1c33ce)
2024-02-16 14:08:46 +01:00
Johannes Pfeifer 862261c9b9
gsa: update documentation
(cherry picked from commit 4a2724959d)
2024-02-14 14:08:08 +01:00
Johannes Pfeifer 711ff0e573
selec_posterior_draws.m: fix bug introduced when removing oo_ as an input
Thanks to Francesco Turino

(cherry picked from commit 6975aaef43)
2024-02-12 16:59:46 +01:00
Sébastien Villemot 76538d894a
Cosmetics
[skip ci]

(cherry picked from commit ec48980e1e)
2024-02-07 13:58:01 +01:00
Sébastien Villemot deab8ab5e4
Bump version number
[skip ci]
2024-02-05 16:10:30 +01:00
Sébastien Villemot 4111b88b89
CI: fix job for deploying manual
[skip ci]
2024-02-05 15:39:09 +01:00
Sébastien Villemot b654d2fdc2
NEWS.md: announcement for version 6.0
[skip ci]

(cherry picked from commit ebfd2aa0a1)
2024-02-02 18:33:37 +01:00
Sébastien Villemot 41dde2259c
Manual: update citation of reference manual working paper
(cherry picked from commit 433f00e224)
2024-02-02 18:33:36 +01:00
Sébastien Villemot 164eb44f6a
Manual: add missing options to occbin_solver
(cherry picked from commit d61cb124ba)
2024-02-02 18:33:36 +01:00
Sébastien Villemot 95492c418b
Manual: better documentation of solve_algo=12,14
(cherry picked from commit 05d82796c2)
2024-02-02 18:33:36 +01:00
Sébastien Villemot 1c19965cda
Manual: typos and cosmetics
(cherry picked from commit cfa978b39e)
2024-02-02 18:33:36 +01:00
Sébastien Villemot cc0b041e18
Manual: fix capitalization of Dynare Team on front page of PDF
(cherry picked from commit 99883d4ca6)
2024-02-01 21:53:04 +01:00
Sébastien Villemot edc81dd79e
Preprocessor: fix prototype of sparse {static,dynamic}_gN_tt.m for N⩾2 2024-01-31 18:16:52 +01:00
Johannes Pfeifer 2427888879
manual: clarify that search requires json
(cherry picked from commit a40b0c146d)
2024-01-30 11:18:28 +01:00
Johannes Pfeifer 45f838b559
manual: fix description of conditional likelihood
(cherry picked from commit 8e91841a39)
2024-01-30 11:18:28 +01:00
Johannes Pfeifer 943461a02f
annualized_shock_decomposition.m: fix bug introduced in 735bd66d
Use dedicated indicator instead of nargout to only request decomposition; closes #1919

(cherry picked from commit 2ed416532b)
2024-01-30 11:18:28 +01:00
Stéphane Adjemian (Argos) bd4357266a
Document dplot Matlab command.
(cherry picked from commit f5a5ebb910)
2024-01-29 20:58:59 +01:00
Sébastien Villemot a7d816cf99
Windows and macOS packages: fix installation path of x13as
The binary location had not been updated following the move of the dseries
submodule (commit e962cb4dba).

(cherry picked from commit 60e3b6a19f)
2024-01-29 16:33:02 +01:00
Stéphane Adjemian (Argos) 3a3d1db710
Add example for PAC equation (with estimation).
(cherry picked from commit 415a86d1d9)
2024-01-29 15:27:51 +01:00
Stéphane Adjemian (Argos) 50c1fb3597
Document composite targets in PAC equation.
(cherry picked from commit 8eab48aa5e)
2024-01-29 15:27:29 +01:00
Stéphane Adjemian (Argos) c8dd3045c9
Throw an error if composite PAC target ∧ trend_component aux. model.
(cherry picked from commit 9f9f4a99ba)
2024-01-29 15:27:09 +01:00
Stéphane Adjemian (Argos) c365f53e5c
Bug fix (wrong condition).
Also add comments about the choice for the definition of the linear
combination of the VAR companion variables.

We should test the numbe of output arguments, not the number of input
arguments. This was bug was probably not affecting the outcomes since
the number of input arguments is always greater than 1.

(cherry picked from commit a48a03bc67)
2024-01-29 15:26:49 +01:00
Stéphane Adjemian (Argos) 66c7e53ff2
Cosmetic changes.
(cherry picked from commit 942d8846e4)
2024-01-29 15:26:28 +01:00
Sébastien Villemot 0803119de4
README.md: fix testsuite documentation for running a whole directory of tests
[skip ci]
2024-01-29 13:59:57 +01:00
Sébastien Villemot 800da740dc
Occbin: add various consistency checks for bind/relax tags
In particular, emit more explicit error messages in the presence of
inconsistencies.

Closes: #103
2024-01-26 20:34:03 +01:00
Sébastien Villemot 4f4e5b8680
Bytecode: error out when using det_cond_forecast with perfect_foresight shocks
They’re not implemented in bytecode.

Closes: #1884
(cherry picked from commit 8954a682c7)
2024-01-26 10:19:11 +01:00
Sébastien Villemot 0149af67b7
Preprocessor / dseries: fix handling of monthly dates for months 10-12
Closes: #1918

(manually cherry picked from commit 6a0ee900a4)
2024-01-26 10:18:57 +01:00
Johannes Pfeifer 7e5888485b
gsa: add proper check for correctness of qz_criterium with unit roots
Critical for stability mapping

(cherry picked from commit b1cb309a73)
2024-01-22 19:06:01 +01:00
Sébastien Villemot ca0823fee4
Build system: workaround for Meson bug, needed for building MATLAB Online package
(cherry picked from commit 330542a79f)
2024-01-22 19:06:01 +01:00
Sébastien Villemot 052bb135c3
MATLAB Online package: update build script for meson
Also, use the local git checkout instead of downloading a source tarball from
the website.

(cherry picked from commit b2f603091a)
2024-01-22 19:06:01 +01:00
Sébastien Villemot c54cb4d29c
Build system: under Linux, do not try to statically link libgomp even with -Dprefer_static=true
Under Debian 12, it fails with:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/12/libgomp.a(team.o): réadressage R_X86_64_TPOFF32 vers symbole caché « gomp_tls_data » ne peut pas être utilisé en créant un objet partagé

(cherry picked from commit 88236b1cc0)
2024-01-22 19:06:01 +01:00
Johannes Pfeifer 57e8c52ef9
GSA_recursive: make sure nobs is correctly set before checking for recursive estimation
Closes #1611

(cherry picked from commit 619de017d6)
2024-01-17 21:31:08 +01:00
Sébastien Villemot 510ba16601
Manual: do not add parentheses to synopsis of functions without arguments
Closes: #1707
(cherry picked from commit 85c637d3d1)
2024-01-17 21:31:08 +01:00
Sébastien Villemot c87c82c5a4
Remove remnants of workaround for incorrect display of macro-directives without arguments
This workaround was implemented in cd195279e9.
The zero-width spaces were inadvertently removed in
248ad18846.

Ref. #1707

(cherry picked from commit 6fe43545d8)
2024-01-17 21:31:08 +01:00
Sébastien Villemot c7d0f29dba
Manual: minor fixes to function synopses
(cherry picked from commit 6b6b648255)
2024-01-17 21:31:08 +01:00
Johannes Pfeifer 0ed937b833
Add display_parameter_values.m utility
(cherry picked from commit 28df34df06)
2024-01-17 14:38:21 +01:00
Johannes Pfeifer 2e237900aa
Tag Dynare figures and add utility for moving figures to uitabgroup
(cherry picked from commit 0187ebe0a2)
2024-01-17 14:38:11 +01:00
Johannes Pfeifer 695a55739c
compute_variance_decomposition.m: only print warning if absolute difference is meaningful
Prevents warnings if relative difference involves division by almost 0

(cherry picked from commit 6ff924550c)
2024-01-17 14:37:56 +01:00
Johannes Pfeifer df49b9f56c
occbin.DSGE_smoother.m: correct figure caption
(cherry picked from commit 248d8ae84f)
2024-01-15 12:18:13 +01:00
Johannes Pfeifer e3b60a1c1f
OccBin tools: rework codes
(cherry picked from commit 1b181fca57)
2024-01-15 11:39:51 +01:00
Johannes Pfeifer af0aa63d8c
🐛 model_info.m: fix display of lagged states
preprocessor increments lags/leads always only by lead_lag

(cherry picked from commit 45e8ab14dc)
2024-01-15 11:39:51 +01:00
Johannes Pfeifer 54268629bd
simulated_moment_uncertainty.m: remove evalin following removal of globals
transformed steady state is not passed back anymore

(cherry picked from commit 23225aca1b)
2024-01-15 11:39:51 +01:00
Sébastien Villemot 7f5c433382
Manual: update Normann’s affiliation
(cherry picked from commit 5d169d658e)

[skip ci]
2024-01-10 11:05:37 +01:00
Sébastien Villemot 9f1270b24d
Forbid alternative 1st order solvers with k_order_solver option
(cherry picked from commit cc02690acf)
2024-01-05 20:27:53 +01:00
Sébastien Villemot 8c8b9e0d67
Improve naming and description of various stack_solve_algo values
Also minor improvements to solve_algo description.

(cherry picked from commit ffb578276e)
2024-01-05 20:27:53 +01:00
Johannes Pfeifer f69a1483de
windows installer: add json-file
(cherry picked from commit 4a7851b069)
2024-01-05 20:27:53 +01:00
Johannes Pfeifer a94803ff29
send_endogenous_variables_to_workspace.m and friends: output column instead of row vectors
(cherry picked from commit 46d7e155d9)
2024-01-05 20:27:53 +01:00
Sébastien Villemot c19a4b14dd
Build system: don’t try to create TAGS file when not in a git working directory
(cherry picked from commit f9cd465fea)
2024-01-03 18:35:47 +01:00
Sébastien Villemot bb7648ad63
license.txt: fix various issues detected by lintian
(cherry picked from commit 53d8278d8a)
2024-01-03 18:35:46 +01:00
Sébastien Villemot 875437a221
Build system: install preprocessor symlink under libdir
(cherry picked from commit 049006a1bf)
2024-01-03 18:35:46 +01:00
Sébastien Villemot 0325d811b1
Build system: install .m files for MS-SBVAR
(cherry picked from commit e7cd6eb408)
2024-01-03 18:35:46 +01:00
Sébastien Villemot 093e9f348e
Build system: update list of ignored files under matlab/
(cherry picked from commit 0679da4cba)
2024-01-03 18:35:46 +01:00
Sébastien Villemot a910701699
Windows package: use our own mirror for the MSYS2 packages
Packages are removed from msys2.org after 21 months. Since the 6.x branch may
have a longer lifetime, it is safer to have our own mirror for the specific
packages that we need.
2024-01-03 10:44:43 +01:00
Sébastien Villemot d4e8d6d30d
Windows package: add missing rule for creating tarballs directory
[skip ci]

(cherry picked from commit a99beac083)
2024-01-03 10:25:02 +01:00
Johannes Pfeifer 4e125d6432
forecast_graphs.m: fix wrong naming
Also removes eval

(cherry picked from commit 02d1e8d3ed)
2024-01-03 10:14:23 +01:00
Johannes Pfeifer f53b6cc6fb
🐛 makedataset.m: correct error message with first_obs specified
(cherry picked from commit 8f07f37138)
2024-01-03 10:14:23 +01:00
Sébastien Villemot 6cae83f2f7
Update copyright years
(cherry picked from commit 8a7440c6ac)
2024-01-03 10:14:23 +01:00
Stéphane Adjemian (Guts) eb2c7cf101
Remove reference to dsmh in reference manual.
[skip ci]
2023-12-22 13:25:46 +01:00
Stéphane Adjemian (Guts) 9fd0dacf8a
Drop Dynamic Striated Metropolis-Hastings.
Will be part of dynare 7.x.
2023-12-22 13:18:29 +01:00
Sébastien Villemot f392c78644
Drop unused riccati_update MEX 2023-12-22 10:22:52 +01:00
Willi Mutschler fbb89dc190
Fixes for CET tests on Octave
- the mode file was previously saved as '-v7.3', now it is '-v6'
- mode_compute=1 and additional_optimizer=1 do not work under Octave

(cherry picked from commit ee2545f84d)
2023-12-22 10:18:48 +01:00
Johannes Pfeifer 0eedd5b46f
graph_comparison_irfs.m: compatibility fix for Octave
(cherry picked from commit 9c28f5feaf)
2023-12-22 10:18:47 +01:00
Sébastien Villemot 5acd6d1207
CI: adapt jobs for stable branch 2023-12-21 16:21:55 +01:00
Sébastien Villemot 6723a147ca
Bump version number 2023-12-21 16:06:00 +01:00
49 changed files with 648 additions and 913 deletions

View File

@ -11,12 +11,10 @@ variables:
# - if VERSION was already set (when manually running a pipeline), use it # - if VERSION was already set (when manually running a pipeline), use it
# - if we are in the official Dynare repository: # - if we are in the official Dynare repository:
# + if on a tag: use the tag # + if on a tag: use the tag
# + if on master: use 7-unstable-$TIMESTAMP-$COMMIT
# + on another branch: use $BRANCH-$TIMESTAMP-$COMMIT # + on another branch: use $BRANCH-$TIMESTAMP-$COMMIT
# - if in a personal repository: use $USER-$TIMESTAMP-$COMMIT # - if in a personal repository: use $USER-$TIMESTAMP-$COMMIT
before_script: before_script:
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ -n $CI_COMMIT_TAG ]]; then export VERSION=$CI_COMMIT_TAG; fi' - 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ -n $CI_COMMIT_TAG ]]; then export VERSION=$CI_COMMIT_TAG; fi'
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ $CI_COMMIT_REF_NAME == master ]]; then export VERSION=7-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]]; then export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi' - 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]]; then export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
- 'if [[ -z $VERSION ]]; then export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi' - 'if [[ -z $VERSION ]]; then export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
@ -162,7 +160,6 @@ test_old_matlab:
paths: paths:
- build-old-matlab/meson-logs/testlog.txt - build-old-matlab/meson-logs/testlog.txt
when: always when: always
when: manual
test_octave: test_octave:
stage: test stage: test
@ -175,7 +172,6 @@ test_octave:
- build-octave/meson-logs/testlog.txt - build-octave/meson-logs/testlog.txt
when: always when: always
needs: [ "build_octave" ] needs: [ "build_octave" ]
when: manual
test_clang_format: test_clang_format:
stage: test stage: test
@ -191,7 +187,7 @@ test_clang_format:
sign_windows: sign_windows:
stage: sign stage: sign
rules: rules:
- if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_REF_NAME == "master"' - if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_TAG =~ /^6/'
when: on_success when: on_success
- when: never - when: never
tags: tags:
@ -205,10 +201,10 @@ sign_windows:
- windows/exe-signed/* - windows/exe-signed/*
expire_in: 3 days expire_in: 3 days
deploy_manual_unstable: deploy_manual_stable:
stage: deploy stage: deploy
rules: rules:
- if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_REF_NAME == "master"' - if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_TAG =~ /^6\.[0-9]+$/'
when: on_success when: on_success
- when: never - when: never
tags: tags:
@ -216,12 +212,13 @@ deploy_manual_unstable:
dependencies: dependencies:
- build_doc - build_doc
script: script:
- rsync --recursive --links --delete build-doc/dynare-manual.html/ /srv/www.dynare.org/manual-unstable/ - rsync --recursive --links --delete build-doc/dynare-manual.html/ /srv/www.dynare.org/manual/
- cp build-doc/dynare-manual.pdf /srv/www.dynare.org/manual.pdf
deploy_snapshot_unstable: deploy_release_stable:
stage: deploy stage: deploy
rules: rules:
- if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_REF_NAME == "master"' - if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_TAG =~ /^6\.[0-9]+$/'
when: on_success when: on_success
- when: never - when: never
tags: tags:
@ -233,11 +230,33 @@ deploy_snapshot_unstable:
- pkg_macOS_arm64 - pkg_macOS_arm64
- pkg_macOS_x86_64 - pkg_macOS_x86_64
script: script:
- cp build-src/meson-dist/*.tar.xz /srv/www.dynare.org/snapshot/source/ && ln -sf *.tar.xz /srv/www.dynare.org/snapshot/source/dynare-latest-src.tar.xz - cp build-src/meson-dist/*.tar.xz /srv/www.dynare.org/release/source/
- f=(windows/exe-signed/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows/dynare-latest-win.exe - cp windows/exe-signed/* /srv/www.dynare.org/release/windows/
- f=(windows/7z/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows-7z/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows-7z/dynare-latest-win.7z - cp windows/7z/* /srv/www.dynare.org/release/windows-7z/
- f=(windows/zip/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows-zip/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows-zip/dynare-latest-win.zip - cp windows/zip/* /srv/www.dynare.org/release/windows-zip/
- f=(macOS/pkg/*-arm64.pkg) && cp ${f[0]} /srv/www.dynare.org/snapshot/macos-arm64/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/macos-arm64/dynare-latest-macos-arm64.pkg - cp macOS/pkg/*-arm64.pkg /srv/www.dynare.org/release/macos-arm64/
- f=(macOS/pkg/*-x86_64.pkg) && cp ${f[0]} /srv/www.dynare.org/snapshot/macos-x86_64/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/macos-x86_64/dynare-latest-macos-x86_64.pkg - cp macOS/pkg/*-x86_64.pkg /srv/www.dynare.org/release/macos-x86_64/
- ~/update-snapshot-list.sh - ~/update-release-list.sh
- curl -X POST -F token="$WEBSITE_PIPELINE_TRIGGER_TOKEN" -F ref=master https://git.dynare.org/api/v4/projects/40/trigger/pipeline - curl -X POST -F token="$WEBSITE_PIPELINE_TRIGGER_TOKEN" -F ref=master https://git.dynare.org/api/v4/projects/40/trigger/pipeline
deploy_beta_stable:
stage: deploy
rules:
- if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_TAG =~ /^6(\.[0-9]+)?-(beta|rc)[0-9]+$/'
when: on_success
- when: never
tags:
- deploy
dependencies:
- pkg_source
- pkg_windows
- sign_windows
- pkg_macOS_arm64
- pkg_macOS_x86_64
script:
- cp build-src/meson-dist/*.tar.xz /srv/www.dynare.org/beta/source/
- cp windows/exe-signed/* /srv/www.dynare.org/beta/windows/
- cp windows/7z/* /srv/www.dynare.org/beta/windows-7z/
- cp windows/zip/* /srv/www.dynare.org/beta/windows-zip/
- cp macOS/pkg/*-arm64.pkg /srv/www.dynare.org/beta/macos-arm64/
- cp macOS/pkg/*-x86_64.pkg /srv/www.dynare.org/beta/macos-x86_64/

View File

@ -7493,11 +7493,6 @@ observed variables.
standard Random-Walk Metropolis-Hastings. Does not yet support standard Random-Walk Metropolis-Hastings. Does not yet support
``moments_varendo``, ``bayesian_irf``, and ``smoother``. ``moments_varendo``, ``bayesian_irf``, and ``smoother``.
``'dsmh'``
Instructs Dynare to use the Dynamic Striated Metropolis Hastings
sampler proposed by *Waggoner, Wu and Zha (2016)* instead of the
standard Random-Walk Metropolis-Hastings.
.. option:: posterior_sampler_options = (NAME, VALUE, ...) .. option:: posterior_sampler_options = (NAME, VALUE, ...)
@ -16020,7 +16015,7 @@ Misc commands
``pdflatex`` and automatically tries to load all required ``pdflatex`` and automatically tries to load all required
packages. Requires the following LaTeX packages: packages. Requires the following LaTeX packages:
``breqn``, ``psfrag``, ``graphicx``, ``epstopdf``, ``longtable``, ``breqn``, ``psfrag``, ``graphicx``, ``epstopdf``, ``longtable``,
``booktabs``, ``caption``, ``float,`` ``amsmath``, ``amsfonts``, ``amssymb``, ``booktabs``, ``caption``, ``float,`` ``amsmath``, ``amsfonts``,
and ``morefloats``. and ``morefloats``.

View File

@ -1,4 +1,4 @@
# Copyright © 2019-2024 Dynare Team # Copyright © 2019-2023 Dynare Team
# #
# This file is part of Dynare. # This file is part of Dynare.
# #
@ -53,7 +53,7 @@ clean-all: clean-lib clean-src clean-tar
# #
tarballs/slicot-$(SLICOT_VERSION).tar.gz: tarballs/slicot-$(SLICOT_VERSION).tar.gz:
mkdir -p tarballs mkdir -p tarballs
wget $(WGET_OPTIONS) -O $@ https://deb.debian.org/debian/pool/main/s/slicot/slicot_$(SLICOT_VERSION).orig.tar.xz wget $(WGET_OPTIONS) -O $@ https://deb.debian.org/debian/pool/main/s/slicot/slicot_$(SLICOT_VERSION).orig.tar.gz
$(DEPS_ARCH)/sources64/slicot-$(SLICOT_VERSION): tarballs/slicot-$(SLICOT_VERSION).tar.gz $(DEPS_ARCH)/sources64/slicot-$(SLICOT_VERSION): tarballs/slicot-$(SLICOT_VERSION).tar.gz
rm -rf $(DEPS_ARCH)/sources64/slicot-* rm -rf $(DEPS_ARCH)/sources64/slicot-*
@ -62,7 +62,7 @@ $(DEPS_ARCH)/sources64/slicot-$(SLICOT_VERSION): tarballs/slicot-$(SLICOT_VERSIO
touch $@ touch $@
$(DEPS_ARCH)/lib64/slicot/libslicot64_pic.a: $(DEPS_ARCH)/sources64/slicot-$(SLICOT_VERSION) $(DEPS_ARCH)/lib64/slicot/libslicot64_pic.a: $(DEPS_ARCH)/sources64/slicot-$(SLICOT_VERSION)
make -C $< -f makefile_Unix FORTRAN=$(BREWDIR)/bin/gfortran LOADER=$(BREWDIR)/bin/gfortran SLICOTLIB=../libslicot64_pic.a OPTS="-O3 -fdefault-integer-8" lib -j$(NTHREADS) make -C $< FORTRAN=$(BREWDIR)/bin/gfortran LOADER=$(BREWDIR)/bin/gfortran SLICOTLIB=../libslicot64_pic.a OPTS="-O3 -fdefault-integer-8" lib -j$(NTHREADS)
strip -S $</libslicot64_pic.a strip -S $</libslicot64_pic.a
mkdir -p $(dir $@) mkdir -p $(dir $@)
cp $</libslicot64_pic.a $@ cp $</libslicot64_pic.a $@

View File

@ -1,2 +1,2 @@
SLICOT_VERSION = 5.9~20240205.gita037f7e SLICOT_VERSION = 5.0+20101122
X13AS_VERSION = 1-1-b60 X13AS_VERSION = 1-1-b60

View File

@ -119,7 +119,7 @@ OutputDirectoryName = CheckPath('graphs',M_.dname);
dyn_graph=bvar.graph_init(sprintf('BVAR forecasts (nlags = %d)', nlags), ny, {'b-' 'g-' 'g-' 'r-' 'r-'}); dyn_graph=bvar.graph_init(sprintf('BVAR forecasts (nlags = %d)', nlags), ny, {'b-' 'g-' 'g-' 'r-' 'r-'});
for i = 1:ny for i = 1:ny
dyn_graph=plot_graph(dyn_graph,[ sims_no_shock_median(:, i) ... dyn_graph=dynare_graph(dyn_graph,[ sims_no_shock_median(:, i) ...
sims_no_shock_up_conf(:, i) sims_no_shock_down_conf(:, i) ... sims_no_shock_up_conf(:, i) sims_no_shock_down_conf(:, i) ...
sims_with_shocks_up_conf(:, i) sims_with_shocks_down_conf(:, i) ], ... sims_with_shocks_up_conf(:, i) sims_with_shocks_down_conf(:, i) ], ...
options_.varobs{i}); options_.varobs{i});
@ -183,31 +183,3 @@ for i = 1:length(options_.varobs)
oo_.bvar.forecast.rmse.(name) = rmse(i); oo_.bvar.forecast.rmse.(name) = rmse(i);
end end
end end
function dyn_graph=plot_graph(dyn_graph,y,tit,x)
% function plot_graph(dyn_graph, y,tit,x)
if nargin < 4
x = (1:size(y,1))';
end
nplot = dyn_graph.plot_nbr + 1;
if nplot > dyn_graph.max_nplot
figure('Name',dyn_graph.figure_name);
nplot = 1;
end
dyn_graph.plot_nbr = nplot;
subplot(dyn_graph.nr,dyn_graph.nc,nplot);
line_types = dyn_graph.line_types;
line_type = line_types{1};
for i=1:size(y,2)
if length(line_types) > 1
line_type = line_types{i};
end
plot(x,y(:,i),line_type);
hold on
end
title(tit);
hold off

View File

@ -272,8 +272,80 @@ elseif opt_gsa.morris==3
return return
elseif opt_gsa.morris==2 % ISKREV stuff elseif opt_gsa.morris==2 % ISKREV stuff
return return
else else % main effects analysis
error('gsa/map_identification: unsupported option morris=%u',opt_gsa.morris) if itrans==0
fsuffix = '';
elseif itrans==1
fsuffix = '_log';
else
fsuffix = '_rank';
end
imap=1:npT;
if isempty(lpmat0)
x0=lpmat(istable,:);
else
x0=[lpmat0(istable,:), lpmat(istable,:)];
end
nrun=length(istable);
nest=min(250,nrun);
if opt_gsa.load_ident_files==0
try
EET=load([OutputDirectoryName,'/SCREEN/',fname_,'_morris_IDE'],'SAcc','ir_cc','ic_cc');
catch
EET=[];
end
ccac = gsa.standardize_columns([mss cc ac]);
[pcc, dd] = eig(cov(ccac(istable,:)));
[latent, isort] = sort(-diag(dd));
latent = -latent;
figure, bar(latent)
title('Eigenvalues in PCA')
pcc=pcc(:,isort);
ccac = ccac*pcc;
npca = max(find(cumsum(latent)./length(latent)<0.99))+1;
siPCA = (EET.SAcc'*abs(pcc'))';
siPCA = siPCA./(max(siPCA,[],2)*ones(1,npT));
SAcc=zeros(size(ccac,2),npT);
gsa_=NaN(npca);
for j=1:npca %size(ccac,2),
if itrans==0
y0 = ccac(istable,j);
elseif itrans==1
y0 = gsa.log_transform(ccac(istable,j));
else
y0 = trank(ccac(istable,j));
end
if ~isempty(EET)
imap=find(siPCA(j,:) >= (0.1.*max(siPCA(j,:))) );
end
gsa_(j) = gsa_sdp(y0(1:nest), x0(1:nest,imap), ...
2, [],[],[],0,[OutputDirectoryName,'/map_cc',fsuffix,int2str(j)], pnames);
SAcc(j,imap)=gsa_(j).si;
imap_cc{j}=imap;
end
save([OutputDirectoryName,'/map_cc',fsuffix,'.mat'],'gsa_')
save([OutputDirectoryName,'/',fname_,'_main_eff.mat'],'imap_cc','SAcc','ccac','-append')
else
load([OutputDirectoryName,'/',fname_,'_main_eff'],'SAcc')
end
hh_fig=dyn_figure(options_.nodisplay,'Name',['Identifiability indices in the ',fsuffix,' moments.']);
bar(sum(SAcc))
set(gca,'xticklabel',' ','fontsize',10,'xtick',1:npT)
set(gca,'xlim',[0.5 npT+0.5])
ydum = get(gca,'ylim');
set(gca,'ylim',[0 ydum(2)])
set(gca,'position',[0.13 0.2 0.775 0.7])
for ip=1:npT
text(ip,-0.02*(ydum(2)),bayestopt_.name{ip},'rotation',90,'HorizontalAlignment','right','interpreter','none')
end
xlabel(' ')
title(['Identifiability indices in the ',fsuffix,' moments.'],'interpreter','none')
dyn_saveas(hh_fig,[OutputDirectoryName,'/',fname_,'_ident_ALL',fsuffix],options_.nodisplay,options_.graph_format);
create_TeX_loader(options_,[OutputDirectoryName,'/',fname_,'_ident_ALL',fsuffix],1,['Identifiability indices in the ',fsuffix,' moments.'],['ident_ALL',fsuffix]',1)
end end
function []=create_TeX_loader(options_,figpath,ifig_number,caption,label_name,scale_factor) function []=create_TeX_loader(options_,figpath,ifig_number,caption,label_name,scale_factor)

View File

@ -93,8 +93,7 @@ function DERIVS = get_perturbation_params_derivs(M_, options_, estim_params_, dr
% This function calls % This function calls
% * [fname,'.dynamic'] % * [fname,'.dynamic']
% * [fname,'.dynamic_params_derivs'] % * [fname,'.dynamic_params_derivs']
% * [fname,'.sparse.static_g1'] % * [fname,'.static']
% * [fname,'.sparse.static_g2']
% * [fname,'.static_params_derivs'] % * [fname,'.static_params_derivs']
% * commutation % * commutation
% * dyn_vech % * dyn_vech
@ -110,7 +109,7 @@ function DERIVS = get_perturbation_params_derivs(M_, options_, estim_params_, dr
% * sylvester3a % * sylvester3a
% * get_perturbation_params_derivs_numerical_objective % * get_perturbation_params_derivs_numerical_objective
% ========================================================================= % =========================================================================
% Copyright © 2019-2024 Dynare Team % Copyright © 2019-2020 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -455,13 +454,12 @@ elseif (analytic_derivation_mode == 0 || analytic_derivation_mode == 1)
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) 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 end
%% Analytical computation of Jacobian and Hessian (wrt selected model parameters) of steady state, i.e. dYss and d2Yss %% Analytical computation of Jacobian and Hessian (wrt selected model parameters) of steady state, i.e. dYss and d2Yss
[g1_static, T_order_static, T_static] = feval([fname,'.sparse.static_g1'], ys, exo_steady_state', params, M_.static_g1_sparse_rowval, M_.static_g1_sparse_colval, M_.static_g1_sparse_colptr); %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 [~, 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
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 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
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 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 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 if d2flag
g2_static_v = feval([fname,'.sparse.static_g2'], ys, exo_steady_state', params, T_order_static, T_static); [~, ~, 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
g2_static = build_two_dim_hessian(M_.static_g2_sparse_indices, g2_static_v, endo_nbr, endo_nbr); %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 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 [~, g1, g2, g3] = feval([fname,'.dynamic'], ys(I), exo_steady_state', params, ys, 1); %note that g3 does not contain symmetric elements
g3 = identification.unfold_g3(g3, yy0ex0_nbr); %add symmetric elements to g3 g3 = identification.unfold_g3(g3, yy0ex0_nbr); %add symmetric elements to g3
@ -507,7 +505,7 @@ elseif (analytic_derivation_mode == 0 || analytic_derivation_mode == 1)
end end
%handling of steady state for nonstationary variables %handling of steady state for nonstationary variables
if any(any(isnan(dys))) if any(any(isnan(dys)))
[U,T] = schur(full(g1_static)); [U,T] = schur(g1_static);
e1 = abs(ordeig(T)) < qz_criterium-1; e1 = abs(ordeig(T)) < qz_criterium-1;
k = sum(e1); % Number of non stationary variables. k = sum(e1); % Number of non stationary variables.
% Number of stationary variables: n = length(e1)-k % Number of stationary variables: n = length(e1)-k

View File

@ -736,7 +736,7 @@ if iload <=0
end end
run_index = 0; % reset index run_index = 0; % reset index
end end
if SampleSize > 1 && mod(iteration,3) if SampleSize > 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 end

View File

@ -15,7 +15,7 @@ function simulation = simul_static_model(samplesize, innovations)
% [2] The last input argument is not mandatory. If absent we use random draws and rescale them with the informations provided % [2] The last input argument is not mandatory. If absent we use random draws and rescale them with the informations provided
% through the shocks block. % through the shocks block.
% Copyright © 2019-2024 Dynare Team % Copyright © 2019-2022 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -83,17 +83,12 @@ else
oo_.exo_simul = Innovations; oo_.exo_simul = Innovations;
end end
static_resid = str2func(sprintf('%s.sparse.static_resid', M_.fname)); staticmodel = str2func(sprintf('%s.static', M_.fname));
static_g1 = str2func(sprintf('%s.sparse.static_g1', M_.fname));
function [resid, g1] = staticmodel(y, x, params)
[resid, T_order, T] = static_resid(y, x, params);
g1 = static_g1(y, x, params, M_.static_g1_sparse_rowval, M_.static_g1_sparse_colval, M_.static_g1_sparse_colptr, T_order, T);
end
% Simulations (call a Newton-like algorithm for each period). % Simulations (call a Newton-like algorithm for each period).
for t=1:samplesize for t=1:samplesize
y = zeros(M_.endo_nbr, 1); y = zeros(M_.endo_nbr, 1);
[oo_.endo_simul(:,t), errorflag, ~, ~, errorcode] = dynare_solve(@staticmodel, y, options_.simul.maxit, options_.dynatol.f, options_.dynatol.x, options_, oo_.exo_simul(t,:), M_.params); [oo_.endo_simul(:,t), errorflag, ~, ~, errorcode] = dynare_solve(staticmodel, y, options_.simul.maxit, options_.dynatol.f, options_.dynatol.x, options_, oo_.exo_simul(t,:), M_.params);
if errorflag if errorflag
dprintf('simul_static_mode: Nonlinear solver failed with errorcode=%i in period %i.', errorcode, t) dprintf('simul_static_mode: Nonlinear solver failed with errorcode=%i in period %i.', errorcode, t)
oo_.endo_simul(:,t) = nan; oo_.endo_simul(:,t) = nan;
@ -108,6 +103,4 @@ if isdseries(innovations)
initperiod = innovations.dates(1); initperiod = innovations.dates(1);
end end
simulation = [dseries(ysim', initperiod, M_.endo_names(1:M_.orig_endo_nbr)), dseries(xsim, initperiod, M_.exo_names)]; simulation = [dseries(ysim', initperiod, M_.endo_names(1:M_.orig_endo_nbr)), dseries(xsim, initperiod, M_.exo_names)];
end

View File

@ -1,58 +0,0 @@
function H = build_two_dim_hessian(sparse_indices, g2_v, neq, nvar)
% Creates a 2D Hessian (equations in rows, pairs of variables in columns),
% given the output from the sparse {static,dynamic}_g2.m
%
% sparse_indices is typically equal to M_.{static,dynamic}_g2_sparse_indices
% g2_v is the vector of non zero values returned by {static,dynamic}_g2.m
% neq is the number of equations (equal to number of rows of the output matrix)
% nvar is the number of variables (the output matrix will have nvar² columns)
% Copyright © 2024 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
nnz = size(sparse_indices, 1);
%% The g2_* arrays may be expanded if there are symmetric elements added
g2_i = int32(zeros(nnz, 1));
g2_j = int32(zeros(nnz, 1));
next_sym_idx = nnz + 1; % Index of next symmetric element to be added
for k = 1:length(g2_v)
eq = sparse_indices(k, 1);
var1 = sparse_indices(k, 2)-1;
var2 = sparse_indices(k, 3)-1;
g2_i(k) = eq;
g2_j(k) = var1 * nvar + var2 + 1;
%% Add symmetric elements, which are not included by sparse {static,dynamic}_g2.m
if var1 ~= var2
g2_i(next_sym_idx) = eq;
g2_j(next_sym_idx) = var2 * nvar + var1 + 1;
g2_v(next_sym_idx) = g2_v(k);
next_sym_idx = next_sym_idx + 1;
end
end
%% On MATLAB < R2020a, sparse() does not accept int32 indices
if ~isoctave && matlab_ver_less_than('9.8')
g2_i = double(g2_i);
g2_j = double(g2_j);
end
H = sparse(g2_i, g2_j, g2_v, neq, nvar*nvar);

View File

@ -13,7 +13,7 @@ function [dr, info, params]=discretionary_policy_1(M_, options_, dr, endo_steady
% - info [integer] scalar or vector, error code. % - info [integer] scalar or vector, error code.
% - params [double] vector of potentially updated parameters % - params [double] vector of potentially updated parameters
% Copyright © 2007-2024 Dynare Team % Copyright © 2007-2020 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -49,9 +49,7 @@ else
end end
params=M_.params; params=M_.params;
y = zeros(M_.endo_nbr,1); [~,Uy,W] = feval([M_.fname,'.objective.static'],zeros(M_.endo_nbr,1),[], M_.params);
[Uy, T_order, T] = feval([M_.fname,'.objective.sparse.static_g1'], y, [], params, M_.objective_g1_sparse_rowval, M_.objective_g1_sparse_colval, M_.objective_g1_sparse_colptr);
if any(any(isnan(Uy))) if any(any(isnan(Uy)))
info = 64 ; %the derivatives of the objective function contain NaN info = 64 ; %the derivatives of the objective function contain NaN
return; return;
@ -72,8 +70,6 @@ if any(any(Uy~=0))
return; return;
end end
g2_v = feval([M_.fname,'.objective.sparse.static_g2'], y, [], params, T_order, T);
W = build_two_dim_hessian(M_.objective_g2_sparse_indices, g2_v, 1, M_.endo_nbr);
W=reshape(W,M_.endo_nbr,M_.endo_nbr); W=reshape(W,M_.endo_nbr,M_.endo_nbr);
klen = M_.maximum_lag + M_.maximum_lead + 1; klen = M_.maximum_lag + M_.maximum_lead + 1;
@ -126,4 +122,4 @@ dr.ghu=G(dr.order_var,:);
if M_.maximum_endo_lag if M_.maximum_endo_lag
Selection=M_.lead_lag_incidence(1,dr.order_var)>0;%select state variables Selection=M_.lead_lag_incidence(1,dr.order_var)>0;%select state variables
end end
dr.ghx=T(:,Selection); dr.ghx=T(:,Selection);

View File

@ -122,7 +122,7 @@ if isempty(dot_location)
fnamelength = length(fname); fnamelength = length(fname);
fname1 = [fname '.dyn']; fname1 = [fname '.dyn'];
d = dir(fname1); d = dir(fname1);
if isempty(d) if length(d) == 0
fname1 = [fname '.mod']; fname1 = [fname '.mod'];
end end
fname = fname1; fname = fname1;
@ -138,7 +138,7 @@ if fnamelength + length('.set_auxiliary_variables') > namelengthmax()
error('Dynare: the name of your .mod file is too long, please shorten it') error('Dynare: the name of your .mod file is too long, please shorten it')
end end
if contains(fname,filesep) if ~isempty(strfind(fname,filesep))
fprintf('\nIt seems you are trying to call a .mod file not located in the "Current Folder". This is not possible (the %s symbol is not allowed in the name of the .mod file).\n', filesep) fprintf('\nIt seems you are trying to call a .mod file not located in the "Current Folder". This is not possible (the %s symbol is not allowed in the name of the .mod file).\n', filesep)
[pathtomodfile,basename] = fileparts(fname); [pathtomodfile,basename] = fileparts(fname);
if exist(pathtomodfile,'dir') if exist(pathtomodfile,'dir')
@ -297,13 +297,17 @@ if status
error('Dynare: preprocessing failed') error('Dynare: preprocessing failed')
end end
if ~ isempty(find(abs(fname) == 46))
fname = fname(:,1:find(abs(fname) == 46)-1) ;
end
% We need to clear the driver (and only the driver, because the "clear all" % We need to clear the driver (and only the driver, because the "clear all"
% within the driver will clean the rest) % within the driver will clean the rest)
clear(['+' fname(1:end-4) '/driver']) clear(['+' fname '/driver'])
try try
cTic = tic; cTic = tic;
evalin('base',[fname(1:end-4) '.driver']); evalin('base',[fname '.driver']);
cToc = toc(cTic); cToc = toc(cTic);
if nargout if nargout
DynareInfo.time.compute = cToc; DynareInfo.time.compute = cToc;
@ -311,7 +315,7 @@ try
catch ME catch ME
W = evalin('caller','whos'); W = evalin('caller','whos');
diary off diary off
if ismember(fname(1:end-4),{W(:).name}) if ismember(fname,{W(:).name})
error('Your workspace already contains a variable with the same name as the mod-file. You need to delete it or rename the mod-file.') error('Your workspace already contains a variable with the same name as the mod-file. You need to delete it or rename the mod-file.')
else else
rethrow(ME) rethrow(ME)

54
matlab/dynare_graph.m Normal file
View File

@ -0,0 +1,54 @@
function dyn_graph=dynare_graph(dyn_graph,y,tit,x)
% function dynare_graph(y,tit,x)
% graphs
%
% INPUT
% figure_name: name of the figures
% colors: line colors
%
% OUTPUT
% dyn_graph: structure with figure information
%
% SPECIAL REQUIREMENT
% none
% Copyright © 2006-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 <https://www.gnu.org/licenses/>.
if nargin < 4
x = (1:size(y,1))';
end
nplot = dyn_graph.plot_nbr + 1;
if nplot > dyn_graph.max_nplot
figure('Name',dyn_graph.figure_name);
nplot = 1;
end
dyn_graph.plot_nbr = nplot;
subplot(dyn_graph.nr,dyn_graph.nc,nplot);
line_types = dyn_graph.line_types;
line_type = line_types{1};
for i=1:size(y,2)
if length(line_types) > 1
line_type = line_types{i};
end
plot(x,y(:,i),line_type);
hold on
end
title(tit);
hold off

View File

@ -0,0 +1,29 @@
function dynare_graph_close()
% function dynare_graph_close()
% close a figure
%
% INPUT
% none
%
% OUTPUT
% none
%
% SPECIAL REQUIREMENT
% none
% Copyright © 2006-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 <https://www.gnu.org/licenses/>.

View File

@ -63,7 +63,7 @@ end
value_format = sprintf('%%%d.%df', val_width, val_precis); value_format = sprintf('%%%d.%df', val_width, val_precis);
header_string_format = sprintf('%%%ds', val_width); header_string_format = sprintf('%%%ds', val_width);
if ~isempty(title) if length(title) > 0
fprintf('\n\n%s\n',title); fprintf('\n\n%s\n',title);
end end
@ -72,7 +72,7 @@ if nargin==9
disp(optional_header) disp(optional_header)
end end
if ~isempty(headers) if length(headers) > 0
hh_tbl = sprintf(label_format_leftbound , headers{1}); hh_tbl = sprintf(label_format_leftbound , headers{1});
for i=2:length(headers) for i=2:length(headers)
hh_tbl = [hh_tbl sprintf(header_string_format, headers{i})]; hh_tbl = [hh_tbl sprintf(header_string_format, headers{i})];

View File

@ -1,6 +1,6 @@
function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,M_,options_,bayestopt_,dr] = dsge_likelihood(xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,BoundsInfo,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,derivatives_info) function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,M_,options_,bayestopt_,dr] = dsge_likelihood(xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,BoundsInfo,dr, endo_steady_state, exo_steady_state, exo_det_steady_state,derivatives_info)
% [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,M_,options_,bayestopt_,oo_] = dsge_likelihood(xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,BoundsInfo,oo_,derivatives_info) % [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,M_,options_,bayestopt_,oo_] = dsge_likelihood(xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,BoundsInfo,oo_,derivatives_info)
% Evaluates the negative of the posterior kernel of a DSGE model using the specified % Evaluates the posterior kernel of a DSGE model using the specified
% kalman_algo; the resulting posterior includes the 2*pi constant of the % kalman_algo; the resulting posterior includes the 2*pi constant of the
% likelihood function % likelihood function
% %
@ -21,7 +21,7 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,M_,options_,baye
% - derivatives_info [structure] derivative info for identification % - derivatives_info [structure] derivative info for identification
% %
% OUTPUTS % OUTPUTS
% - fval [double] scalar, value of minus the likelihood or posterior kernel. % - 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. % - 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). % - exit_flag [integer] scalar, equal to 1 (no issues when evaluating the likelihood) or 0 (not able to evaluate the likelihood).
% - DLIK [double] Vector with score of the likelihood % - DLIK [double] Vector with score of the likelihood
@ -37,7 +37,7 @@ function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,M_,options_,baye
% This function calls: dynare_resolve, lyapunov_symm, lyapunov_solver, compute_Pinf_Pstar, kalman_filter_d, missing_observations_kalman_filter_d, % This function calls: dynare_resolve, lyapunov_symm, lyapunov_solver, compute_Pinf_Pstar, kalman_filter_d, missing_observations_kalman_filter_d,
% univariate_kalman_filter_d, kalman_steady_state, get_perturbation_params_deriv, kalman_filter, missing_observations_kalman_filter, univariate_kalman_filter, priordens % univariate_kalman_filter_d, kalman_steady_state, get_perturbation_params_deriv, kalman_filter, missing_observations_kalman_filter, univariate_kalman_filter, priordens
% Copyright © 2004-2024 Dynare Team % Copyright © 2004-2023 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %

View File

@ -1,299 +0,0 @@
function dsmh(TargetFun, xparam1, mh_bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_)
% Dynamic Striated Metropolis-Hastings algorithm.
%
% INPUTS
% o TargetFun [char] string specifying the name of the objective
% function (posterior kernel).
% o xparam1 [double] (p*1) vector of parameters to be estimated (initial values).
% o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters.
% o dataset_ data structure
% o dataset_info dataset info structure
% o options_ options structure
% o M_ model structure
% o estim_params_ estimated parameters structure
% o bayestopt_ estimation options structure
% o oo_ outputs structure
%
% SPECIAL REQUIREMENTS
% None.
%
% PARALLEL CONTEXT
% The most computationally intensive part of this function may be executed
% in parallel. The code suitable to be executed in
% parallel on multi core or cluster machine (in general a 'for' cycle)
% has been removed from this function and been placed in the posterior_sampler_core.m funtion.
%
% The DYNARE parallel packages comprise a i) set of pairs of Matlab functions that can be executed in
% parallel and called name_function.m and name_function_core.m and ii) a second set of functions used
% to manage the parallel computations.
%
% This function was the first function to be parallelized. Later, other
% functions have been parallelized using the same methodology.
% Then the comments write here can be used for all the other pairs of
% parallel functions and also for management functions.
% Copyright © 2022-2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
opts = options_.posterior_sampler_options.dsmh;
lambda = exp(bsxfun(@minus,options_.posterior_sampler_options.dsmh.H,1:1:options_.posterior_sampler_options.dsmh.H)/(options_.posterior_sampler_options.dsmh.H-1)*log(options_.posterior_sampler_options.dsmh.lambda1));
c = 0.055 ;
MM = int64(options_.posterior_sampler_options.dsmh.N*options_.posterior_sampler_options.dsmh.G/10) ;
% Step 0: Initialization of the sampler
[param, tlogpost_iminus1, loglik, bayestopt_] = ...
smc_samplers_initialization(TargetFun, 'dsmh', opts.particles, mh_bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_);
ESS = zeros(options_.posterior_sampler_options.dsmh.H,1) ;
zhat = 1 ;
% The DSMH starts here
for i=2:options_.posterior_sampler_options.dsmh.H
disp('');
disp('Tempered iteration');
disp(i) ;
% Step 1: sort the densities and compute IS weigths
[tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) ;
[tlogpost_i,weights,zhat,ESS,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) ;
% Step 2: tune c_i
c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_);
% Step 3: Metropolis step
[param,tlogpost_iminus1,loglik] = mutation_DSMH(TargetFun,param,tlogpost_i,tlogpost_iminus1,loglik,lambda,i,c,MM,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_);
end
weights = exp(loglik*(lambda(end)-lambda(end-1)));
weights = weights/sum(weights);
indx_resmpl = smc_resampling(weights,rand(1,1),options_.posterior_sampler_options.dsmh.particles);
distrib_param = param(:,indx_resmpl);
mean_xparam = mean(distrib_param,2);
npar = length(xparam1);
lb95_xparam = zeros(npar,1) ;
ub95_xparam = zeros(npar,1) ;
for i=1:npar
temp = sortrows(distrib_param(i,:)') ;
lb95_xparam(i) = temp(0.025*options_.posterior_sampler_options.dsmh.particles) ;
ub95_xparam(i) = temp(0.975*options_.posterior_sampler_options.dsmh.particles) ;
end
TeX = options_.TeX;
str = sprintf(' Param. \t Lower Bound (95%%) \t Mean \t Upper Bound (95%%)');
for l=1:npar
name = get_the_name(l,TeX,M_,estim_params_,options_.varobs);
str = sprintf('%s\n %s \t\t %5.4f \t\t %7.5f \t\t %5.4f', str, name, lb95_xparam(l), mean_xparam(l), ub95_xparam(l));
end
disp(str)
disp('')
%% Plot parameters densities
if TeX
fidTeX = fopen([M_.fname '_param_density.tex'],'w');
fprintf(fidTeX,'%% TeX eps-loader file generated by DSMH.m (Dynare).\n');
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
fprintf(fidTeX,' \n');
end
number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two.
bandwidth = 0; % Rule of thumb optimal bandwidth parameter.
kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation.
plt = 1 ;
%for plt = 1:nbplt,
if TeX
NAMES = [];
TeXNAMES = [];
end
hh_fig = dyn_figure(options_.nodisplay,'Name','Parameters Densities');
for k=1:npar %min(nstar,npar-(plt-1)*nstar)
subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k)
%kk = (plt-1)*nstar+k;
[name,texname] = get_the_name(k,TeX,M_,estim_params_,options_.varobs);
optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.posterior_sampler_options.dsmh.particles,bandwidth,kernel_function);
[density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,...
options_.posterior_sampler_options.dsmh.particles,optimal_bandwidth,kernel_function);
plot(density(:,1),density(:,2));
hold on
if TeX
title(texname,'interpreter','latex')
else
title(name,'interpreter','none')
end
hold off
axis tight
drawnow
end
dyn_saveas(hh_fig,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format);
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
% TeX eps loader file
fprintf(fidTeX,'\\begin{figure}[H]\n');
fprintf(fidTeX,'\\centering \n');
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt));
fprintf(fidTeX,'\\caption{Parameter densities based on the Dynamic Striated Metropolis-Hastings algorithm.}');
fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt));
fprintf(fidTeX,'\\end{figure}\n');
fprintf(fidTeX,' \n');
end
%end
function [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param)
[~,indx_ord] = sortrows(tlogpost_iminus1);
tlogpost_iminus1 = tlogpost_iminus1(indx_ord);
param = param(:,indx_ord);
loglik = loglik(indx_ord);
function [tlogpost_i,weights,zhat,ESS,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS)
if i==1
tlogpost_i = tlogpost_iminus1 + loglik*lambda(i);
else
tlogpost_i = tlogpost_iminus1 + loglik*(lambda(i)-lambda(i-1));
end
weights = exp(tlogpost_i-tlogpost_iminus1);
zhat = (mean(weights))*zhat ;
weights = weights/sum(weights);
ESS(i) = 1/sum(weights.^2);
% estimates of mean and variance
mu = param*weights;
z = bsxfun(@minus,param,mu);
Omega = z*diag(weights)*z';
Omegachol = chol(Omega)';
function c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_)
disp('tuning c_i...');
disp('Initial value =');
disp(c) ;
npar = size(param,1);
lower_prob = (.5*(options_.posterior_sampler_options.dsmh.alpha0+options_.posterior_sampler_options.dsmh.alpha1))^5;
upper_prob = (.5*(options_.posterior_sampler_options.dsmh.alpha0+options_.posterior_sampler_options.dsmh.alpha1))^(1/5);
stop=0 ;
while stop==0
acpt = 0.0;
indx_resmpl = smc_resampling(weights,rand(1,1),options_.posterior_sampler_options.dsmh.G);
param0 = param(:,indx_resmpl);
tlogpost0 = tlogpost_i(indx_resmpl);
for j=1:options_.posterior_sampler_options.dsmh.G
for l=1:options_.posterior_sampler_options.dsmh.K
validate = 0;
while validate == 0
candidate = param0(:,j) + sqrt(c)*Omegachol*randn(npar,1);
if all(candidate >= mh_bounds.lb) && all(candidate <= mh_bounds.ub)
[tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_);
if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value)
validate = 1;
if rand(1,1)<exp(tlogpostx-tlogpost0(j)) % accept
acpt = acpt + 1/(options_.posterior_sampler_options.dsmh.G*options_.posterior_sampler_options.dsmh.K);
param0(:,j)= candidate;
tlogpost0(j) = tlogpostx;
end
end
end
end
end
end
disp('Acceptation rate =') ;
disp(acpt) ;
if options_.posterior_sampler_options.dsmh.alpha0<=acpt && acpt<=options_.posterior_sampler_options.dsmh.alpha1
disp('done!');
stop=1;
else
if acpt<lower_prob
c = c/5;
elseif lower_prob<=acpt && acpt<=upper_prob
c = c*log(.5*(options_.posterior_sampler_options.dsmh.alpha0+options_.posterior_sampler_options.dsmh.alpha1))/log(acpt);
else
c = 5*c;
end
disp('Trying with c= ') ;
disp(c)
end
end
function [out_param,out_tlogpost_iminus1,out_loglik] = mutation_DSMH(TargetFun,param,tlogpost_i,tlogpost_iminus1,loglik,lambda,i,c,MM,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_)
indx_levels = (1:1:MM-1)*options_.posterior_sampler_options.dsmh.N*options_.posterior_sampler_options.dsmh.G/MM;
npar = size(param,1) ;
p = 1/(10*options_.posterior_sampler_options.dsmh.tau);
disp('Metropolis step...');
% build the dynamic grid of levels
levels = [0.0;tlogpost_iminus1(indx_levels)];
% initialize the outputs
out_param = param;
out_tlogpost_iminus1 = tlogpost_i;
out_loglik = loglik;
% resample and initialize the starting groups
indx_resmpl = smc_resampling(weights,rand(1,1),options_.posterior_sampler_options.dsmh.G);
param0 = param(:,indx_resmpl);
tlogpost_iminus10 = tlogpost_iminus1(indx_resmpl);
tlogpost_i0 = tlogpost_i(indx_resmpl);
loglik0 = loglik(indx_resmpl);
% Start the Metropolis
for l=1:options_.posterior_sampler_options.dsmh.N*options_.posterior_sampler_options.dsmh.tau
for j=1:options_.posterior_sampler_options.dsmh.G
u1 = rand(1,1);
u2 = rand(1,1);
if u1<p
k=1 ;
for m=1:MM-1
if levels(m)<=tlogpost_iminus10(j) && tlogpost_iminus10(j)<levels(m+1)
k = m+1;
break
end
end
indx = floor( (k-1)*options_.posterior_sampler_options.dsmh.N*options_.posterior_sampler_options.dsmh.G/MM+1 + u2*(options_.posterior_sampler_options.dsmh.N*options_.posterior_sampler_options.dsmh.G/MM-1) );
if i==1
alp = (loglik(indx)-loglik0(j))*lambda(i);
else
alp = (loglik(indx)-loglik0(j))*(lambda(i)-lambda(i-1));
end
if u2<exp(alp)
param0(:,j) = param(:,indx);
tlogpost_i0(j) = tlogpost_i(indx);
loglik0(j) = loglik(indx);
tlogpost_iminus10(j) = tlogpost_iminus1(indx);
end
else
validate= 0;
while validate==0
candidate = param0(:,j) + sqrt(c)*Omegachol*randn(npar,1);
if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub)
[tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_);
if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value)
validate = 1;
if u2<exp(tlogpostx-tlogpost_i0(j)) % accept
param0(:,j) = candidate;
tlogpost_i0(j) = tlogpostx;
loglik0(j) = loglikx;
if i==1
tlogpost_iminus10(j) = tlogpostx-loglikx*lambda(i);
else
tlogpost_iminus10(j) = tlogpostx-loglikx*(lambda(i)-lambda(i-1));
end
end
end
end
end
end
end
if mod(l,options_.posterior_sampler_options.dsmh.tau)==0
rang = (l/options_.posterior_sampler_options.dsmh.tau-1)*options_.posterior_sampler_options.dsmh.G+1:l*options_.posterior_sampler_options.dsmh.G/options_.posterior_sampler_options.dsmh.tau;
out_param(:,rang) = param0;
out_tlogpost_iminus1(rang) = tlogpost_i0;
out_loglik(rang) = loglik0;
end
end

View File

@ -35,7 +35,7 @@ fprintf(fid,'%s \n','\usepackage{psfrag}');
fprintf(fid,'%s \n','\usepackage{graphicx}'); fprintf(fid,'%s \n','\usepackage{graphicx}');
fprintf(fid,'%s \n','\usepackage{epstopdf}'); fprintf(fid,'%s \n','\usepackage{epstopdf}');
fprintf(fid,'%s \n','\usepackage{longtable,booktabs}'); fprintf(fid,'%s \n','\usepackage{longtable,booktabs}');
fprintf(fid,'%s \n','\usepackage{amsmath,amsfonts,amssymb}'); fprintf(fid,'%s \n','\usepackage{amsmath,amsfonts}');
fprintf(fid,'%s \n','\usepackage{breqn}'); fprintf(fid,'%s \n','\usepackage{breqn}');
fprintf(fid,'%s \n','\usepackage{float,morefloats,caption}'); fprintf(fid,'%s \n','\usepackage{float,morefloats,caption}');
fprintf(fid,'%s \n','\begin{document}'); fprintf(fid,'%s \n','\begin{document}');

View File

@ -59,7 +59,7 @@ function planner_objective_value = evaluate_planner_objective(M_,options_,oo_)
% In the deterministic case, resorting to approximations for welfare is no longer required as it is possible to simulate the model given initial conditions for pre-determined variables and terminal conditions for forward-looking variables, whether these initial and terminal conditions are explicitly or implicitly specified. Assuming that the number of simulated periods is high enough for the new steady-state to be reached, the new unconditional welfare is thus the last period's welfare. As for the conditional welfare, it can be derived using backward recursions on the equation W = U + beta*W(+1) starting from the final unconditional steady-state welfare. % In the deterministic case, resorting to approximations for welfare is no longer required as it is possible to simulate the model given initial conditions for pre-determined variables and terminal conditions for forward-looking variables, whether these initial and terminal conditions are explicitly or implicitly specified. Assuming that the number of simulated periods is high enough for the new steady-state to be reached, the new unconditional welfare is thus the last period's welfare. As for the conditional welfare, it can be derived using backward recursions on the equation W = U + beta*W(+1) starting from the final unconditional steady-state welfare.
% Copyright © 2007-2024 Dynare Team % Copyright © 2007-2022 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -92,11 +92,11 @@ end
if options_.ramsey_policy && oo_.gui.ran_perfect_foresight if options_.ramsey_policy && oo_.gui.ran_perfect_foresight
T = size(oo_.endo_simul,2); T = size(oo_.endo_simul,2);
U_term = feval([M_.fname '.objective.sparse.static_resid'], oo_.endo_simul(:,T-M_.maximum_lead), oo_.exo_simul(T-M_.maximum_lead,:), M_.params); [U_term] = feval([M_.fname '.objective.static'],oo_.endo_simul(:,T-M_.maximum_lead),oo_.exo_simul(T-M_.maximum_lead,:), M_.params);
EW = U_term/(1-beta); EW = U_term/(1-beta);
W = EW; W = EW;
for t=T-M_.maximum_lead:-1:1+M_.maximum_lag for t=T-M_.maximum_lead:-1:1+M_.maximum_lag
U = feval([M_.fname '.objective.sparse.static_resid'], oo_.endo_simul(:,t), oo_.exo_simul(t,:), M_.params); [U] = feval([M_.fname '.objective.static'],oo_.endo_simul(:,t),oo_.exo_simul(t,:), M_.params);
W = U + beta*W; W = U + beta*W;
end end
planner_objective_value = struct('conditional', W, 'unconditional', EW); planner_objective_value = struct('conditional', W, 'unconditional', EW);
@ -108,8 +108,7 @@ else
ys = oo_.dr.ys; ys = oo_.dr.ys;
end end
if options_.order == 1 && ~options_.discretionary_policy if options_.order == 1 && ~options_.discretionary_policy
[U, T_order, T] = feval([M_.fname '.objective.sparse.static_resid'], ys, zeros(1,exo_nbr), M_.params); [U,Uy] = feval([M_.fname '.objective.static'],ys,zeros(1,exo_nbr), M_.params);
Uy = feval([M_.fname '.objective.sparse.static_g1'], ys, zeros(1,exo_nbr), M_.params, M_.objective_g1_sparse_rowval, M_.objective_g1_sparse_colval, M_.objective_g1_sparse_colptr, T_order, T);
Gy = dr.ghx(nstatic+(1:nspred),:); Gy = dr.ghx(nstatic+(1:nspred),:);
Gu = dr.ghu(nstatic+(1:nspred),:); Gu = dr.ghu(nstatic+(1:nspred),:);
@ -138,9 +137,7 @@ else
planner_objective_value.conditional.zero_initial_multiplier = W_L_0; planner_objective_value.conditional.zero_initial_multiplier = W_L_0;
elseif options_.order == 2 && ~M_.hessian_eq_zero %full second order approximation elseif options_.order == 2 && ~M_.hessian_eq_zero %full second order approximation
[U, T_order, T] = feval([M_.fname '.objective.sparse.static_resid'], ys, zeros(1,exo_nbr), M_.params); [U,Uy,Uyy] = feval([M_.fname '.objective.static'],ys,zeros(1,exo_nbr), M_.params);
[Uy, T_order, T] = feval([M_.fname '.objective.sparse.static_g1'], ys, zeros(1,exo_nbr), M_.params, M_.objective_g1_sparse_rowval, M_.objective_g1_sparse_colval, M_.objective_g1_sparse_colptr, T_order, T);
Uyy_v = feval([M_.fname '.objective.sparse.static_g2'], ys, zeros(1,exo_nbr), M_.params, T_order, T);
Gy = dr.ghx(nstatic+(1:nspred),:); Gy = dr.ghx(nstatic+(1:nspred),:);
Gu = dr.ghu(nstatic+(1:nspred),:); Gu = dr.ghu(nstatic+(1:nspred),:);
@ -156,7 +153,6 @@ else
guu(dr.order_var,:) = dr.ghuu; guu(dr.order_var,:) = dr.ghuu;
gss(dr.order_var,:) = dr.ghs2; gss(dr.order_var,:) = dr.ghs2;
Uyy = build_two_dim_hessian(M_.objective_g2_sparse_indices, Uyy_v, 1, M_.endo_nbr);
Uyy = full(Uyy); Uyy = full(Uyy);
Uyygygy = A_times_B_kronecker_C(Uyy,gy,gy); Uyygygy = A_times_B_kronecker_C(Uyy,gy,gy);
@ -232,16 +228,13 @@ else
planner_objective_value.conditional.steady_initial_multiplier = W_L_SS; planner_objective_value.conditional.steady_initial_multiplier = W_L_SS;
planner_objective_value.conditional.zero_initial_multiplier = W_L_0; planner_objective_value.conditional.zero_initial_multiplier = W_L_0;
elseif (options_.order == 2 && M_.hessian_eq_zero) || options_.discretionary_policy %linear quadratic problem elseif (options_.order == 2 && M_.hessian_eq_zero) || options_.discretionary_policy %linear quadratic problem
[U, T_order, T] = feval([M_.fname '.objective.sparse.static_resid'], ys, zeros(1,exo_nbr), M_.params); [U,Uy,Uyy] = feval([M_.fname '.objective.static'],ys,zeros(1,exo_nbr), M_.params);
[Uy, T_order, T] = feval([M_.fname '.objective.sparse.static_g1'], ys, zeros(1,exo_nbr), M_.params, M_.objective_g1_sparse_rowval, M_.objective_g1_sparse_colval, M_.objective_g1_sparse_colptr, T_order, T);
Uyy_v = feval([M_.fname '.objective.sparse.static_g2'], ys, zeros(1,exo_nbr), M_.params, T_order, T);
Gy = dr.ghx(nstatic+(1:nspred),:); Gy = dr.ghx(nstatic+(1:nspred),:);
Gu = dr.ghu(nstatic+(1:nspred),:); Gu = dr.ghu(nstatic+(1:nspred),:);
gy(dr.order_var,:) = dr.ghx; gy(dr.order_var,:) = dr.ghx;
gu(dr.order_var,:) = dr.ghu; gu(dr.order_var,:) = dr.ghu;
Uyy = build_two_dim_hessian(M_.objective_g2_sparse_indices, Uyy_v, 1, M_.endo_nbr);
Uyy = full(Uyy); Uyy = full(Uyy);
Uyygygy = A_times_B_kronecker_C(Uyy,gy,gy); Uyygygy = A_times_B_kronecker_C(Uyy,gy,gy);
@ -312,7 +305,7 @@ else
dr.(['g_' num2str(i)]) = [dr.(['g_' num2str(i)]); W.(['W_' num2str(i)])]; dr.(['g_' num2str(i)]) = [dr.(['g_' num2str(i)]); W.(['W_' num2str(i)])];
end end
% Amends the steady-state vector accordingly % Amends the steady-state vector accordingly
U = feval([M_.fname '.objective.sparse.static_resid'], ys, zeros(1,exo_nbr), M_.params); [U] = feval([M_.fname '.objective.static'],ys,zeros(1,exo_nbr), M_.params);
ysteady = [ys(oo_.dr.order_var); U/(1-beta)]; ysteady = [ys(oo_.dr.order_var); U/(1-beta)];
% Generates the sequence of shocks to compute unconditional welfare % Generates the sequence of shocks to compute unconditional welfare

View File

@ -123,11 +123,7 @@ for its = 1:maxit
fjac2=fjac'*fjac; fjac2=fjac'*fjac;
temp=max(sum(abs(fjac2))); temp=max(sum(abs(fjac2)));
if temp>0 if temp>0
if issparse(fjac) p=-(fjac2+sqrt(nn*eps)*temp*eye(nn))\(fjac'*fvec);
p=-(fjac2+sqrt(nn*eps)*temp*speye(nn))\(fjac'*fvec);
else
p=-(fjac2+sqrt(nn*eps)*temp*eye(nn))\(fjac'*fvec);
end
else else
errorflag = true; errorflag = true;
errorcode = 5; errorcode = 5;

View File

@ -25,7 +25,7 @@ function [dr,info]=PCL_resol(ys,check_flag)
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright © 2001-2024 Dynare Team % Copyright © 2001-2017 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -65,13 +65,7 @@ end
dr.ys = ys; dr.ys = ys;
check1 = 0; check1 = 0;
% testing for steadystate file % testing for steadystate file
static_resid = str2func(sprintf('%s.sparse.static_resid', M_.fname)); fh = str2func([M_.fname '.static']);
static_g1 = str2func(sprintf('%s.sparse.static_g1', M_.fname));
function [resid, g1] = static_resid_g1(y, x, params)
[resid, T_order, T] = static_resid(y, x, params);
g1 = static_g1(y, x, params, M_.static_g1_sparse_rowval, M_.static_g1_sparse_colval, M_.static_g1_sparse_colptr, T_order, T);
end
if options_.steadystate_flag if options_.steadystate_flag
[dr.ys,check1] = feval([M_.fname '_steadystate'],dr.ys,... [dr.ys,check1] = feval([M_.fname '_steadystate'],dr.ys,...
[oo_.exo_steady_state; ... [oo_.exo_steady_state; ...
@ -93,17 +87,17 @@ else
if ~options_.ramsey_policy if ~options_.ramsey_policy
if options_.linear == 0 if options_.linear == 0
% nonlinear models % nonlinear models
if max(abs(static_resid_g1(dr.ys, [oo_.exo_steady_state; ... if max(abs(feval(fh,dr.ys,[oo_.exo_steady_state; ...
oo_.exo_det_steady_state], M_.params))) > options_.solve_tolf oo_.exo_det_steady_state], M_.params))) > options_.solve_tolf
opt = options_; opt = options_;
opt.jacobian_flag = false; opt.jacobian_flag = false;
[dr.ys, check1] = dynare_solve(static_resid_g1, dr.ys, options.steady_.maxit, options_.solve_tolf, options_.solve_tolx, ... [dr.ys, check1] = dynare_solve(fh,dr.ys, options.steady_.maxit, options_.solve_tolf, options_.solve_tolx, ...
opt, [oo_.exo_steady_state; oo_.exo_det_steady_state], M_.params); opt, [oo_.exo_steady_state; oo_.exo_det_steady_state], M_.params);
end end
else else
% linear models % linear models
[fvec,jacob] = static_resid_g1(dr.ys, [oo_.exo_steady_state;... [fvec,jacob] = feval(fh,dr.ys,[oo_.exo_steady_state;...
oo_.exo_det_steady_state], M_.params); oo_.exo_det_steady_state], M_.params);
if max(abs(fvec)) > 1e-12 if max(abs(fvec)) > 1e-12
dr.ys = dr.ys-jacob\fvec; dr.ys = dr.ys-jacob\fvec;
end end
@ -117,7 +111,7 @@ if check1
resid = check1 ; resid = check1 ;
else else
info(1)= 20; info(1)= 20;
resid = static_resid(ys, oo_.exo_steady_state, M_.params); resid = feval(fh,ys,oo_.exo_steady_state, M_.params);
end end
info(2) = resid'*resid ; info(2) = resid'*resid ;
return return
@ -146,8 +140,6 @@ end
oo_.exo_simul = tempex; oo_.exo_simul = tempex;
tempex = []; tempex = [];
end
% 01/01/2003 MJ added dr_algo == 1 % 01/01/2003 MJ added dr_algo == 1
% 08/24/2001 MJ uses Schmitt-Grohe and Uribe (2001) constant correction % 08/24/2001 MJ uses Schmitt-Grohe and Uribe (2001) constant correction
% in dr.ghs2 % in dr.ghs2

View File

@ -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) exo_steady_state, exo_det_steady_state,params, byte_code)
% Add auxiliary variables to the steady state vector % Add auxiliary variables to the steady state vector
% Copyright © 2009-2024 Dynare Team % Copyright © 2009-2023 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -30,7 +30,7 @@ for i=1:n+1
[exo_steady_state; ... [exo_steady_state; ...
exo_det_steady_state],params); exo_det_steady_state],params);
else else
res = feval([fname '.sparse.static_resid'], ys1,... res = feval([fname '.static'],ys1,...
[exo_steady_state; ... [exo_steady_state; ...
exo_det_steady_state],params); exo_det_steady_state],params);
end end

View File

@ -23,7 +23,7 @@ function [oo_, ts]=perfect_foresight_solver(M_, options_, oo_, no_error_if_learn
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
% Copyright © 1996-2024 Dynare Team % Copyright © 1996-2023 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -55,7 +55,7 @@ end
periods = options_.periods; periods = options_.periods;
if options_.debug if options_.debug
model_static = str2func([M_.fname,'.sparse.static_resid']); model_static = str2func([M_.fname,'.static']);
for ii=1:size(oo_.exo_simul,1) for ii=1:size(oo_.exo_simul,1)
[residual(:,ii)] = model_static(oo_.steady_state, oo_.exo_simul(ii,:),M_.params); [residual(:,ii)] = model_static(oo_.steady_state, oo_.exo_simul(ii,:),M_.params);
end end

View File

@ -1,6 +1,6 @@
project('dynare', project('dynare',
'cpp', 'fortran', 'c', 'cpp', 'fortran', 'c',
version : '7-unstable', version : '6.1',
# NB: update C++ standard in .clang-format whenever the following is modified # NB: update C++ standard in .clang-format whenever the following is modified
default_options : [ 'cpp_std=gnu++20', 'fortran_std=f2018', default_options : [ 'cpp_std=gnu++20', 'fortran_std=f2018',
'c_std=gnu17', 'warning_level=2' ], 'c_std=gnu17', 'warning_level=2' ],
@ -365,10 +365,6 @@ shared_module('logarithmic_reduction', [ 'mex/sources/logarithmic_reduction/mexF
shared_module('disclyap_fast', [ 'mex/sources/disclyap_fast/disclyap_fast.f08' ] + mex_blas_fortran_iface, shared_module('disclyap_fast', [ 'mex/sources/disclyap_fast/disclyap_fast.f08' ] + mex_blas_fortran_iface,
kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ]) kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ])
# TODO: Same remark as A_times_B_kronecker_C
shared_module('riccati_update', [ 'mex/sources/riccati_update/mexFunction.f08' ] + mex_blas_fortran_iface,
kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ])
qmc_sequence_src = [ 'mex/sources/sobol/qmc_sequence.cc', qmc_sequence_src = [ 'mex/sources/sobol/qmc_sequence.cc',
'mex/sources/sobol/sobol.f08' ] 'mex/sources/sobol/sobol.f08' ]
# Hack for statically linking libgfortran # Hack for statically linking libgfortran
@ -1830,7 +1826,6 @@ mod_and_m_tests = [
'solver-test-functions/wood.m',] }, 'solver-test-functions/wood.m',] },
{ 'test' : [ 'cyclereduction.m' ] }, { 'test' : [ 'cyclereduction.m' ] },
{ 'test' : [ 'logarithmicreduction.m' ] }, { 'test' : [ 'logarithmicreduction.m' ] },
{ 'test' : [ 'riccatiupdate.m' ] },
{ 'test' : [ 'kalman/likelihood/test_kalman_mex.m' ] }, { 'test' : [ 'kalman/likelihood/test_kalman_mex.m' ] },
{ 'test' : [ 'contribs.m' ], { 'test' : [ 'contribs.m' ],
'extra' : [ 'sandbox.mod', 'extra' : [ 'sandbox.mod',

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2021-2024 Dynare Team * Copyright © 2021-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -18,23 +18,26 @@
*/ */
#include "k_ord_objective.hh" #include "k_ord_objective.hh"
#include "objective_abstract_class.hh"
#include <cassert> #include <cassert>
#include <utility> #include <utility>
KordwDynare::KordwDynare(KordpDynare& m, Journal& jr, Vector& inParams, KordwDynare::KordwDynare(KordpDynare& m, ConstVector& NNZD_arg, Journal& jr, Vector& inParams,
std::unique_ptr<ObjectiveMFile> objectiveFile_arg, std::unique_ptr<ObjectiveAC> objectiveFile_arg,
const std::vector<int>& dr_order) : const std::vector<int>& dr_order) :
model {m}, model {m},
NNZD {NNZD_arg},
journal {jr}, journal {jr},
params {inParams}, params {inParams},
resid(1), resid(1),
ud {1}, ud {1},
objectiveFile {std::move(objectiveFile_arg)} objectiveFile {std::move(objectiveFile_arg)}
{ {
dynppToDyn = dr_order;
dynToDynpp.resize(model.ny()); dynToDynpp.resize(model.ny());
for (int i = 0; i < model.ny(); i++) for (int i = 0; i < model.ny(); i++)
dynToDynpp[dr_order[i]] = i; dynToDynpp[dynppToDyn[i]] = i;
} }
void void
@ -43,10 +46,71 @@ KordwDynare::calcDerivativesAtSteady()
assert(ud.begin() == ud.end()); assert(ud.begin() == ud.end());
std::vector<TwoDMatrix> dyn_ud; // Planner's objective derivatives, in Dynare form
dyn_ud.emplace_back(1, model.ny()); // Allocate Jacobian
dyn_ud.back().zeros();
for (int i = 2; i <= model.order(); i++)
{
// Higher order derivatives, as sparse (3-column) matrices
dyn_ud.emplace_back(static_cast<int>(NNZD[i - 1]), 3);
dyn_ud.back().zeros();
}
Vector xx(model.nexog()); Vector xx(model.nexog());
xx.zeros(); xx.zeros();
resid.zeros(); resid.zeros();
objectiveFile->eval(model.getSteady(), xx, params, resid, dynToDynpp, ud); objectiveFile->eval(model.getSteady(), xx, params, resid, dyn_ud);
for (int i = 1; i <= model.order(); i++)
populateDerivativesContainer(dyn_ud, i);
}
void
KordwDynare::populateDerivativesContainer(const std::vector<TwoDMatrix>& dyn_ud, int ord)
{
const TwoDMatrix& u = dyn_ud[ord - 1];
// utility derivatives FSSparseTensor instance
auto udTi = std::make_unique<FSSparseTensor>(ord, model.ny(), 1);
IntSequence s(ord, 0);
if (ord == 1)
for (int i = 0; i < u.ncols(); i++)
{
for (int j = 0; j < u.nrows(); j++)
{
double x = u.get(j, dynppToDyn[s[0]]);
if (x != 0.0)
udTi->insert(s, j, x);
}
s[0]++;
}
else // ord ≥ 2
for (int i = 0; i < u.nrows(); i++)
{
int j = static_cast<int>(u.get(i, 0)) - 1;
int i1 = static_cast<int>(u.get(i, 1)) - 1;
if (j < 0 || i1 < 0)
continue; // Discard empty entries (see comment in DynamicModelAC::unpackSparseMatrix())
for (int k = 0; k < ord; k++)
{
s[k] = dynToDynpp[i1 % model.ny()];
i1 /= model.ny();
}
if (ord == 2 && !s.isSorted())
continue; // Skip symmetric elements (only needed at order 2)
else if (ord > 2)
s.sort(); // For higher order, canonicalize the multi-index
double x = u.get(i, 2);
udTi->insert(s, j, x);
}
ud.insert(std::move(udTi));
} }
template<> template<>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2021-2024 Dynare Team * Copyright © 2021-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -21,7 +21,7 @@
#define K_ORD_OBJECTIVE_HH #define K_ORD_OBJECTIVE_HH
#include "k_ord_dynare.hh" #include "k_ord_dynare.hh"
#include "objective_m.hh" #include "objective_abstract_class.hh"
class KordwDynare; class KordwDynare;
@ -29,19 +29,22 @@ class KordwDynare
{ {
public: public:
KordpDynare& model; KordpDynare& model;
const ConstVector& NNZD;
private: private:
Journal& journal; Journal& journal;
Vector& params; Vector& params;
Vector resid; Vector resid;
TensorContainer<FSSparseTensor> ud; // planner's objective derivatives, in Dynare++ form TensorContainer<FSSparseTensor> ud; // planner's objective derivatives, in Dynare++ form
std::vector<int> dynppToDyn; // Maps Dynare++ jacobian variable indices to Dynare ones
std::vector<int> dynToDynpp; // Maps Dynare jacobian variable indices to Dynare++ ones std::vector<int> dynToDynpp; // Maps Dynare jacobian variable indices to Dynare++ ones
std::unique_ptr<ObjectiveMFile> objectiveFile; std::unique_ptr<ObjectiveAC> objectiveFile;
public: public:
KordwDynare(KordpDynare& m, Journal& jr, Vector& inParams, KordwDynare(KordpDynare& m, ConstVector& NNZD_arg, Journal& jr, Vector& inParams,
std::unique_ptr<ObjectiveMFile> objectiveFile_arg, const std::vector<int>& varOrder); std::unique_ptr<ObjectiveAC> objectiveFile_arg, const std::vector<int>& varOrder);
void calcDerivativesAtSteady(); void calcDerivativesAtSteady();
void populateDerivativesContainer(const std::vector<TwoDMatrix>& dyn_ud, int ord);
[[nodiscard]] const TensorContainer<FSSparseTensor>& [[nodiscard]] const TensorContainer<FSSparseTensor>&
getPlannerObjDerivatives() const getPlannerObjDerivatives() const
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2021-2024 Dynare Team * Copyright © 2021-2022 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -31,7 +31,6 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <string>
#include "dynmex.h" #include "dynmex.h"
@ -88,8 +87,8 @@ The routine proceeds in several steps:
to the approxAtSteady method in the ApproximationWelfare class carries out the necessary to the approxAtSteady method in the ApproximationWelfare class carries out the necessary
operation operation
- Importing the derivatives of the felicity function with the calcDerivativesAtSteady() method of - Importing the derivatives of the felicity function with the calcDerivativesAtSteady() method of
the KordwDynare class. It relies on the MATLAB-generated files, which are handled by the the KordwDynare class. It relies on the Matlab-generated files, which are handled by the
ObjectiveMFile class ObjectiveAC and ObjectiveMFile classes
- Pinpointing the derivatives of the felicity and welfare functions. The performStep method of - Pinpointing the derivatives of the felicity and welfare functions. The performStep method of
the KOrderWelfare class carries out the calculations,resorting to the FaaDiBruno class and its the KOrderWelfare class carries out the calculations,resorting to the FaaDiBruno class and its
methods to get the needed intermediary results. methods to get the needed intermediary results.
@ -215,6 +214,15 @@ extern "C"
mexErrMsgTxt("The derivatives were not computed for the required order. Make sure that you " mexErrMsgTxt("The derivatives were not computed for the required order. Make sure that you "
"used the right order option inside the `stoch_simul' command"); "used the right order option inside the `stoch_simul' command");
const mxArray* nnzderivatives_obj_mx = mxGetField(M_mx, 0, "NNZDerivatives_objective");
if (!(nnzderivatives_obj_mx && mxIsDouble(nnzderivatives_obj_mx)
&& !mxIsComplex(nnzderivatives_obj_mx) && !mxIsSparse(nnzderivatives_obj_mx)))
mexErrMsgTxt("M_.NNZDerivatives should be a real dense array");
ConstVector NNZD_obj {nnzderivatives_obj_mx};
if (NNZD.length() < kOrder || NNZD_obj[kOrder - 1] == -1)
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"); const mxArray* endo_names_mx = mxGetField(M_mx, 0, "endo_names");
if (!(endo_names_mx && mxIsCell(endo_names_mx) if (!(endo_names_mx && mxIsCell(endo_names_mx)
&& mxGetNumberOfElements(endo_names_mx) == static_cast<size_t>(nEndo))) && mxGetNumberOfElements(endo_names_mx) == static_cast<size_t>(nEndo)))
@ -253,32 +261,6 @@ extern "C"
std::transform(mxGetPr(order_var_mx), mxGetPr(order_var_mx) + nEndo, dr_order.begin(), std::transform(mxGetPr(order_var_mx), mxGetPr(order_var_mx) + nEndo, dr_order.begin(),
[](double x) { return static_cast<int>(x) - 1; }); [](double x) { return static_cast<int>(x) - 1; });
const mxArray* objective_g1_sparse_rowval_mx
= mxGetField(M_mx, 0, "objective_g1_sparse_rowval");
if (!(objective_g1_sparse_rowval_mx && mxIsInt32(objective_g1_sparse_rowval_mx)))
mexErrMsgTxt("M_.objective_g1_sparse_rowval should be an int32 array");
const mxArray* objective_g1_sparse_colval_mx
= mxGetField(M_mx, 0, "objective_g1_sparse_colval");
if (!(objective_g1_sparse_colval_mx && mxIsInt32(objective_g1_sparse_colval_mx)))
mexErrMsgTxt("M_.objective_g1_sparse_colval should be an int32 array");
const mxArray* objective_g1_sparse_colptr_mx
= mxGetField(M_mx, 0, "objective_g1_sparse_colptr");
if (!(objective_g1_sparse_colptr_mx && mxIsInt32(objective_g1_sparse_colptr_mx)))
mexErrMsgTxt("M_.objective_g1_sparse_colptr should be an int32 array");
std::vector<const mxArray*> objective_gN_sparse_indices;
for (int o {2}; o <= kOrder; o++)
{
using namespace std::string_literals;
auto fieldname {"objective_g"s + std::to_string(o) + "_sparse_indices"};
const mxArray* indices = mxGetField(M_mx, 0, fieldname.c_str());
if (!(indices && mxIsInt32(indices)))
mexErrMsgTxt(("M_."s + fieldname + " should be an int32 array").c_str());
objective_gN_sparse_indices.push_back(indices);
}
const int nSteps const int nSteps
= 0; // Dynare++ solving steps, for time being default to 0 = deterministic steady state = 0; // Dynare++ solving steps, for time being default to 0 = deterministic steady state
@ -309,14 +291,21 @@ extern "C"
// run stochastic steady // run stochastic steady
app.walkStochSteady(); app.walkStochSteady();
const mxArray* objective_tmp_nbr_mx = mxGetField(M_mx, 0, "objective_tmp_nbr");
if (!(objective_tmp_nbr_mx && mxIsDouble(objective_tmp_nbr_mx)
&& !mxIsComplex(objective_tmp_nbr_mx) && !mxIsSparse(objective_tmp_nbr_mx)
&& mxGetNumberOfElements(objective_tmp_nbr_mx) >= static_cast<size_t>(kOrder + 1)))
mexErrMsgTxt("M_.objective_tmp_nbr should be a real dense array with strictly more elements "
"than the order of derivation");
int ntt_objective = std::accumulate(mxGetPr(objective_tmp_nbr_mx),
mxGetPr(objective_tmp_nbr_mx) + kOrder + 1, 0);
// Getting derivatives of the planner's objective function // Getting derivatives of the planner's objective function
std::unique_ptr<ObjectiveMFile> objectiveFile; std::unique_ptr<ObjectiveAC> objectiveFile;
objectiveFile = std::make_unique<ObjectiveMFile>( objectiveFile = std::make_unique<ObjectiveMFile>(fname, ntt_objective);
fname, kOrder, objective_g1_sparse_rowval_mx, objective_g1_sparse_colval_mx,
objective_g1_sparse_colptr_mx, objective_gN_sparse_indices);
// make KordwDynare object // make KordwDynare object
KordwDynare welfare(dynare, journal, modParams, std::move(objectiveFile), dr_order); KordwDynare welfare(dynare, NNZD_obj, journal, modParams, std::move(objectiveFile), dr_order);
// construct main K-order approximation class of welfare // construct main K-order approximation class of welfare
ApproximationWelfare appwel(welfare, discount_factor, app.get_rule_ders(), ApproximationWelfare appwel(welfare, discount_factor, app.get_rule_ders(),

View File

@ -0,0 +1,38 @@
/*
* Copyright © 2021-2023 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef OBJECTIVE_ABSTRACT_CLASS_HH
#define OBJECTIVE_ABSTRACT_CLASS_HH
#include <vector>
#include "twod_matrix.hh"
class ObjectiveAC
{
protected:
int ntt; // Size of vector of temporary terms
public:
ObjectiveAC(int ntt_arg) : ntt {ntt_arg} {};
virtual ~ObjectiveAC() = default;
virtual void eval(const Vector& y, const Vector& x, const Vector& params, Vector& residual,
std::vector<TwoDMatrix>& md)
= 0;
};
#endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2021-2024 Dynare Team * Copyright © 2021-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -26,41 +26,88 @@
#include "objective_m.hh" #include "objective_m.hh"
ObjectiveMFile::ObjectiveMFile(const std::string& modName, int kOrder_arg, ObjectiveMFile::ObjectiveMFile(const std::string& modName, int ntt_arg) :
const mxArray* objective_g1_sparse_rowval_mx_arg, ObjectiveAC(ntt_arg), ObjectiveMFilename {modName + ".objective.static"}
const mxArray* objective_g1_sparse_colval_mx_arg,
const mxArray* objective_g1_sparse_colptr_mx_arg,
const std::vector<const mxArray*> objective_gN_sparse_indices_arg) :
ObjectiveMFilename {modName + ".objective.sparse.static"},
kOrder {kOrder_arg},
objective_g1_sparse_rowval_mx {objective_g1_sparse_rowval_mx_arg},
objective_g1_sparse_colval_mx {objective_g1_sparse_colval_mx_arg},
objective_g1_sparse_colptr_mx {objective_g1_sparse_colptr_mx_arg},
objective_gN_sparse_indices {objective_gN_sparse_indices_arg}
{ {
} }
void void
ObjectiveMFile::eval(const Vector& y, const Vector& x, const Vector& modParams, Vector& residual, ObjectiveMFile::unpackSparseMatrixAndCopyIntoTwoDMatData(mxArray* sparseMat, TwoDMatrix& tdm)
const std::vector<int>& dynToDynpp,
TensorContainer<FSSparseTensor>& derivatives) const
{ {
mxArray* y_mx = mxCreateDoubleMatrix(y.length(), 1, mxREAL); int totalCols = mxGetN(sparseMat);
std::copy_n(y.base(), y.length(), mxGetPr(y_mx)); mwIndex* rowIdxVector = mxGetIr(sparseMat);
mwIndex* colIdxVector = mxGetJc(sparseMat);
mxArray* x_mx = mxCreateDoubleMatrix(1, x.length(), mxREAL); assert(tdm.ncols() == 3);
std::copy_n(x.base(), x.length(), mxGetPr(x_mx)); /* 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() >= static_cast<int>(mxGetNzmax(sparseMat)));
mxArray* params_mx = mxCreateDoubleMatrix(modParams.length(), 1, mxREAL); double* ptr = mxGetPr(sparseMat);
std::copy_n(modParams.base(), modParams.length(), mxGetPr(params_mx));
mxArray *T_order_mx, *T_mx; int rind = 0;
int output_row = 0;
for (int i = 0; i < totalCols; i++)
for (int j = 0; j < static_cast<int>((colIdxVector[i + 1] - colIdxVector[i])); j++, rind++)
{
tdm.get(output_row, 0) = rowIdxVector[rind] + 1;
tdm.get(output_row, 1) = i + 1;
tdm.get(output_row, 2) = ptr[rind];
output_row++;
}
/* 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 < tdm.nrows())
{
tdm.get(output_row, 0) = 0;
tdm.get(output_row, 1) = 0;
tdm.get(output_row, 2) = 0;
output_row++;
}
}
void
ObjectiveMFile::eval(const Vector& y, const Vector& x, const Vector& modParams, Vector& residual,
std::vector<TwoDMatrix>& md) noexcept(false)
{
mxArray* T_m = mxCreateDoubleMatrix(ntt, 1, mxREAL);
mxArray* y_m = mxCreateDoubleMatrix(y.length(), 1, mxREAL);
std::copy_n(y.base(), y.length(), mxGetPr(y_m));
mxArray* x_m = mxCreateDoubleMatrix(1, x.length(), mxREAL);
std::copy_n(x.base(), x.length(), mxGetPr(x_m));
mxArray* params_m = mxCreateDoubleMatrix(modParams.length(), 1, mxREAL);
std::copy_n(modParams.base(), modParams.length(), mxGetPr(params_m));
mxArray* T_flag_m = mxCreateLogicalScalar(false);
{
// Compute temporary terms (for all orders)
std::string funcname = ObjectiveMFilename + "_g" + std::to_string(md.size()) + "_tt";
std::array<mxArray*, 1> plhs;
std::array prhs {T_m, y_m, x_m, params_m};
int retVal
= mexCallMATLAB(plhs.size(), plhs.data(), prhs.size(), prhs.data(), funcname.c_str());
if (retVal != 0)
throw DynareException(__FILE__, __LINE__, "Trouble calling " + funcname);
mxDestroyArray(T_m);
T_m = plhs[0];
}
{ {
// Compute residuals // Compute residuals
std::string funcname = ObjectiveMFilename + "_resid"; std::string funcname = ObjectiveMFilename + "_resid";
std::array<mxArray*, 3> plhs; std::array<mxArray*, 1> plhs;
std::array prhs {y_mx, x_mx, params_mx}; std::array prhs {T_m, y_m, x_m, params_m, T_flag_m};
int retVal int retVal
= mexCallMATLAB(plhs.size(), plhs.data(), prhs.size(), prhs.data(), funcname.c_str()); = mexCallMATLAB(plhs.size(), plhs.data(), prhs.size(), prhs.data(), funcname.c_str());
@ -69,103 +116,35 @@ ObjectiveMFile::eval(const Vector& y, const Vector& x, const Vector& modParams,
residual = Vector {plhs[0]}; residual = Vector {plhs[0]};
mxDestroyArray(plhs[0]); mxDestroyArray(plhs[0]);
T_order_mx = plhs[1];
T_mx = plhs[2];
} }
{ for (size_t i = 1; i <= md.size(); i++)
// Compute Jacobian
std::string funcname = ObjectiveMFilename + "_g1";
std::array<mxArray*, 3> plhs;
std::array prhs {y_mx,
x_mx,
params_mx,
const_cast<mxArray*>(objective_g1_sparse_rowval_mx),
const_cast<mxArray*>(objective_g1_sparse_colval_mx),
const_cast<mxArray*>(objective_g1_sparse_colptr_mx),
T_order_mx,
T_mx};
int retVal
= mexCallMATLAB(plhs.size(), plhs.data(), prhs.size(), prhs.data(), funcname.c_str());
if (retVal != 0)
throw DynareException(__FILE__, __LINE__, "Trouble calling " + funcname);
assert(static_cast<int>(mxGetN(plhs[0])) == y.length());
double* g1_v {mxGetPr(plhs[0])};
mwIndex* g1_ir {mxGetIr(plhs[0])};
mwIndex* g1_jc {mxGetJc(plhs[0])};
IntSequence s(1, 0);
auto tensor = std::make_unique<FSSparseTensor>(1, y.length(), 1);
for (int j {0}; j < y.length(); j++)
for (mwIndex k {g1_jc[j]}; k < g1_jc[j + 1]; k++)
{
s[0] = dynToDynpp[j];
tensor->insert(s, g1_ir[k], g1_v[k]);
}
mxDestroyArray(plhs[0]);
mxDestroyArray(T_order_mx);
T_order_mx = plhs[1];
mxDestroyArray(T_mx);
T_mx = plhs[2];
derivatives.insert(std::move(tensor));
}
for (int o {2}; o <= kOrder; o++)
{ {
// Compute higher derivatives // Compute model derivatives
std::string funcname = ObjectiveMFilename + "_g" + std::to_string(o); std::string funcname = ObjectiveMFilename + "_g" + std::to_string(i);
std::array<mxArray*, 3> plhs; std::array<mxArray*, 1> plhs;
std::array prhs {y_mx, x_mx, params_mx, T_order_mx, T_mx}; std::array prhs {T_m, y_m, x_m, params_m, T_flag_m};
int retVal int retVal
= mexCallMATLAB(plhs.size(), plhs.data(), prhs.size(), prhs.data(), funcname.c_str()); = mexCallMATLAB(plhs.size(), plhs.data(), prhs.size(), prhs.data(), funcname.c_str());
if (retVal != 0) if (retVal != 0)
throw DynareException(__FILE__, __LINE__, "Trouble calling " + funcname); throw DynareException(__FILE__, __LINE__, "Trouble calling " + funcname);
const mxArray* sparse_indices_mx {objective_gN_sparse_indices[o - 2]}; if (i == 1)
size_t nnz {mxGetM(sparse_indices_mx)};
#if MX_HAS_INTERLEAVED_COMPLEX
const int32_T* sparse_indices {mxGetInt32s(sparse_indices_mx)};
#else
const int32_T* sparse_indices {static_cast<const int32_T*>(mxGetData(sparse_indices_mx))};
#endif
assert(mxGetNumberOfElements(plhs[0]) == nnz);
double* gN_v {mxGetPr(plhs[0])};
IntSequence s(o, 0);
auto tensor = std::make_unique<FSSparseTensor>(o, y.length(), 1);
for (size_t k {0}; k < nnz; k++)
{ {
for (int i {0}; i < o; i++) assert(static_cast<int>(mxGetM(plhs[0])) == md[i - 1].nrows());
s[i] = dynToDynpp[sparse_indices[k + (i + 1) * nnz] - 1]; assert(static_cast<int>(mxGetN(plhs[0])) == md[i - 1].ncols());
assert(s.isSorted()); std::copy_n(mxGetPr(plhs[0]), mxGetM(plhs[0]) * mxGetN(plhs[0]), md[i - 1].base());
tensor->insert(s, sparse_indices[k] - 1, gN_v[k]);
} }
else
unpackSparseMatrixAndCopyIntoTwoDMatData(plhs[0], md[i - 1]);
mxDestroyArray(plhs[0]); mxDestroyArray(plhs[0]);
mxDestroyArray(T_order_mx);
T_order_mx = plhs[1];
mxDestroyArray(T_mx);
T_mx = plhs[2];
derivatives.insert(std::move(tensor));
} }
mxDestroyArray(y_mx); mxDestroyArray(T_m);
mxDestroyArray(x_mx); mxDestroyArray(y_m);
mxDestroyArray(params_mx); mxDestroyArray(x_m);
mxDestroyArray(T_order_mx); mxDestroyArray(params_m);
mxDestroyArray(T_mx); mxDestroyArray(T_flag_m);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2021-2024 Dynare Team * Copyright © 2021-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -20,34 +20,24 @@
#ifndef OBJECTIVE_M_HH #ifndef OBJECTIVE_M_HH
#define OBJECTIVE_M_HH #define OBJECTIVE_M_HH
#include <vector> #include "objective_abstract_class.hh"
#include "dynmex.h" #include "mex.h"
#include <dynmex.h>
#include "Vector.hh" /**
#include "sparse_tensor.hh" * handles calls to <model>/+objective/static.m
#include "t_container.hh" *
**/
// Handles calls to <model>/+objective/+sparse/static*.m class ObjectiveMFile : public ObjectiveAC
class ObjectiveMFile
{ {
private: private:
const std::string ObjectiveMFilename; const std::string ObjectiveMFilename;
const int kOrder; static void unpackSparseMatrixAndCopyIntoTwoDMatData(mxArray* sparseMat, TwoDMatrix& tdm);
const mxArray *const objective_g1_sparse_rowval_mx, *const objective_g1_sparse_colval_mx,
*const objective_g1_sparse_colptr_mx;
// Stores M_.objective_gN_sparse_indices, starting from N=2
const std::vector<const mxArray*> objective_gN_sparse_indices;
public: public:
ObjectiveMFile(const std::string& modName, int kOrder_arg, explicit ObjectiveMFile(const std::string& modName, int ntt_arg);
const mxArray* objective_g1_sparse_rowval_mx_arg,
const mxArray* objective_g1_sparse_colval_mx_arg,
const mxArray* objective_g1_sparse_colptr_mx_arg,
const std::vector<const mxArray*> objective_gN_sparse_indices_arg);
void eval(const Vector& y, const Vector& x, const Vector& params, Vector& residual, void eval(const Vector& y, const Vector& x, const Vector& params, Vector& residual,
const std::vector<int>& dynToDynpp, TensorContainer<FSSparseTensor>& derivatives) const std::vector<TwoDMatrix>& md) override;
noexcept(false);
}; };
#endif #endif

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004-2011 Ondra Kamenik * Copyright © 2004-2011 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -240,11 +240,16 @@ public:
real = r; real = r;
} }
virtual ~_matrix_iter() = default; virtual ~_matrix_iter() = default;
[[nodiscard]] bool bool
operator==(const _Self& it) const operator==(const _Self& it) const
{ {
return ptr == it.ptr; return ptr == it.ptr;
} }
bool
operator!=(const _Self& it) const
{
return ptr != it.ptr;
}
_TRef _TRef
operator*() const operator*() const
{ {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004-2011 Ondra Kamenik * Copyright © 2004-2011 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -114,6 +114,42 @@ Vector::Vector(mxArray* p) :
throw SYLV_MES_EXCEPTION("This is not a dense array of real doubles."); throw SYLV_MES_EXCEPTION("This is not a dense array of real doubles.");
} }
bool
Vector::operator==(const Vector& y) const
{
return ConstVector(*this) == y;
}
bool
Vector::operator!=(const Vector& y) const
{
return ConstVector(*this) != y;
}
bool
Vector::operator<(const Vector& y) const
{
return ConstVector(*this) < y;
}
bool
Vector::operator<=(const Vector& y) const
{
return ConstVector(*this) <= y;
}
bool
Vector::operator>(const Vector& y) const
{
return ConstVector(*this) > y;
}
bool
Vector::operator>=(const Vector& y) const
{
return ConstVector(*this) >= y;
}
void void
Vector::zeros() Vector::zeros()
{ {
@ -287,10 +323,17 @@ ConstVector::operator==(const ConstVector& y) const
return i == len; return i == len;
} }
std::partial_ordering bool
ConstVector::operator<=>(const ConstVector& y) const ConstVector::operator<(const ConstVector& y) const
{ {
return std::lexicographical_compare_three_way(data, data + len, y.data, y.data + y.len); int i = std::min(len, y.len);
int ii = 0;
while (ii < i && operator[](ii) == y[ii])
ii++;
if (ii < i)
return operator[](ii) < y[ii];
else
return len < y.len;
} }
double double

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004-2011 Ondra Kamenik * Copyright © 2004-2011 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -25,7 +25,6 @@
to avoid running virtual method invokation mechanism. Some to avoid running virtual method invokation mechanism. Some
members, and methods are thus duplicated */ members, and methods are thus duplicated */
#include <compare>
#include <complex> #include <complex>
#include <utility> #include <utility>
@ -109,6 +108,15 @@ public:
return s; return s;
} }
// Exact equality.
bool operator==(const Vector& y) const;
bool operator!=(const Vector& y) const;
// Lexicographic ordering.
bool operator<(const Vector& y) const;
bool operator<=(const Vector& y) const;
bool operator>(const Vector& y) const;
bool operator>=(const Vector& y) const;
virtual ~Vector() virtual ~Vector()
{ {
if (destroy) if (destroy)
@ -211,9 +219,29 @@ public:
return s; return s;
} }
// Exact equality // Exact equality
[[nodiscard]] bool operator==(const ConstVector& y) const; bool operator==(const ConstVector& y) const;
bool
operator!=(const ConstVector& y) const
{
return !operator==(y);
}
// Lexicographic ordering // Lexicographic ordering
[[nodiscard]] std::partial_ordering operator<=>(const ConstVector& y) const; bool operator<(const ConstVector& y) const;
bool
operator<=(const ConstVector& y) const
{
return operator<(y) || operator==(y);
}
bool
operator>(const ConstVector& y) const
{
return !operator<=(y);
}
bool
operator>=(const ConstVector& y) const
{
return !operator<(y);
}
[[nodiscard]] double getNorm() const; [[nodiscard]] double getNorm() const;
[[nodiscard]] double getMax() const; [[nodiscard]] double getMax() const;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -35,14 +35,12 @@ OrdSequence::operator[](int i) const
orderings can be used for different problem sizes. We order them orderings can be used for different problem sizes. We order them
according to the average, and then according to the first item. */ according to the average, and then according to the first item. */
std::partial_ordering bool
OrdSequence::operator<=>(const OrdSequence& s) const OrdSequence::operator<(const OrdSequence& s) const
{ {
double ta = average(); double ta = average();
double sa = s.average(); double sa = s.average();
if (auto cmp1 = ta <=> sa; cmp1 != 0) return (ta < sa || ((ta == sa) && (operator[](0) > s[0])));
return cmp1;
return operator[](0) <=> s[0];
} }
bool bool

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -55,7 +55,6 @@
#include "int_sequence.hh" #include "int_sequence.hh"
#include <compare>
#include <list> #include <list>
#include <string> #include <string>
#include <vector> #include <vector>
@ -63,7 +62,7 @@
/* Here is the abstraction for an equivalence class. We implement it as /* Here is the abstraction for an equivalence class. We implement it as
vector<int>. We have a constructor for empty class, copy vector<int>. We have a constructor for empty class, copy
constructor. What is important here is the ordering operator constructor. What is important here is the ordering operator
operator<=>() and methods for addition of an integer, and addition of operator<() and methods for addition of an integer, and addition of
another sequence. Also we provide method has() which returns true if a another sequence. Also we provide method has() which returns true if a
given integer is contained. */ given integer is contained. */
@ -75,9 +74,9 @@ public:
OrdSequence() : data() OrdSequence() : data()
{ {
} }
[[nodiscard]] bool operator==(const OrdSequence& s) const; bool operator==(const OrdSequence& s) const;
int operator[](int i) const; int operator[](int i) const;
[[nodiscard]] std::partial_ordering operator<=>(const OrdSequence& s) const; bool operator<(const OrdSequence& s) const;
[[nodiscard]] const std::vector<int>& [[nodiscard]] const std::vector<int>&
getData() const getData() const
{ {
@ -121,7 +120,12 @@ public:
// Copy constructor plus gluing i1 and i2 in one class // Copy constructor plus gluing i1 and i2 in one class
Equivalence(const Equivalence& e, int i1, int i2); Equivalence(const Equivalence& e, int i1, int i2);
[[nodiscard]] bool operator==(const Equivalence& e) const; bool operator==(const Equivalence& e) const;
bool
operator!=(const Equivalence& e) const
{
return !operator==(e);
}
[[nodiscard]] int [[nodiscard]] int
getN() const getN() const
{ {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -76,11 +76,16 @@ public:
// Constructs the tensor dimensions for slicing (see the implementation for details) // Constructs the tensor dimensions for slicing (see the implementation for details)
TensorDimens(const IntSequence& ss, const IntSequence& coor); TensorDimens(const IntSequence& ss, const IntSequence& coor);
[[nodiscard]] bool bool
operator==(const TensorDimens& td) const operator==(const TensorDimens& td) const
{ {
return nvs == td.nvs && sym == td.sym; return nvs == td.nvs && sym == td.sym;
} }
bool
operator!=(const TensorDimens& td) const
{
return !operator==(td);
}
[[nodiscard]] int [[nodiscard]] int
dimen() const dimen() const

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -103,10 +103,10 @@ IntSequence::operator==(const IntSequence& s) const
return std::equal(data, data + length, s.data, s.data + s.length); return std::equal(data, data + length, s.data, s.data + s.length);
} }
std::strong_ordering bool
IntSequence::operator<=>(const IntSequence& s) const IntSequence::operator<(const IntSequence& s) const
{ {
return std::lexicographical_compare_three_way(data, data + length, s.data, s.data + s.length); return std::lexicographical_compare(data, data + length, s.data, s.data + s.length);
} }
bool bool

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -43,7 +43,6 @@
#define INT_SEQUENCE_HH #define INT_SEQUENCE_HH
#include <algorithm> #include <algorithm>
#include <compare>
#include <initializer_list> #include <initializer_list>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -120,7 +119,12 @@ public:
if (destroy) if (destroy)
delete[] data; delete[] data;
} }
[[nodiscard]] bool operator==(const IntSequence& s) const; bool operator==(const IntSequence& s) const;
bool
operator!=(const IntSequence& s) const
{
return !operator==(s);
}
int& int&
operator[](int i) operator[](int i)
{ {
@ -137,10 +141,15 @@ public:
return length; return length;
} }
/* We provide two orderings. The first operator<=>() is the linear /* We provide two orderings. The first operator<() is the linear
lexicographic ordering, the second less() is the non-linear Cartesian lexicographic ordering, the second less() is the non-linear Cartesian
ordering. */ ordering. */
[[nodiscard]] std::strong_ordering operator<=>(const IntSequence& s) const; bool operator<(const IntSequence& s) const;
bool
operator<=(const IntSequence& s) const
{
return (operator==(s) || operator<(s));
}
[[nodiscard]] bool lessEq(const IntSequence& s) const; [[nodiscard]] bool lessEq(const IntSequence& s) const;
[[nodiscard]] bool less(const IntSequence& s) const; [[nodiscard]] bool less(const IntSequence& s) const;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -86,7 +86,7 @@ public:
KronProdDimens& operator=(const KronProdDimens& kd) = default; KronProdDimens& operator=(const KronProdDimens& kd) = default;
KronProdDimens& operator=(KronProdDimens&& kd) = default; KronProdDimens& operator=(KronProdDimens&& kd) = default;
[[nodiscard]] bool bool
operator==(const KronProdDimens& kd) const operator==(const KronProdDimens& kd) const
{ {
return rows == kd.rows && cols == kd.cols; return rows == kd.rows && cols == kd.cols;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -95,7 +95,7 @@ public:
Permutation(const Permutation& p, int i) : permap(p.permap.insert(p.size(), i)) Permutation(const Permutation& p, int i) : permap(p.permap.insert(p.size(), i))
{ {
} }
[[nodiscard]] bool bool
operator==(const Permutation& p) const operator==(const Permutation& p) const
{ {
return permap == p.permap; return permap == p.permap;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -115,7 +115,7 @@ public:
{ {
per.apply(nvmax); per.apply(nvmax);
} }
[[nodiscard]] bool bool
operator==(const PerTensorDimens& td) const operator==(const PerTensorDimens& td) const
{ {
return TensorDimens::operator==(td) && per == td.per; return TensorDimens::operator==(td) && per == td.per;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -126,11 +126,16 @@ public:
{ {
return run; return run;
} }
[[nodiscard]] bool bool
operator==(const symiterator& it) const operator=(const symiterator& it)
{ {
return dim == it.dim && run == it.run; return dim == it.dim && run == it.run;
} }
bool
operator!=(const symiterator& it)
{
return !operator=(it);
}
}; };
/* The class SymmetrySet defines a set of symmetries of the given length /* The class SymmetrySet defines a set of symmetries of the given length

View File

@ -1,6 +1,6 @@
/* /*
* Copyright © 2004 Ondra Kamenik * Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2024 Dynare Team * Copyright © 2019-2023 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -150,11 +150,16 @@ public:
{ {
return offset; return offset;
} }
[[nodiscard]] bool bool
operator==(const index& n) const operator==(const index& n) const
{ {
return offset == n.offset; return offset == n.offset;
} }
bool
operator!=(const index& n) const
{
return offset != n.offset;
}
[[nodiscard]] const IntSequence& [[nodiscard]] const IntSequence&
getCoor() const getCoor() const
{ {

View File

@ -1,98 +0,0 @@
! Copyright © 2022-2023 Dynare Team
!
! This file is part of Dynare.
!
! Dynare is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! Dynare is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with Dynare. If not, see <https://www.gnu.org/licenses/>.
! Implements Ptmp = T*(P-K*Z*P)*transpose(T)+Q where
! P is the (r x r) variance-covariance matrix of the state vector
! T is the (r x r) transition matrix of the state vector
! K is the (r x n) gain matrix
! Z is the (n x r) matrix linking observable variables to state variables
! Q is the (r x r) variance-covariance matrix of innovations in the state equation
! and accounting for different properties:
! P is a (symmetric) positive semi-definite matrix
! T can be triangular
subroutine mexFunction(nlhs, plhs, nrhs, prhs) bind(c, name='mexFunction')
use matlab_mex
use blas
implicit none (type, external)
type(c_ptr), dimension(*), intent(in), target :: prhs
type(c_ptr), dimension(*), intent(out) :: plhs
integer(c_int), intent(in), value :: nlhs, nrhs
real(real64), dimension(:,:), pointer, contiguous :: P, T, K, Z, Q, Pnew
real(real64), dimension(:,:), allocatable :: tmp1, tmp2
integer :: i, n, r
character(kind=c_char, len=2) :: num2str
! 0. Checking the consistency and validity of input arguments
if (nrhs /= 5_c_int) then
call mexErrMsgTxt("Must have 5 input arguments")
end if
if (nlhs > 1_c_int) then
call mexErrMsgTxt("Too many output arguments")
end if
do i=1,5
if (.not. (c_associated(prhs(i)) .and. mxIsDouble(prhs(i)) .and. &
(.not. mxIsComplex(prhs(i))) .and. (.not. mxIsSparse(prhs(i))))) then
write (num2str,"(i2)") i
call mexErrMsgTxt("Argument " // trim(num2str) // " should be a real dense matrix")
end if
end do
r = int(mxGetM(prhs(1))) ! Number of states
n = int(mxGetN(prhs(3))) ! Number of observables
if ((r /= mxGetN(prhs(1))) & ! Number of columns of P
&.or. (r /= mxGetM(prhs(2))) & ! Number of lines of T
&.or. (r /= mxGetN(prhs(2))) & ! Number of columns of T
&.or. (r /= mxGetM(prhs(3))) & ! Number of lines of K
&.or. (n /= mxGetM(prhs(4))) & ! Number of lines of Z
&.or. (r /= mxGetN(prhs(4))) & ! Number of columns of Z
&.or. (r /= mxGetM(prhs(5))) & ! Number of lines of Q
&.or. (r /= mxGetN(prhs(5))) & ! Number of columns of Q
) then
call mexErrMsgTxt("Input dimension mismatch")
end if
! 1. Storing the relevant information in Fortran format
P(1:r,1:r) => mxGetPr(prhs(1))
T(1:r,1:r) => mxGetPr(prhs(2))
K(1:r,1:n) => mxGetPr(prhs(3))
Z(1:n,1:r) => mxGetPr(prhs(4))
Q(1:r,1:r) => mxGetPr(prhs(5))
plhs(1) = mxCreateDoubleMatrix(int(r, mwSize), int(r, mwSize), mxREAL)
Pnew(1:r, 1:r) => mxGetPr(plhs(1))
! 2. Computing the Riccati update of the P matrix
allocate(tmp1(r,r), tmp2(r,r))
! Pnew <- Q
Pnew = Q
! tmp1 <- K*Z
call matmul_add("N", "N", 1._real64, K, Z, 0._real64, tmp1)
! tmp2 <- P
tmp2 = P
! tmp2 <- tmp2 - tmp1*P
call matmul_add("N", "N", -1._real64, tmp1, P, 1._real64, tmp2)
! tmp1 <- T*tmp2
call matmul_add("N", "N", 1._real64, T, tmp2, 0._real64, tmp1)
! Pnew <- tmp1*T' + Pnew
call matmul_add("N", "T", 1._real64, tmp1, T, 1._real64, Pnew)
end subroutine mexFunction

View File

@ -2,7 +2,7 @@
** **
** Pseudo code of the algorithm is given at http://home.online.no/~pjacklam/notes/invnorm ** Pseudo code of the algorithm is given at http://home.online.no/~pjacklam/notes/invnorm
** **
** Copyright © 2010-2024 Dynare Team ** Copyright © 2010-2023 Dynare Team
** **
** This file is part of Dynare. ** This file is part of Dynare.
** **
@ -104,8 +104,9 @@ icdf(const T uniform)
return gaussian; return gaussian;
} }
template<typename T>
void void
icdfm(int n, auto* U) icdfm(int n, T* U)
{ {
#pragma omp parallel for #pragma omp parallel for
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
@ -113,8 +114,9 @@ icdfm(int n, auto* U)
return; return;
} }
template<typename T>
void void
icdfmSigma(int d, int n, auto* U, const double* LowerCholSigma) icdfmSigma(int d, int n, T* U, const double* LowerCholSigma)
{ {
double one = 1.0; double one = 1.0;
double zero = 0.0; double zero = 0.0;
@ -126,8 +128,9 @@ icdfmSigma(int d, int n, auto* U, const double* LowerCholSigma)
copy_n(tmp.begin(), d * n, U); copy_n(tmp.begin(), d * n, U);
} }
template<typename T>
void void
usphere(int d, int n, auto* U) usphere(int d, int n, T* U)
{ {
icdfm(n * d, U); icdfm(n * d, U);
#pragma omp parallel for #pragma omp parallel for
@ -144,8 +147,9 @@ usphere(int d, int n, auto* U)
} }
} }
template<typename T>
void void
usphereRadius(int d, int n, double radius, auto* U) usphereRadius(int d, int n, double radius, T* U)
{ {
icdfm(n * d, U); icdfm(n * d, U);
#pragma omp parallel for #pragma omp parallel for

@ -1 +1 @@
Subproject commit d8866fbec8a09df0d8fa1d2e7e60b2aae8685ea8 Subproject commit 20acdbc119648f8ae6438e7f3a18943b4c23e7d2

View File

@ -1,87 +0,0 @@
source_dir = getenv('source_root');
addpath([source_dir filesep 'matlab']);
dynare_config;
testFailed = 0;
skipline()
disp('*** TESTING: riccatiupdate.m ***');
t0 = clock;
% Set the number of experiments for time measurement
N = 5000;
% Set the dimension of the problem to be solved.
r = 50;
n = 100;
tol = 1e-15;
% Set the input arguments
% P, Q: use the fact that for any real matrix A, A'*A is positive semidefinite
P = rand(n,r);
P = P'*P;
Q = rand(n,r);
Q = Q'*Q;
K = rand(r,n);
Z = rand(n,r);
T = rand(r,r);
% Computing an upperbound for the norm the updated variance-covariance matrix
ub = norm(T,1)^2*norm(P,1)*(1+norm(K*Z,1))+norm(Q,1);
% Weighting the P and Q matrices to keep the norm of the variance-covariance matrix below 1
P = 0.5*P/ub;
Q = 0.5*Q/ub;
% 1. Update the state vairance-covariance matrix with Matlab
tElapsed1 = 0.;
tic;
for i=1:N
Ptmp_matlab = T*(P-K*Z*P)*transpose(T)+Q;
end
tElapsed1 = toc;
disp(['Elapsed time for the Matlab Riccati update is: ' num2str(tElapsed1) ' (N=' int2str(N) ').'])
% 2. Update the state varance-covariance matrix with the mex routine
tElapsed2 = 0.;
Ptmp_fortran = P;
try
tic;
for i=1:N
Ptmp_fortran = riccati_update(P, T, K, Z, Q);
end
tElapsed2 = toc;
disp(['Elapsed time for the Fortran Riccati update is: ' num2str(tElapsed2) ' (N=' int2str(N) ').'])
R = norm(Ptmp_fortran-Ptmp_matlab,1);
if (R > tol)
testFailed = testFailed+1;
dprintf('The Fortran Riccati update is wrong')
end
catch
testFailed = testFailed+1;
dprintf('Fortran Riccati update failed')
end
% Compare the Fortran and Matlab execution time
if tElapsed1<tElapsed2
skipline()
dprintf('Matlab Riccati update is %5.2f times faster than its Fortran counterpart.', tElapsed2/tElapsed1)
skipline()
else
skipline()
dprintf('Fortran Riccati update is %5.2f times faster than its Matlab counterpart.', tElapsed1/tElapsed2)
skipline()
end
% Compare results after multiple calls
N = 50;
disp(['After 1 update using the Riccati formula, the norm-1 discrepancy is ' num2str(norm(Ptmp_fortran-Ptmp_matlab,1)) '.']);
for i=2:N
Ptmp_matlab = T*(Ptmp_matlab-K*Z*Ptmp_matlab)*transpose(T)+Q;
Ptmp_fortran = riccati_update(Ptmp_fortran, T, K, Z, Q);
disp(['After ' int2str(i) ' updates using the Riccati formula, the norm-1 discrepancy is ' num2str(norm(Ptmp_fortran-Ptmp_matlab,1)) '.'])
end
t1 = clock;
fprintf('\n*** Elapsed time (in seconds): %.1f\n\n', etime(t1, t0));
quit(testFailed > 0)

View File

@ -1,4 +1,4 @@
# Copyright © 2017-2024 Dynare Team # Copyright © 2017-2023 Dynare Team
# #
# This file is part of Dynare. # This file is part of Dynare.
# #
@ -49,7 +49,7 @@ clean-all: clean-lib clean-src clean-tar
tarballs/slicot-$(SLICOT_VERSION).tar.gz: tarballs/slicot-$(SLICOT_VERSION).tar.gz:
mkdir -p tarballs mkdir -p tarballs
wget $(WGET_OPTIONS) -O $@ https://deb.debian.org/debian/pool/main/s/slicot/slicot_$(SLICOT_VERSION).orig.tar.xz wget $(WGET_OPTIONS) -O $@ https://deb.debian.org/debian/pool/main/s/slicot/slicot_$(SLICOT_VERSION).orig.tar.gz
sources64/slicot-$(SLICOT_VERSION)-with-64bit-integer: tarballs/slicot-$(SLICOT_VERSION).tar.gz sources64/slicot-$(SLICOT_VERSION)-with-64bit-integer: tarballs/slicot-$(SLICOT_VERSION).tar.gz
rm -rf sources64/slicot-*-with-64bit-integer rm -rf sources64/slicot-*-with-64bit-integer
@ -64,13 +64,13 @@ sources64/slicot-$(SLICOT_VERSION)-with-32bit-integer-and-underscore: tarballs/s
touch $@ touch $@
lib64/Slicot/without-underscore/libslicot64_pic.a: sources64/slicot-$(SLICOT_VERSION)-with-64bit-integer lib64/Slicot/without-underscore/libslicot64_pic.a: sources64/slicot-$(SLICOT_VERSION)-with-64bit-integer
make -C $< -f makefile_Unix lib SLICOTLIB=../libslicot64_pic.a OPTS="$(FFLAGS) -fno-underscoring -fdefault-integer-8" FORTRAN=x86_64-w64-mingw32-gfortran LOADER=x86_64-w64-mingw32-gfortran ARCH=x86_64-w64-mingw32-ar make -C $< lib SLICOTLIB=../libslicot64_pic.a OPTS="$(FFLAGS) -fno-underscoring -fdefault-integer-8" FORTRAN=x86_64-w64-mingw32-gfortran LOADER=x86_64-w64-mingw32-gfortran ARCH=x86_64-w64-mingw32-ar
x86_64-w64-mingw32-strip --strip-debug $</libslicot64_pic.a x86_64-w64-mingw32-strip --strip-debug $</libslicot64_pic.a
mkdir -p $(dir $@) mkdir -p $(dir $@)
cp $</libslicot64_pic.a $@ cp $</libslicot64_pic.a $@
lib64/Slicot/with-underscore/libslicot_pic.a: sources64/slicot-$(SLICOT_VERSION)-with-32bit-integer-and-underscore lib64/Slicot/with-underscore/libslicot_pic.a: sources64/slicot-$(SLICOT_VERSION)-with-32bit-integer-and-underscore
make -C $< -f makefile_Unix lib SLICOTLIB=../libslicot_pic.a OPTS="$(FFLAGS)" FORTRAN=x86_64-w64-mingw32-gfortran LOADER=x86_64-w64-mingw32-gfortran ARCH=x86_64-w64-mingw32-ar make -C $< lib SLICOTLIB=../libslicot_pic.a OPTS="$(FFLAGS)" FORTRAN=x86_64-w64-mingw32-gfortran LOADER=x86_64-w64-mingw32-gfortran ARCH=x86_64-w64-mingw32-ar
x86_64-w64-mingw32-strip --strip-debug $</libslicot_pic.a x86_64-w64-mingw32-strip --strip-debug $</libslicot_pic.a
mkdir -p $(dir $@) mkdir -p $(dir $@)
cp $</libslicot_pic.a $@ cp $</libslicot_pic.a $@
@ -158,7 +158,7 @@ mingw64: tarballs/mingw-w64-x86_64-gcc-$(MINGW64_GCC_VERSION)-any.pkg.tar.zst ta
tarballs/mingw-w64-x86_64-%-any.pkg.tar.zst: tarballs/mingw-w64-x86_64-%-any.pkg.tar.zst:
mkdir -p tarballs mkdir -p tarballs
wget $(WGET_OPTIONS) -O $@ http://repo.msys2.org/mingw/x86_64/$(notdir $@) wget $(WGET_OPTIONS) -O $@ https://www.dynare.org/windows-pkg-build/msys2/6.x/$(notdir $@)
clean-msys2: clean-msys2:
rm -rf lib64-msys2 rm -rf lib64-msys2

View File

@ -1,4 +1,4 @@
SLICOT_VERSION = 5.9~20240205.gita037f7e SLICOT_VERSION = 5.0+20101122
X13AS_VERSION = 1-1-b60 X13AS_VERSION = 1-1-b60
OCTAVE_VERSION = 8.4.0 OCTAVE_VERSION = 8.4.0