Compare commits
1 Commits
master
...
conditiona
Author | SHA1 | Date |
---|---|---|
Stéphane Adjemian (Ryûk) | 68fb35be24 |
|
@ -1,27 +0,0 @@
|
|||
# NB: whenever the present file is modified, the same modification should be
|
||||
# applied to the copy in preprocessor.git
|
||||
|
||||
# For general information about our coding style, and the specific version
|
||||
# of clang-format used, see:
|
||||
# https://git.dynare.org/Dynare/dynare/-/wikis/CodingGuidelines#c-code
|
||||
# For the list of options of clang-format, see:
|
||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
# Effective configuration can be obtained with:
|
||||
# clang-format --dump-config
|
||||
Language: Cpp
|
||||
Standard: c++20
|
||||
ColumnLimit: 100
|
||||
BasedOnStyle: GNU
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: AfterColon
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: false
|
||||
IndentPPDirectives: AfterHash
|
||||
PackConstructorInitializers: NextLine
|
||||
PPIndentWidth: 1
|
||||
PointerAlignment: Left
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeCpp11BracedList: true
|
|
@ -1,8 +0,0 @@
|
|||
# NB: to use clang-tidy on the MEX source code, make sure that you have
|
||||
# libomp-dev installed (the LLVM implementation of OpenMP)
|
||||
|
||||
# TODO: add the following check families:
|
||||
# - bugprone-*
|
||||
# - cppcoreguidelines-
|
||||
|
||||
Checks: 'performance-*,modernize-*,-modernize-use-trailing-return-type,-clang-diagnostic-unqualified-std-cast-call'
|
|
@ -1,8 +1,6 @@
|
|||
((c-mode . ((indent-tabs-mode . nil)
|
||||
(fill-column . 100)
|
||||
(c-file-style . "gnu")))
|
||||
(c++-mode . ((indent-tabs-mode . nil)
|
||||
(fill-column . 100)
|
||||
(c-file-style . "gnu")))
|
||||
(makefile-mode . ((indent-tabs-mode . t)))
|
||||
(octave-mode . ((indent-tabs-mode . nil)
|
||||
|
|
|
@ -1,35 +1,159 @@
|
|||
# For checking that no file has been unduly ignored, run:
|
||||
# $ git ls-files -i -c --exclude-per-directory=.gitignore
|
||||
# $ git ls-files -i --exclude-per-directory=.gitignore
|
||||
# Any file that is displayed should be removed from the ignore list
|
||||
# (possibly by an exclusion rule beginning with an exclamation mark)
|
||||
|
||||
# Generic ignore rules
|
||||
*~
|
||||
*.o
|
||||
*.a
|
||||
*.fig
|
||||
\#*\#
|
||||
TAGS
|
||||
*.mat
|
||||
|
||||
# Created when building the reference manual
|
||||
# Build system rules
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
confdefs.h
|
||||
configure
|
||||
config.log
|
||||
config.status
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.guess
|
||||
config.sub
|
||||
depcomp
|
||||
install-sh
|
||||
/missing
|
||||
/mex/build/matlab/missing
|
||||
/mex/build/octave/missing
|
||||
/compile
|
||||
/mex/build/matlab/compile
|
||||
/mex/build/octave/compile
|
||||
ylwrap
|
||||
ar-lib
|
||||
|
||||
# checksum associated with fast option
|
||||
checksum
|
||||
|
||||
# Make Check Rules
|
||||
*.trs
|
||||
*.tls
|
||||
|
||||
# Doc rules
|
||||
*.pdf
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
*.toc
|
||||
*.idx
|
||||
*.scn
|
||||
*.nav
|
||||
*.snm
|
||||
*.vrb
|
||||
*.bbl
|
||||
*.blg
|
||||
*.lof
|
||||
/doc/manual/build
|
||||
/doc/manual/utils/version.py
|
||||
/doc/manual/utils/__pycache__/*
|
||||
!/doc/guide.bbl
|
||||
!/doc/parallel/AvenueParadigm.pdf
|
||||
!/doc/parallel/iVaNo_*.pdf
|
||||
!/doc/parallel/netbook_*.pdf
|
||||
!/doc/parallel/quest_*.pdf
|
||||
!/doc/parallel/RWMH_quest1_*.pdf
|
||||
!/doc/parallel/waitbars*.pdf
|
||||
doc/internals/*.html
|
||||
doc/internals/ltxpng
|
||||
|
||||
# Created by the Windows package build script
|
||||
/windows/deps/lib64/
|
||||
/windows/deps/lib64-msys2/
|
||||
/windows/deps/matlab64/
|
||||
/windows/deps/mingw64/
|
||||
/windows/deps/octave64/
|
||||
/windows/deps/sources64/
|
||||
/windows/deps/tarballs/
|
||||
/windows/exe/
|
||||
/windows/7z/
|
||||
/windows/zip/
|
||||
# MATLAB dir
|
||||
/matlab/preprocessor64/
|
||||
/matlab/supported_octave_version.m
|
||||
/matlab/dynare_version.m
|
||||
|
||||
# Created by the macOS package build script
|
||||
/macOS/deps/arm64/sources64/
|
||||
/macOS/deps/x86_64/sources64/
|
||||
/macOS/deps/tarballs/
|
||||
/macOS/deps/arm64/lib64/
|
||||
/macOS/deps/x86_64/lib64/
|
||||
build-doc
|
||||
# DLL rules
|
||||
*.mex
|
||||
*.oct
|
||||
*.mexglx
|
||||
*.mexa64
|
||||
*.mexw32
|
||||
*.mexw64
|
||||
*.mexmaci
|
||||
*.mexmaci64
|
||||
/mex/matlab/
|
||||
/mex/octave/
|
||||
|
||||
# Symbolic links created for building MEX files
|
||||
/mex/build/matlab/*/*.c
|
||||
/mex/build/matlab/*/*.cc
|
||||
/mex/build/matlab/*/*.f08
|
||||
/mex/build/matlab/*/*.F08
|
||||
/mex/build/octave/*/*.c
|
||||
/mex/build/octave/*/*.cc
|
||||
/mex/build/octave/*/*.f08
|
||||
/mex/build/octave/*/*.F08
|
||||
|
||||
# Fortran modules
|
||||
/mex/build/matlab/*/*.mod
|
||||
/mex/build/octave/*/*.mod
|
||||
|
||||
# Extra rules for trust_region MEX testfiles
|
||||
/mex/sources/block_trust_region/test/*.mod
|
||||
/mex/sources/block_trust_region/test/dulmage_mendelsohn_test
|
||||
/mex/sources/block_trust_region/test/trust_region_test
|
||||
!/mex/sources/block_trust_region/test/Makefile
|
||||
|
||||
# Windows
|
||||
!/windows/Makefile
|
||||
!/windows/deps/Makefile
|
||||
windows/deps/lib32/
|
||||
windows/deps/lib64/
|
||||
windows/deps/lib32-msys2/
|
||||
windows/deps/lib64-msys2/
|
||||
windows/deps/matlab32/
|
||||
windows/deps/matlab64/
|
||||
windows/deps/mingw32/
|
||||
windows/deps/mingw64/
|
||||
windows/deps/octave32/
|
||||
windows/deps/octave64/
|
||||
windows/deps/sources32/
|
||||
windows/deps/sources64/
|
||||
windows/deps/tarballs/
|
||||
windows/exe/
|
||||
windows/7z/
|
||||
windows/zip/
|
||||
|
||||
# MacOS stuff
|
||||
.DS_Store
|
||||
macOS/pkg/
|
||||
macOS/deps/sources64/
|
||||
macOS/deps/tarballs/
|
||||
macOS/deps/lib64/
|
||||
|
||||
# Emacs stuff
|
||||
TAGS
|
||||
scripts/dynare.elc
|
||||
|
||||
# MS-Sbvar
|
||||
/contrib/ms-sbvar/*.prn
|
||||
/contrib/ms-sbvar/*.dat
|
||||
/contrib/ms-sbvar/sbvar_commandline
|
||||
/contrib/ms-sbvar/sbvar_init_file
|
||||
!/contrib/ms-sbvar/Makefile
|
||||
/tests/ms-sbvar/*.tmp
|
||||
|
||||
# Reporting
|
||||
*synctex.gz
|
||||
tests/reporting/tmpRepDir
|
||||
|
||||
# Julia Tests
|
||||
tests/julia/rbc/rbc*.jl
|
||||
|
||||
# Octave variables saved when Octave crashes
|
||||
octave-workspace
|
||||
|
||||
# VERSION generated file
|
||||
VERSION
|
||||
|
||||
matlab/supported_octave_version.m
|
||||
|
|
209
.gitlab-ci.yml
209
.gitlab-ci.yml
|
@ -1,99 +1,83 @@
|
|||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
TERM: linux
|
||||
MATLAB_VERSION: R2023b
|
||||
OLD_MATLAB_VERSION: R2018b
|
||||
# To ensure that "false && true" fails, see https://gitlab.com/gitlab-org/gitlab-runner/-/issues/25394#note_412609647
|
||||
FF_ENABLE_BASH_EXIT_CODE_CHECK: 'true'
|
||||
MATLAB_VERSION: R2022b
|
||||
OLD_MATLAB_VERSION: R2014a
|
||||
OCTAVE_VERSION: 7.3.0
|
||||
|
||||
# The next stanza creates the version number used for the source tarball and the
|
||||
# binary packages. Here are the following possible cases:
|
||||
# - if VERSION was already set (when manually running a pipeline), use it
|
||||
# - if we are in the official Dynare repository:
|
||||
# + if on a tag: use the tag
|
||||
# + if on master: use 7-unstable-$TIMESTAMP-$COMMIT
|
||||
# + if on master: use 6-unstable-$TIMESTAMP-$COMMIT
|
||||
# + on another branch: use $BRANCH-$TIMESTAMP-$COMMIT
|
||||
# - if in a personal repository: use $USER-$TIMESTAMP-$COMMIT
|
||||
before_script:
|
||||
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ -n $CI_COMMIT_TAG ]]; then export VERSION=$CI_COMMIT_TAG; fi'
|
||||
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ $CI_COMMIT_REF_NAME == master ]]; then export VERSION=7-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
|
||||
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]]; then export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
|
||||
- 'if [[ -z $VERSION ]]; then export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
|
||||
- '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ -n $CI_COMMIT_TAG ]] && export VERSION=$CI_COMMIT_TAG'
|
||||
- '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ $CI_COMMIT_REF_NAME == master ]] && export VERSION=6-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA'
|
||||
- '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA'
|
||||
- '[[ -z $VERSION ]] && export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA'
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- pkg
|
||||
- sign
|
||||
- deploy
|
||||
|
||||
build_matlab:
|
||||
build_binaries:
|
||||
stage: build
|
||||
script:
|
||||
- meson setup -Dbuild_for=matlab -Dmatlab_path=/opt/MATLAB/$MATLAB_VERSION -Dbuildtype=release build-matlab
|
||||
- meson compile -v -C build-matlab
|
||||
- autoreconf -si
|
||||
- ./configure --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION --with-octave=/usr/local/octave/$OCTAVE_VERSION PACKAGE_VERSION=$VERSION PACKAGE_STRING="dynare $VERSION"
|
||||
- make -j $(nproc) LN_S="cp -p"
|
||||
artifacts:
|
||||
paths:
|
||||
- build-matlab/
|
||||
expire_in: 3 days
|
||||
|
||||
build_octave:
|
||||
stage: build
|
||||
script:
|
||||
- meson setup -Dbuild_for=octave -Dbuildtype=release build-octave
|
||||
- meson compile -v -C build-octave
|
||||
artifacts:
|
||||
paths:
|
||||
- build-octave/
|
||||
- preprocessor/dynare-preprocessor
|
||||
- mex/octave/
|
||||
- mex/matlab/
|
||||
expire_in: 3 days
|
||||
|
||||
build_doc:
|
||||
stage: build
|
||||
script:
|
||||
- meson rewrite kwargs set project / version "$VERSION"
|
||||
# Use a local copy of MathJax to avoid using CDN (which are a privacy issue)
|
||||
# NB: Debian 12 “Bookworm” has MathJax 2. The following needs to be updated
|
||||
# when Debian moves to MathJax 3.
|
||||
- meson setup -Dbuild_for=octave -Dmathjax_path=mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML build-doc
|
||||
- meson compile -v -C build-doc doc
|
||||
- cp -dR /usr/share/javascript/mathjax build-doc/dynare-manual.html/_static/
|
||||
- autoreconf -si
|
||||
- ./configure --disable-matlab --disable-octave PACKAGE_VERSION=$VERSION PACKAGE_STRING="dynare $VERSION"
|
||||
- make -j $(nproc) pdf html
|
||||
artifacts:
|
||||
paths:
|
||||
- build-doc/
|
||||
- doc/manual/build/
|
||||
- doc/**/*.pdf
|
||||
- preprocessor/doc/*/*.pdf
|
||||
expire_in: 3 days
|
||||
|
||||
pkg_source:
|
||||
stage: pkg
|
||||
script:
|
||||
- meson rewrite kwargs set project / version "$VERSION"
|
||||
- git commit -a -m "Source for $VERSION"
|
||||
- meson setup -Dbuild_for=octave build-src
|
||||
- meson dist -C build-src --no-tests
|
||||
- rm doc/manual/source/_static/mathjax && sed -i "/^mathjax_path *=/d" doc/manual/source/conf.py
|
||||
- 'for f in configure.ac preprocessor/configure.ac mex/build/matlab/configure.ac mex/build/octave/configure.ac; do sed -i "s/^AC_INIT(\[\(.*\)\],\s*\[\(.*\)\])/AC_INIT([\1], [$VERSION])/" $f; done'
|
||||
- autoreconf -si
|
||||
- ./configure --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION --with-octave=/usr/local/octave/$OCTAVE_VERSION
|
||||
- make dist
|
||||
artifacts:
|
||||
paths:
|
||||
- build-src/meson-dist/dynare-*.tar.xz
|
||||
- dynare-*.tar.xz
|
||||
expire_in: 3 days
|
||||
needs: []
|
||||
|
||||
pkg_windows:
|
||||
stage: pkg
|
||||
script:
|
||||
- meson rewrite kwargs set project / version "$VERSION"
|
||||
- mkdir -p windows/deps/tarballs && cp /usr/lib/dynare-runner/matlab64-* windows/deps/tarballs/
|
||||
- ln -s ~/tarballs windows/deps/
|
||||
- make -C windows
|
||||
- rm windows/deps/tarballs/matlab64-* # No need to cache these files
|
||||
cache:
|
||||
- key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- windows/deps/sources64/
|
||||
- windows/deps/lib64/
|
||||
# We do not cache lib64-msys2, mingw64, octave64 and
|
||||
# matlab64, because those are simply extracted from a tarball. It
|
||||
# would be a waste of space and of (re-compression) time.
|
||||
- key: $CI_JOB_NAME
|
||||
# This cache is shared between all branches, to save space
|
||||
paths:
|
||||
- windows/deps/tarballs/
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- windows/deps/sources64/
|
||||
- windows/deps/lib64/
|
||||
# We do not cache lib64-msys2, mingw64, octave64 and
|
||||
# matlab64, because those are simply extracted from a tarball. It
|
||||
# would be a waste of space and of (re-compression) time.
|
||||
artifacts:
|
||||
paths:
|
||||
- windows/exe/*
|
||||
|
@ -102,18 +86,16 @@ pkg_windows:
|
|||
expire_in: 3 days
|
||||
needs: [ "build_doc" ]
|
||||
|
||||
pkg_macOS_x86_64:
|
||||
pkg_macOS:
|
||||
stage: pkg
|
||||
script:
|
||||
# Enforce the arm64 meson for rewrite, as a workaround to https://github.com/mesonbuild/meson/issues/12282
|
||||
- env PATH="/opt/homebrew/bin:$PATH" meson rewrite kwargs set project / version "$VERSION"
|
||||
- ln -s ~/tarballs macOS/deps/x86_64
|
||||
- make -C macOS build-x86_64
|
||||
- ln -s ~/tarballs macOS/deps/
|
||||
- make -C macOS
|
||||
cache:
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- macOS/deps/x86_64/sources64/
|
||||
- macOS/deps/x86_64/lib64/
|
||||
- macOS/deps/sources64/
|
||||
- macOS/deps/lib64/
|
||||
tags:
|
||||
- macOS
|
||||
artifacts:
|
||||
|
@ -122,46 +104,32 @@ pkg_macOS_x86_64:
|
|||
expire_in: 3 days
|
||||
needs: [ "build_doc" ]
|
||||
|
||||
pkg_macOS_arm64:
|
||||
stage: pkg
|
||||
script:
|
||||
# Enforce the arm64 meson for rewrite, as a workaround to https://github.com/mesonbuild/meson/issues/12282
|
||||
- env PATH="/opt/homebrew/bin:$PATH" meson rewrite kwargs set project / version "$VERSION"
|
||||
- ln -s ~/tarballs macOS/deps/arm64
|
||||
- make -C macOS build-arm64
|
||||
cache:
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- macOS/deps/arm64/sources64/
|
||||
- macOS/deps/arm64/lib64/
|
||||
tags:
|
||||
- macOS
|
||||
.test_matlab_template:
|
||||
stage: test
|
||||
artifacts:
|
||||
paths:
|
||||
- macOS/pkg/*
|
||||
expire_in: 3 days
|
||||
needs: [ "build_doc" ]
|
||||
- tests/**/*.m.log
|
||||
- tests/**/*.m.trs
|
||||
- tests/**/*.jnl
|
||||
- tests/run_test_matlab_output.txt
|
||||
when: always
|
||||
needs: [ "build_binaries" ]
|
||||
|
||||
test_matlab:
|
||||
stage: test
|
||||
extends: .test_matlab_template
|
||||
script:
|
||||
- meson test -C build-matlab --no-rebuild --num-processes $(($(nproc) * 3 / 4))
|
||||
artifacts:
|
||||
paths:
|
||||
- build-matlab/meson-logs/testlog.txt
|
||||
when: always
|
||||
needs: [ "build_matlab" ]
|
||||
- autoreconf -si
|
||||
- ./configure --disable-octave --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION
|
||||
- make -j $(($(nproc) * 3 / 4)) -C tests check-matlab
|
||||
|
||||
test_old_matlab:
|
||||
stage: test
|
||||
extends: .test_matlab_template
|
||||
script:
|
||||
- meson setup -Dbuild_for=matlab -Dmatlab_path=/opt/MATLAB/$OLD_MATLAB_VERSION -Dbuildtype=release build-old-matlab
|
||||
- meson compile -v -C build-old-matlab
|
||||
- meson test -C build-old-matlab --num-processes $(($(nproc) * 3 / 4))
|
||||
artifacts:
|
||||
paths:
|
||||
- build-old-matlab/meson-logs/testlog.txt
|
||||
when: always
|
||||
- autoreconf -si
|
||||
- ./configure --disable-octave --with-matlab=/usr/local/MATLAB/$OLD_MATLAB_VERSION
|
||||
- make -C mex/build/matlab clean
|
||||
- make -j $(nproc) -C mex/build/matlab
|
||||
- make -j $(($(nproc) * 3 / 4)) -C tests check-matlab
|
||||
when: manual
|
||||
|
||||
test_octave:
|
||||
|
@ -169,41 +137,22 @@ test_octave:
|
|||
variables:
|
||||
OPENBLAS_NUM_THREADS: 1
|
||||
script:
|
||||
- meson test -C build-octave --no-rebuild
|
||||
- autoreconf -si
|
||||
- ./configure --disable-matlab --with-octave=/usr/local/octave/$OCTAVE_VERSION
|
||||
- make -j $(nproc) -C tests check-octave
|
||||
artifacts:
|
||||
paths:
|
||||
- build-octave/meson-logs/testlog.txt
|
||||
- tests/**/*.o.log
|
||||
- tests/**/*.o.trs
|
||||
- tests/**/*.jnl
|
||||
- tests/run_test_octave_output.txt
|
||||
when: always
|
||||
needs: [ "build_octave" ]
|
||||
needs: [ "build_binaries" ]
|
||||
when: manual
|
||||
|
||||
test_clang_format:
|
||||
stage: test
|
||||
script:
|
||||
- meson setup -Dbuild_for=octave build-clang-format
|
||||
- ninja -C build-clang-format clang-format-check
|
||||
needs: []
|
||||
|
||||
# For the sign and deploy jobs, we don’t use the “needs” keyword, since we
|
||||
# don’t want those jobs to start before the “test” and “pkg” stages have
|
||||
# succeeded. Hence we stick to the “dependencies” keyword.
|
||||
|
||||
sign_windows:
|
||||
stage: sign
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_REF_NAME == "master"'
|
||||
when: on_success
|
||||
- when: never
|
||||
tags:
|
||||
- sign
|
||||
dependencies:
|
||||
- pkg_windows
|
||||
script:
|
||||
- f=(windows/exe/*) && mkdir -p windows/exe-signed/ && osslsigncode sign -pkcs11module /usr/lib/x86_64-linux-gnu/libykcs11.so.2 -key "pkcs11:id=%01;type=private;pin-value=$YUBIKEY_PIN" -certs ~/cepremap-code-signing-comodo-sectigo.pem -n Dynare -i https://www.dynare.org -t http://timestamp.comodoca.com -in ${f[0]} -out windows/exe-signed/${f[0]##*/}
|
||||
artifacts:
|
||||
paths:
|
||||
- windows/exe-signed/*
|
||||
expire_in: 3 days
|
||||
# For the deploy jobs, we don’t use the “needs” keyword, since we don’t want
|
||||
# those jobs to start before the “test” and “pkg” stages have succeeded. Hence
|
||||
# we stick to the “dependencies” keyword.
|
||||
|
||||
deploy_manual_unstable:
|
||||
stage: deploy
|
||||
|
@ -212,11 +161,13 @@ deploy_manual_unstable:
|
|||
when: on_success
|
||||
- when: never
|
||||
tags:
|
||||
- deploy
|
||||
- restricted
|
||||
dependencies:
|
||||
- build_doc
|
||||
script:
|
||||
- rsync --recursive --links --delete build-doc/dynare-manual.html/ /srv/www.dynare.org/manual-unstable/
|
||||
- rm -rf doc/manual/build/html/_static/mathjax
|
||||
- ln -s /usr/share/javascript/mathjax doc/manual/build/html/_static/mathjax
|
||||
- rsync --recursive --links --delete doc/manual/build/html/ /srv/www.dynare.org/manual-unstable/
|
||||
|
||||
deploy_snapshot_unstable:
|
||||
stage: deploy
|
||||
|
@ -225,19 +176,17 @@ deploy_snapshot_unstable:
|
|||
when: on_success
|
||||
- when: never
|
||||
tags:
|
||||
- deploy
|
||||
- restricted
|
||||
dependencies:
|
||||
- pkg_source
|
||||
- pkg_windows
|
||||
- sign_windows
|
||||
- pkg_macOS_arm64
|
||||
- pkg_macOS_x86_64
|
||||
- pkg_macOS
|
||||
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
|
||||
- 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
|
||||
- f=(windows/exe/*) && osslsigncode sign -pkcs12 ~/cepremap-comodo-sectigo-code-signing.p12 -n Dynare -i https://www.dynare.org -t http://timestamp.comodoca.com -in ${f[0]} -out ${f[0]}.signed && mv ${f[0]}.signed ${f[0]}
|
||||
- cp *.tar.xz /srv/www.dynare.org/snapshot/source/ && ln -sf *.tar.xz /srv/www.dynare.org/snapshot/source/dynare-latest-src.tar.xz
|
||||
- f=(windows/exe/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows/dynare-latest-win.exe
|
||||
- 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
|
||||
- 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
|
||||
- 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
|
||||
- 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
|
||||
- f=(macOS/pkg/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/macos/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/macos/dynare-latest-macos.pkg
|
||||
- ~/update-snapshot-list.sh
|
||||
- curl -X POST -F token="$WEBSITE_PIPELINE_TRIGGER_TOKEN" -F ref=master https://git.dynare.org/api/v4/projects/40/trigger/pipeline
|
||||
|
|
|
@ -10,10 +10,19 @@
|
|||
[submodule "matlab/utilities/tests"]
|
||||
path = matlab/utilities/tests
|
||||
url = ../../Dynare/m-unit-tests.git
|
||||
[submodule "matlab/particles"]
|
||||
path = matlab/particles
|
||||
url = ../../Dynare/particles.git
|
||||
[submodule "matlab/modules/dseries"]
|
||||
path = matlab/dseries
|
||||
path = matlab/modules/dseries
|
||||
url = ../../Dynare/dseries.git
|
||||
branch = master
|
||||
[submodule "matlab/modules/reporting"]
|
||||
path = matlab/modules/reporting
|
||||
url = ../../Dynare/reporting.git
|
||||
[submodule "contrib/jsonlab"]
|
||||
path = contrib/jsonlab
|
||||
url = https://github.com/fangq/jsonlab.git
|
||||
[submodule "preprocessor"]
|
||||
path = preprocessor
|
||||
url = ../../Dynare/preprocessor.git
|
||||
|
|
|
@ -2,29 +2,31 @@
|
|||
|
||||
## Introduction
|
||||
|
||||
Hello from the Dynare Team! We’re happy you’re on this page because hopefully that means you’re thinking of getting directly involved with the Dynare project. Herein, we outline how you can contribute to Dynare. Please read this document all the way through before contributing.
|
||||
Hello from the Dynare Team! We're happy you're on this page because hopefully that means you're thinking of getting directly involved with the Dynare project. Herein, we outline how you can contribute to Dynare. Please read this document all the way through before contributing.
|
||||
|
||||
Please follow the steps in the sections below in order. Note that, though we’d love for you to contribute code, you don’t need to be a programmer to contribute to Dynare. You can report bugs, ask for enhancements, fix typos in the manual, contribute tests to the test suite, or do something we haven’t thought of yet!
|
||||
Please follow the steps in the sections below in order. Note that, though we'd love for you to contribute code, you don't need to be a programmer to contribute to Dynare. You can report bugs, ask for enhancements, fix typos in the manual, contribute tests to the test suite, or do something we haven't thought of yet!
|
||||
|
||||
If something is not clear, don’t hesitate to ask if you can’t find the answer online. You can contact us directly at [dev@dynare.org](mailto:dev@dynare.org).
|
||||
If something is not clear, don't hesitate to ask if you can't find the answer online. You can contact us directly at [dev@dynare.org](mailto:dev@dynare.org).
|
||||
|
||||
Please note that the repositories under the purview of this page are:
|
||||
|
||||
* [Dynare](https://git.dynare.org/Dynare/dynare)
|
||||
* [Preprocessor](https://git.dynare.org/Dynare/preprocessor)
|
||||
* [Particles](https://git.dynare.org/Dynare/particles)
|
||||
* [Dseries](https://git.dynare.org/Dynare/dseries)
|
||||
* [Reporting](https://git.dynare.org/Dynare/reporting)
|
||||
* [Testsuite](https://git.dynare.org/Dynare/testsuite)
|
||||
* [M-unit-tests](https://git.dynare.org/Dynare/m-unit-tests)
|
||||
|
||||
## Making your Intentions Known
|
||||
|
||||
Before making changes to the codebase, it’d be helpful if you communicated your intentions with us. This will avoid double work and ensure that you don’t contribute code that won’t be included in Dynare for one reason or another.
|
||||
Before making changes to the codebase, it'd be helpful if you communicated your intentions with us. This will avoid double work and ensure that you don't contribute code that won't be included in Dynare for one reason or another.
|
||||
|
||||
### Create your account on our GitLab instance
|
||||
|
||||
All the development of Dynare happens in [GitLab](https://about.gitlab.com/), which is an integrated environment for storing code under git, keeping track of issues and milestones, and perform testing. The Dynare Team has its own instance of GitLab.
|
||||
|
||||
In order to work with us, you need to create your account on our GitLab instance on the [register page](https://git.dynare.org/users/sign_in). Note that account requests are manually validated, so be prepared to wait for a couple of hours or days before your account is created; if your account request is rejected, do not hesitate to contact us directly.
|
||||
In order to work with us, you need to create your account on our GitLab instance on the [register page](https://git.dynare.org/users/sign_in).
|
||||
|
||||
You will also need to register your SSH key in your GitLab profile if you want to contribute code.
|
||||
|
||||
|
@ -34,7 +36,7 @@ You can report bugs in both the stable and unstable versions of Dynare. Before r
|
|||
|
||||
To report a bug in Dynare, simply open a Gitlab issue in the repository where the bug resides. For example, to report a bug in Dynare itself, go to the [Dynare repository issue page](https://git.dynare.org/Dynare/dynare/issues) and click on "New Issue."
|
||||
|
||||
The minimal information to add is a subject and a description of the steps needed to reproduce the bug. However, the most helpful description would also provide the code to reproduce the bug (often times a `.mod` file). The most helpful `.mod` file is a minimal, quick-running example that reproduces the bug, but we’ll take anything that will help us squash a bug.
|
||||
The minimal information to add is a subject and a description of the steps needed to reproduce the bug. However, the most helpful description would also provide the code to reproduce the bug (often times a `.mod` file). The most helpful `.mod` file is a minimal, quick-running example that reproduces the bug, but we'll take anything that will help us squash a bug.
|
||||
|
||||
To include short amounts of code, please paste it into the description box, using the appropriate [GitLab Flavored Markdown](https://docs.gitlab.com/ee/user/markdown.html) code. For larger amounds of code like `.mod` files, please create a new [GitLab snippet](https://git.dynare.org/dashboard/snippets) and provide the link in the description box.
|
||||
|
||||
|
@ -42,13 +44,13 @@ To include short amounts of code, please paste it into the description box, usin
|
|||
|
||||
Issues are not only used to report bugs. They are also used to ask for improvements to the codebase or new features to Dynare in general. Please be descriptive when asking for improvements or new features. Links or references to papers or detailed examples are helpful.
|
||||
|
||||
Though our development priorities lay with those who finance Dynare and with what we think may most benefit the Dynare community, this does not mean we are closed to outside ideas for enhancements. On the contrary: we invite them! Moreover, if you are willing to program the enhancement you want, the odds of it being included in Dynare are much higher than if you needed us to do it. That said, it is best to create an issue with an enhancement idea **before** beginning the work. As stated above, this is important to avoid duplication of work and also because we wouldn’t want you to take the time to work on something that would not end up being included in Dynare.
|
||||
Though our development priorities lay with those who finance Dynare and with what we think may most benefit the Dynare community, this does not mean we are closed to outside ideas for enhancements. On the contrary: we invite them! Moreover, if you are willing to program the enhancement you want, the odds of it being included in Dynare are much higher than if you needed us to do it. That said, it is best to create an issue with an enhancement idea **before** beginning the work. As stated above, this is important to avoid duplication of work and also because we wouldn't want you to take the time to work on something that would not end up being included in Dynare.
|
||||
|
||||
## Get to Coding!
|
||||
|
||||
So, now you’ve reported the bug or asked for an enhancemnt by creating a GitLab issue. That’s already a great help. Thank you!
|
||||
So, now you've reported the bug or asked for an enhancemnt by creating a GitLab issue. That's already a great help. Thank you!
|
||||
|
||||
Now, if you want to go the extra mile, you’ll volunteer to contribute code to fix the GitLab issue you created above. Once we’ve agreed that you’ll do it, please do the following:
|
||||
Now, if you want to go the extra mile, you'll volunteer to contribute code to fix the GitLab issue you created above. Once we've agreed that you'll do it, please do the following:
|
||||
|
||||
1. Clone the Dynare repository:
|
||||
* `git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git`
|
||||
|
@ -61,7 +63,7 @@ Now, if you want to go the extra mile, you’ll volunteer to contribute code to
|
|||
1. Do your work, all the while respecting the [Dynare Coding Guidelines](https://git.dynare.org/Dynare/dynare/-/wikis/CodingGuidelines)
|
||||
1. You may also want to have a look at the [coding resources](https://git.dynare.org/Dynare/dynare/-/wikis/CodingResources)
|
||||
|
||||
As you work, your forked repository will likely fall out of sync with the main Dynare repository as we’ll be working in parallel. No matter. Follow these steps to ensure your changes will be merge-able when they’re done:
|
||||
As you work, your forked repository will likely fall out of sync with the main Dynare repository as we'll be working in parallel. No matter. Follow these steps to ensure your changes will be merge-able when they're done:
|
||||
|
||||
1. Get the changes from the main Dynare repository:
|
||||
* `git checkout master`
|
||||
|
@ -72,7 +74,7 @@ As you work, your forked repository will likely fall out of sync with the main D
|
|||
* `git rebase origin/master`
|
||||
* This last command may cause a conflict. It is up to you to resolve this conflict.
|
||||
|
||||
Once you’ve made the changes necessary to fix the bug or add an enhancement, ensure that it has been rebased on the master branch (following the steps above), commit it, push it to your forked Dynare repository, and create a pull request:
|
||||
Once you've made the changes necessary to fix the bug or add an enhancement, ensure that it has been rebased on the master branch (following the steps above), commit it, push it to your forked Dynare repository, and create a pull request:
|
||||
|
||||
1. Get the latest changes from Dynare and rebase your branch on top of them (see above)
|
||||
1. Commit your changes:
|
||||
|
@ -84,17 +86,17 @@ Once you’ve made the changes necessary to fix the bug or add an enhancement, e
|
|||
|
||||
## Tests
|
||||
|
||||
The Dynare testsuite runs every time a commit is pushed, either in the official repository or in your personal repository, through [GitLab Continuous Integration](https://docs.gitlab.com/ee/ci/). It’s how we quickly catch bugs that may have been introduced by changes made.
|
||||
The Dynare testsuite runs every time a commit is pushed, either in the official repository or in your personal repository, through [GitLab Continuous Integration](https://docs.gitlab.com/ee/ci/). It's how we quickly catch bugs that may have been introduced by changes made.
|
||||
|
||||
The output from the latest run of the test suite can be found in the `test_matlab` job associated to the [latest pipeline](https://git.dynare.org/Dynare/dynare/pipelines). This is also a good place to start fixing bugs. If you see a `.mod` file that doesn’t run in the test suite and think you can fix it, create an issue and once you have the go ahead, go for it!
|
||||
The output from the latest run of the test suite can be found in the `test_matlab` job associated to the [latest pipeline](https://git.dynare.org/Dynare/dynare/pipelines). This is also a good place to start fixing bugs. If you see a `.mod` file that doesn't run in the test suite and think you can fix it, create an issue and once you have the go ahead, go for it!
|
||||
|
||||
### Integration tests
|
||||
|
||||
It’s useful to contribute `.mod` files that test some aspect of Dynare that is not currently tested. A `.mod` file that runs into a bug is perfect. As the test suite currently takes several hours to run, we prefer you modify a current test to also create the bug you’ve found. If you can’t do that, please add a new test that runs as quickly as possible. It will contain only those commands necessary to create the bug, nothing more. To contribute a test, after having made an issue and cloned and forked the repository as described above, do the following:
|
||||
It's useful to contribute `.mod` files that test some aspect of Dynare that is not currently tested. A `.mod` file that runs into a bug is perfect. As the test suite currently takes several hours to run, we prefer you modify a current test to also create the bug you've found. If you can't do that, please add a new test that runs as quickly as possible. It will contain only those commands necessary to create the bug, nothing more. To contribute a test, after having made an issue and cloned and forked the repository as described above, do the following:
|
||||
|
||||
1. Modify the `mod_and_m_tests` variable in `meson.build` with a entry containing your test file name
|
||||
1. If any ancillary files are needed to run your test, please include them in the `'extra'` field
|
||||
1. Add and commit your test file and `meson.build` as described above
|
||||
1. Modify the `MODFILES` variable in `tests/Makefile.am` with a line containing your test file name
|
||||
1. If any ancillary files are needed to run your test, please include them in the `EXTRA_DIST` variable in `tests/Makefile.am`
|
||||
1. Add and commit your test file and `tests/Makefile.am` as described above
|
||||
1. Push and create a pull request as described above
|
||||
|
||||
### Unit tests
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
SUBDIRS = preprocessor doc tests mex/sources
|
||||
|
||||
if ENABLE_MATLAB
|
||||
SUBDIRS += mex/build/matlab
|
||||
endif
|
||||
if ENABLE_OCTAVE
|
||||
SUBDIRS += mex/build/octave
|
||||
endif
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
EXTRA_DIST = \
|
||||
matlab \
|
||||
dynare++ \
|
||||
contrib \
|
||||
NEWS.md \
|
||||
license.txt \
|
||||
README.md \
|
||||
COPYING \
|
||||
CONTRIBUTING.md \
|
||||
windows \
|
||||
macOS \
|
||||
examples \
|
||||
scripts \
|
||||
.dir-locals.el
|
||||
|
||||
all-local:
|
||||
# Create top-level preprocessor symlink needed by matlab/dynare.m (when Dynare is run
|
||||
# from the locally-built copy)
|
||||
$(LN_S) -f $(abs_builddir)/preprocessor/src/dynare-preprocessor$(EXEEXT) $(abs_builddir)/preprocessor/dynare-preprocessor$(EXEEXT)
|
||||
# Create backward-compatibility symlink for old location of preprocessor
|
||||
$(MKDIR_P) matlab/preprocessor64/
|
||||
$(LN_S) -f $(abs_builddir)/preprocessor/src/dynare-preprocessor$(EXEEXT) $(abs_srcdir)/matlab/preprocessor64/dynare_m$(EXEEXT)
|
||||
|
||||
clean-local:
|
||||
rm -f preprocessor/dynare-preprocessor$(EXEEXT)
|
||||
rm -rf matlab/preprocessor64/
|
||||
|
||||
dist-hook:
|
||||
rm -rf `find $(distdir)/matlab $(distdir)/examples -name *~`
|
||||
rm -f $(distdir)/matlab/dynare_version.m
|
||||
rm -rf $(distdir)/matlab/preprocessor64/
|
||||
$(MKDIR_P) $(distdir)/mex/matlab $(distdir)/mex/octave
|
||||
rm -rf `find $(distdir) -name '.git*'`
|
||||
|
||||
install-exec-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/preprocessor
|
||||
# The following will break under Windows, but we don’t use the install rule there
|
||||
$(LN_S) -f $(bindir)/dynare-preprocessor$(EXEEXT) $(DESTDIR)$(pkglibdir)/preprocessor/dynare-preprocessor$(EXEEXT)
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/contrib/ms-sbvar/TZcode
|
||||
cp -r contrib/ms-sbvar/TZcode/MatlabFiles $(DESTDIR)$(pkglibdir)/contrib/ms-sbvar/TZcode
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/contrib/jsonlab
|
||||
cp -r contrib/jsonlab $(DESTDIR)$(pkglibdir)/contrib/jsonlab
|
||||
cp -r examples $(DESTDIR)$(pkglibdir)
|
||||
cp -r matlab $(DESTDIR)$(pkglibdir)
|
||||
find $(DESTDIR)$(pkglibdir) -name LICENSE.md -delete
|
||||
# Recreate backward-compatibility symlink
|
||||
rm -f $(DESTDIR)$(pkglibdir)/matlab/preprocessor64/dynare_m$(EXEEXT)
|
||||
$(LN_S) -f $(bindir)/dynare-preprocessor$(EXEEXT) $(DESTDIR)$(pkglibdir)/matlab/preprocessor64/dynare_m$(EXEEXT)
|
||||
# We don’t fail over doc install rules, since the user may deliberately not have compiled them
|
||||
# (e.g. with the “nodoc” option under Debian)
|
||||
$(MKDIR_P) $(DESTDIR)$(docdir)
|
||||
-cp doc/*.pdf doc/gsa/gsa.pdf doc/parallel/parallel.pdf doc/dseries-and-reporting/dseriesReporting.pdf preprocessor/doc/preprocessor/preprocessor.pdf preprocessor/doc/macroprocessor/macroprocessor.pdf doc/manual/build/latex/dynare-manual.pdf $(DESTDIR)$(docdir)
|
||||
-cp -r doc/manual/build/html $(DESTDIR)$(docdir)/dynare-manual.html
|
||||
|
||||
uninstall-local:
|
||||
rm -rf $(DESTDIR)$(pkglibdir)
|
||||
rm -rf $(DESTDIR)$(docdir)
|
519
NEWS.md
519
NEWS.md
|
@ -1,521 +1,3 @@
|
|||
Announcement for Dynare 6.0 (on 2024-02-02)
|
||||
===========================================
|
||||
|
||||
We are pleased to announce the release of Dynare 6.0.
|
||||
|
||||
This major release adds new features and fixes various bugs.
|
||||
|
||||
The Windows, macOS, MATLAB Online and source packages are already available for
|
||||
download at [the Dynare website](https://www.dynare.org/download/).
|
||||
|
||||
This release is compatible with MATLAB versions ranging from 9.5 (R2018b) to
|
||||
23.2 (R2023b), and with GNU Octave versions ranging from 7.1.0 to 8.4.0 (NB:
|
||||
the Windows package requires version 8.4.0 specifically).
|
||||
|
||||
Major user-visible changes
|
||||
--------------------------
|
||||
|
||||
- The Sequential Monte Carlo sampler as described by Herbst and Schorfheide
|
||||
(2014) is now available under value `hssmc` for option
|
||||
`posterior_sampling_method`.
|
||||
|
||||
- New routines for perfect foresight simulation with expectation errors. In
|
||||
such a scenario, agents make expectation errors in that the path they had
|
||||
anticipated in period 1 is not realized exactly. More precisely, in some
|
||||
simulation periods, they may receive new information that makes them revise
|
||||
their anticipation for the path of future shocks. Also, under this scenario,
|
||||
it is assumed that agents behave as under perfect foresight, *i.e.* they
|
||||
make their decisions as if there were no uncertainty and they knew exactly
|
||||
the path of future shocks; the new information that they may receive comes
|
||||
as a total surprise to them. Available under new
|
||||
`perfect_foresight_with_expectation_errors_setup` and
|
||||
`perfect_foresight_with_expectation_errors_solver` commands, and
|
||||
`shocks(learnt_in=…)`, `mshocks(learnt_in=…)` and `endval(learnt_in=…)`
|
||||
blocks.
|
||||
|
||||
- New routines for IRF matching with stochastic simulations:
|
||||
|
||||
- Both frequentist (as in Christiano, Eichenbaum, and Evans, 2005) and
|
||||
Bayesian (as in Christiano, Trabandt, and Walentin, 2010) IRF matching
|
||||
approaches are implemented. The core idea of IRF matching is to treat
|
||||
empirical impulse responses (*e.g.* given from an SVAR or local projection
|
||||
estimation) as data and select model parameters that align the model’s
|
||||
IRFs closely with their empirical counterparts.
|
||||
|
||||
- Available under option `mom_method = irf_matching` option to the
|
||||
`method_of_moments` command.
|
||||
|
||||
- New blocks `matched_irfs` and `matched_irfs_weights` for specifying the
|
||||
values and weights of the empirical impulse response functions.
|
||||
|
||||
- Pruning à la Andreasen et al. (2018) is now available at an arbitrary
|
||||
approximation order when performing stochastic simulations with
|
||||
`stoch_simul`, and at 3rd order when performing particle filtering.
|
||||
|
||||
- New `log` option to the `var` statement. In addition to the endogenous
|
||||
variable(s) thus declared, this option also triggers the creation of
|
||||
auxiliary variable(s) equal to the log of the corresponding endogenous
|
||||
variable(s). For example, given a `var(log) y;` statement, two endogenous
|
||||
will be created (`y` and `LOG_y`), and an auxiliary equation linking the two
|
||||
will also be added (equal to `y = exp(LOG_y);`). Moreover, every occurrence
|
||||
of `y` in the model will be replaced by `exp(LOG_y)`. This option is, for
|
||||
example, useful for performing a loglinear approximation of some variable(s)
|
||||
in the context of a first-order stochastic approximation; or for ensuring
|
||||
that the variable(s) stay(s) in the definition domain of the function
|
||||
defining the steady state or the dynamic residuals when the nonlinear solver
|
||||
is used.
|
||||
|
||||
- New model editing features
|
||||
|
||||
- Multiple `model` blocks are now supported (this was already working but
|
||||
not explicitly documented).
|
||||
|
||||
- Multiple `estimated_params` blocks now concatenate their contents (instead
|
||||
of overwriting previous ones, which was the former undocumented behavior);
|
||||
an `overwrite` option has been added to provide the old behavior.
|
||||
|
||||
- New `model_options` statement to set model options in a global fashion.
|
||||
|
||||
- New `model_remove` command to remove equations.
|
||||
|
||||
- New `model_replace` block to replace equations.
|
||||
|
||||
- New `var_remove` command to remove variables (or parameters).
|
||||
|
||||
- New `estimated_params_remove` block to remove estimated parameters.
|
||||
|
||||
- Stochastic simulations
|
||||
|
||||
- Performance improvements for simulation of the solution under perturbation
|
||||
and for particle filtering at higher order (⩾ 3).
|
||||
|
||||
- Performance improvement for the first order perturbation solution using
|
||||
either cycle reduction (`dr=cycle_reduction` option) or logarithmic
|
||||
reduction (`dr=logarithmic_reduction`).
|
||||
|
||||
- New `nomodelsummary` option to the `stoch_simul` command, to suppress the
|
||||
printing of the model summary and the covariance of the exogenous shocks.
|
||||
|
||||
- Estimation
|
||||
|
||||
- A truncated normal distribution can now be specified as a prior, using the
|
||||
3rd and 4th parameters of the `estimated_params` block as the bounds.
|
||||
|
||||
- New `conditional_likelihood` option to the `estimation` command. When the
|
||||
option is set, instead of using the Kalman filter to evaluate the
|
||||
likelihood, Dynare will evaluate the conditional likelihood based on the
|
||||
first-order reduced form of the model by assuming that the initial state
|
||||
vector is at its steady state.
|
||||
|
||||
- New `additional_optimizer_steps` option to the `estimation` command to
|
||||
trigger the sequential execution of several optimizers when looking for
|
||||
the posterior mode.
|
||||
|
||||
- The `generate_trace_plots` command now allows comparing multiple chains.
|
||||
|
||||
- The Geweke and Raftery-Lewis convergence diagnostics will now also be
|
||||
displayed when `mh_nblocks>1`.
|
||||
|
||||
- New `robust`, `TolGstep`, and `TolGstepRel` options to the optimizer
|
||||
available under `mode_compute=5` (“newrat”).
|
||||
|
||||
- New `brooks_gelman_plotrows` option to the `estimation` command for
|
||||
controlling the number of parameters to depict along the rows of the
|
||||
figures depicting the Brooks and Gelman (1998) convergence diagnostics.
|
||||
|
||||
- New `mh_init_scale_factor` option to the `estimation` command tor govern
|
||||
the overdispersion of the starting draws when initializing several Monte
|
||||
Carlo Markov Chains. This option supersedes the `mh_init_scale` option,
|
||||
which is now deprecated.
|
||||
|
||||
- Steady state computation
|
||||
|
||||
- Steady state computation now accounts for occasionally-binding constraints
|
||||
of mixed-complementarity problems (as defined by `mcp` tags).
|
||||
|
||||
- New `tolx` option to the `steady` command for governing the termination
|
||||
based on the step tolerance.
|
||||
|
||||
- New `fsolve_options` option to the `steady` command for passing options to
|
||||
`fsolve` (in conjunction with the `solve_algo=0` option).
|
||||
|
||||
- New option `from_initval_to_endval` option to the `homotopy_setup` block,
|
||||
for easily computing homotopy from initial to terminal steady state (when
|
||||
the former is already computed).
|
||||
|
||||
- New `non_zero` option to `resid` command to restrict display to non-zero
|
||||
residuals.
|
||||
|
||||
- Perfect foresight
|
||||
|
||||
- Significant performance improvement of the `stack_solve_algo=1` option to
|
||||
the `perfect_foresight_solver` command (Laffargue-Boucekkine-Juillard
|
||||
algorithm) when used in conjunction with options `block` and/or `bytecode`
|
||||
of the `model` block.
|
||||
|
||||
- New `relative_to_initval` option to the `mshocks` block, to use the
|
||||
initial steady state as a basis for the multiplication when there is an
|
||||
`endval` block.
|
||||
|
||||
- New `static_mfs` option to the `model` block (and to the `model_options`
|
||||
command), for controlling the minimum feedback set computation for the
|
||||
static model. It defaults to `0` (corresponding to the behavior in Dynare
|
||||
version 5).
|
||||
|
||||
- Various improvements to homotopy
|
||||
|
||||
- New `endval_steady` option to the `perfect_foresight_setup` command for
|
||||
computing the terminal steady state at the same time as the transitory
|
||||
dynamics (and new options `steady_solve_algo`, `steady_tolf`,
|
||||
`steady_tolx`, `steady_maxit` and `steady_markowitz` for controlling the
|
||||
steady state nonlinear solver).
|
||||
|
||||
- New `homotopy_linearization_fallback` and
|
||||
`homotopy_marginal_linearization_fallback` options to the
|
||||
`perfect_foresight_solver` command to get an approximate solution when
|
||||
homotopy fails to go to 100%.
|
||||
|
||||
- New `homotopy_initial_step_size`, `homotopy_min_step_size`,
|
||||
`homotopy_step_size_increase_success_count` and
|
||||
`homotopy_max_completion_share` options to the
|
||||
`perfect_foresight_solver` command to fine tune the homotopy behavior.
|
||||
|
||||
- Purely backward, forward and static models are now supported by the
|
||||
homotopy procedure.
|
||||
|
||||
- The `stack_solve_algo=1` and `stack_solve_algo=6` options of the
|
||||
`perfect_foresight_solver` command were merged and are now synonymous.
|
||||
They both provide the Laffargue-Boucekkine-Juillard algorithm and work
|
||||
with and without the `block` and `bytecode` options of the `model` block.
|
||||
Using `stack_solve_algo=1` is now recommended, but `stack_solve_algo=6` is
|
||||
kept for backward compatibility.
|
||||
|
||||
- OccBin
|
||||
|
||||
- New `simul_reset_check_ahead_periods` option to the `occbin_setup` and
|
||||
`occbin_solver` commands, for resetting `check_ahead_periods` in each
|
||||
simulation period.
|
||||
|
||||
- new `simul_max_check_ahead_periods`, `likelihood_max_check_ahead_periods`,
|
||||
and `smoother_max_check_ahead_periods` options to the `occbin_setup`
|
||||
command, for truncating the number of periods for which agents check ahead
|
||||
which regime is present.
|
||||
|
||||
- Optimal policy
|
||||
|
||||
- The `osr` command now accepts the `analytic_derivation` and
|
||||
`analytic_derivation_mode` options.
|
||||
|
||||
- The `evaluate_planner_objective` command now computes the unconditional
|
||||
welfare for higher-order approximations (⩾ 3).
|
||||
|
||||
- New `periods` and `drop` options to the `evaluate_planner_objective`
|
||||
command.
|
||||
|
||||
- Semi-structural models
|
||||
|
||||
- New `pac_target_info` block for decomposing the PAC target into an
|
||||
arbitrary number of components. Furthermore, in the presence of such a
|
||||
block, the new `pac_target_nonstationary` operator can be used to select
|
||||
the non stationary part of the target (typically useful in the error
|
||||
correction term of the PAC equation).
|
||||
|
||||
- New `kind` option to the `pac_model` command. This option allows the user
|
||||
to select the formula used to compute the weights on the VAR companion
|
||||
matrix variables that are used to form PAC expectations.
|
||||
|
||||
- Performance improvement to `solve_algo=12` and `solve_algo=14`, which
|
||||
significantly accelerates the simulation of purely backward, forward and
|
||||
static models with the `perfect_foresight_solver` command and the routines
|
||||
for semi-structural models.
|
||||
|
||||
- dseries classes
|
||||
|
||||
- The `remove` and `remove_` methods now accept a list of variables (they
|
||||
would previously only accept a single variable).
|
||||
|
||||
- New MATLAB/Octave command `dplot` to plot mathematical expressions
|
||||
generated from variables fetched from (different) dseries objects.
|
||||
|
||||
- Misc
|
||||
|
||||
- New `display_parameter_values` command to print the parameter values in
|
||||
the command window.
|
||||
|
||||
- New `collapse_figures_in_tabgroup` command to dock all figures.
|
||||
|
||||
- Performance improvement for the `use_dll` option of the `model` block. The
|
||||
preprocessor now takes advantage of parallelization when compiling the MEX
|
||||
files.
|
||||
|
||||
- New mathematical primitives available: complementary error function
|
||||
(`erfc`), hyperbolic functions (`cosh`, `sinh`, `tanh`, `acosh`, `asinh`,
|
||||
`atanh`).
|
||||
|
||||
- New `last_simulation_period` option to the `initval_file` command.
|
||||
|
||||
- The `calib_smoother` command now accepts the `nobs` and
|
||||
`heteroskedastic_filter` options.
|
||||
|
||||
- Under the MATLAB Desktop, autocompletion is now available for the `dynare`
|
||||
command and other CLI commands (thanks to Eduard Benet Cerda from
|
||||
MathWorks).
|
||||
|
||||
- Model debugging: The preprocessor now creates files for evaluating the
|
||||
left- and right-hand sides of model equations separately. For a model file
|
||||
called `ramst.mod`, you can call
|
||||
`[lhs,rhs]=ramst.debug.static_resid(y,x,params);` (for the static model)
|
||||
and `[lhs,rhs]=ramst.debug.dynamic_resid(y,x,params,steady_state);` (for
|
||||
the dynamic model), where `y` are the endogenous, `x` the exogenous,
|
||||
`params` the parameters, and `steady_state` is self-explanatory. NB: In
|
||||
the dynamic case, the vector `y` of endogenous must have 3n elements
|
||||
where n is the number of endogenous (including auxiliary ones); the
|
||||
first n elements correspond to the lagged values, the middle n
|
||||
elements to the contemporaneous values, and the last n elements to the
|
||||
lead values.
|
||||
|
||||
- New interactive MATLAB/Octave command `search` for listing the equations
|
||||
in which given variable(s) appear (requires `json` command line option).
|
||||
|
||||
- The `model_info` command allows to print the block decomposition even if
|
||||
the `block` option of the `model` block has not been used, by specifying
|
||||
the new options `block_static` and `block_dynamic`.
|
||||
|
||||
- There is now a default value for the global initialization file
|
||||
(`GlobalInitFile` option of the configuration file): the `global_init.m`
|
||||
in the Dynare configuration directory (typically
|
||||
`$HOME/.config/dynare/global_init.m` under Linux and macOS, and
|
||||
`c:\Users\USERNAME\AppData\Roaming\dynare\global_init.m` under Windows).
|
||||
|
||||
- For those compiling Dynare from source, the build system has been entirely
|
||||
rewritten and now uses Meson; as a consequence, it is now faster and
|
||||
easier to understand.
|
||||
|
||||
- References:
|
||||
|
||||
- Andreasen, Martin M., Jesús Fernández-Villaverde, and Juan Rubio-Ramírez
|
||||
(2018): “The Pruned State-Space System for Non-Linear DSGE Models: Theory
|
||||
and Empirical Applications,” *Review of Economic Studies*, 85(1), 1-49.
|
||||
- Brooks, Stephen P., and Andrew Gelman (1998): “General methods for
|
||||
monitoring convergence of iterative simulations,” *Journal of Computational
|
||||
and Graphical Statistics*, 7, pp. 434–455.
|
||||
- Christiano, Eichenbaum and Charles L. Evans (2005): “Nominal Rigidities and
|
||||
the Dynamic Effects of a Shock to Monetary Policy,” *Journal of Political
|
||||
Economy*, 113(1), 1–45.
|
||||
- Christiano, Lawrence J., Mathias Trabandt, and Karl Walentin (2010): “DSGE
|
||||
Models for Monetary Policy Analysis,” In: *Handbook of Monetary Economics
|
||||
3*, 285–367.
|
||||
- Herbst, Edward and Schorfheide, Frank (2014): "Sequential Monte Carlo
|
||||
Sampling for DSGE Models," *Journal of Applied Econometrics*, 29,
|
||||
1073-1098.
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
- The default value of the `mode_compute` option of the `estimation` command
|
||||
has been changed to `5` (it was previously `4`).
|
||||
|
||||
- When using block decomposition (with the `block` option of the `model`
|
||||
block), the option `mfs` now defaults to `1`. This setting should deliver
|
||||
better performance in perfect foresight simulation on most models.
|
||||
|
||||
- The default location for the configuration file has changed. On Linux and
|
||||
macOS, the configuration file is now searched by default under
|
||||
`dynare/dynare.ini` in the configuration directories defined by the XDG
|
||||
specification (typically `$HOME/.config/dynare/dynare.ini` for the
|
||||
user-specific configuration and `/etc/xdg/dynare/dynare.ini` for the
|
||||
system-wide configuration, the former having precedence over the latter).
|
||||
Under Windows, the configuration file is now searched by default in
|
||||
`%APPDATA%\dynare\dynare.ini` (typically
|
||||
`c:\Users\USERNAME\AppData\Roaming\dynare\dynare.ini`).
|
||||
|
||||
- The information stored in `oo_.endo_simul, oo_.exo_simul`, and `oo_.irfs` is
|
||||
no longer duplicated in the base workspace. New helper functions
|
||||
`send_endogenous_variables_to_workspace`,
|
||||
`send_exogenous_variables_to_workspace`, and `send_irfs_to_workspace` have
|
||||
been introduced to explicitly request these outputs and to mimic the old
|
||||
behavior.
|
||||
|
||||
- The `dynare_sensitivity` command has been renamed `sensitivity`. The old
|
||||
name is still accepted but triggers a warning.
|
||||
|
||||
- The syntax `resid(1)` is no longer supported.
|
||||
|
||||
- The `mode_compute=6` option to the `estimation` command now recursively
|
||||
updates the covariance matrix across the `NumberOfMh` Metropolis-Hastings
|
||||
runs, starting with the `InitialCovarianceMatrix` in the first run, instead
|
||||
of computing it from scratch in every Metropolis-Hastings run.
|
||||
|
||||
- The `periods` command has been removed.
|
||||
|
||||
- The `Sigma_e` command has been removed.
|
||||
|
||||
- The `block` option of the `model` block no longer has an effect when used in
|
||||
conjunction with `stoch_simul` or `estimation` commands.
|
||||
|
||||
- The Dynare++ executable is no longer distributed since almost all of its
|
||||
functionalities have been integrated inside Dynare for MATLAB/Octave.
|
||||
|
||||
- A macro-processor variable defined without a value (such as `@#define var`
|
||||
in the `.mod` file or alternatively `-Dvar` on the `dynare` command line) is
|
||||
now assigned the `true` logical value (it was previously assigned `1`).
|
||||
|
||||
- The `parallel_slave_open_mode` option of the `dynare` command has been
|
||||
renamed `parallel_follower_open_mode`.
|
||||
|
||||
- The `static` option of the `model_info` command is now deprecated and is
|
||||
replaced by the `block_static` option.
|
||||
|
||||
Bugs that were present in 5.5 and that have been fixed in 6.0
|
||||
-------------------------------------------------------------
|
||||
|
||||
* The `mh_initialize_from_previous_mcmc` option of the `estimation` command
|
||||
would not work if estimation was conducted with a different prior and the
|
||||
last draw in the previous MCMC fell outside the new prior bounds
|
||||
* When specifying a generalized inverse Gamma prior, the hyperparameter
|
||||
computation would erroneously ignore the resulting mean shift
|
||||
* When using the `mh_recover` option of the `estimation` command, the status
|
||||
bar always started at zero instead of showing the overall progress of the
|
||||
recovered chain
|
||||
* The `model_diagnostics` command would fail to check the correctness of
|
||||
user-defined steady state files
|
||||
* GSA: LaTeX output was not working as expected
|
||||
* Forecasts and filtered variables could not be retrieved with the
|
||||
`heteroskedastic_shocks` block
|
||||
* The OccBin smoother would potentially not display all smoothed shocks with
|
||||
`heteroskedastic_filter` option
|
||||
* The OccBin smoother would crash if the number of requested periods was
|
||||
smaller than the data length
|
||||
* The multivariate OccBin smoother would return wrong results if the constraint
|
||||
was binding in the first period
|
||||
* The `plot_shock_decomposition` command would fail with the `init2shocks`
|
||||
block if the `initial_condition_decomposition` was not run before
|
||||
* LaTeX output under Windows failed to compile for `plot_priors=1` option of
|
||||
the `estimation` command and Brooks and Gelman (1998) convergence diagnostics
|
||||
* The plot produced by the `shock_decomposition` command was too big, making
|
||||
the close button inaccessible
|
||||
* Monthly dates for October, November and December (*i.e.* with a 2-digit month
|
||||
number) were not properly interpreted by the preprocessor
|
||||
* Theoretical moments computed by `stoch_simul` at `order=2` with `pruning`
|
||||
would not contain unconditional and conditional variance decomposition
|
||||
|
||||
|
||||
Announcement for Dynare 5.5 (on 2023-10-23)
|
||||
===========================================
|
||||
|
||||
We are pleased to announce the release of Dynare 5.5.
|
||||
|
||||
This maintenance release fixes various bugs.
|
||||
|
||||
The Windows, macOS and source packages are already available for download at
|
||||
[the Dynare website](https://www.dynare.org/download/).
|
||||
|
||||
All users are strongly encouraged to upgrade.
|
||||
|
||||
This release is compatible with MATLAB versions ranging from 8.3 (R2014a) to
|
||||
23.2 (R2023b), and with GNU Octave version 8.3.0 (under Windows).
|
||||
|
||||
Note for macOS users with an Apple Silicon processor: this is the first Dynare
|
||||
release that comes with native Apple Silicon (arm64) support under MATLAB.
|
||||
Please download the corresponding package, to be used with MATLAB R2023b for
|
||||
Apple Silicon.
|
||||
|
||||
Here is a list of the problems identified in version 5.4 and that have been
|
||||
fixed in version 5.5:
|
||||
|
||||
* In a stochastic context, results could be incorrect if an endogenous with a
|
||||
lead ⩾ 2 or an exogenous with a lead ⩾ 1 appeared in the argument(s) of a
|
||||
call to a (nonlinear) external function
|
||||
* With the `use_dll` option of the `model` block, the expression `sign(x)`
|
||||
would evaluate to ±1 instead of 0 if `x=0`
|
||||
* If the guess value given to the `steady` command was such that the residuals
|
||||
were all below tolerance, except some that are `NaN`, then this guess value
|
||||
was incorrectly accepted as the solution to the steady state problem
|
||||
* The `method_of_moments` command with GMM was ignoring the
|
||||
`analytic_standard_errors` option when using `mode_compute=4`
|
||||
* Homotopy with the `extended_path` command at `order=0` was broken
|
||||
* The `parallel_use_psexec` command-line option was ignored
|
||||
* With the `bytecode` option of the `model` block, using the operators `abs()`,
|
||||
`cbrt()` and `sign()` would lead to a crash
|
||||
* The `fast` command-line option was broken under MATLAB with Windows
|
||||
* Ramsey steady state computation could fail if an `expectation` or `diff`
|
||||
operator was present in the model
|
||||
* A crash could occur if some external function call was present in an
|
||||
auxiliary variable
|
||||
* The `endogenous_prior` option of the `estimation` command could erroneously
|
||||
display a warning message about missing observations
|
||||
* The `model_comparison` command would crash if the `.mod` file name had less
|
||||
than four characters
|
||||
* The `shock_decomposition` command would overwrite previously stored smoother
|
||||
results
|
||||
* The `x13` interface in dseries did not handle missing values, particularly at
|
||||
the beginning of a series
|
||||
* The `x13` interface in dseries would occasionally crash under Windows with
|
||||
segmentation violations
|
||||
* OccBin: estimation would crash if a previous `shocks(surprise)` simulation
|
||||
was conducted
|
||||
* The `internals` command would not find the location of the `_results.mat`
|
||||
file
|
||||
* The `prior optimize` command would not work with `mode_compute=5`
|
||||
|
||||
|
||||
Announcement for Dynare 5.4 (on 2023-03-22)
|
||||
===========================================
|
||||
|
||||
We are pleased to announce the release of Dynare 5.4.
|
||||
|
||||
This maintenance release fixes various bugs.
|
||||
|
||||
The Windows, macOS and source packages are already available for download at
|
||||
[the Dynare website](https://www.dynare.org/download/).
|
||||
|
||||
All users are strongly encouraged to upgrade.
|
||||
|
||||
This release is compatible with MATLAB versions ranging from 8.3 (R2014a) to
|
||||
9.14 (R2023a), and with GNU Octave version 8.1.0 (under Windows).
|
||||
|
||||
Note for macOS users with an Apple Silicon processor, and who are also MATLAB
|
||||
users: the official MATLAB version for use on those processors is still the
|
||||
Intel version (running through Rosetta 2), so the official Dynare package for
|
||||
download on our website is built for Intel only. However, since Mathworks has
|
||||
released a beta version of MATLAB for Apple Silicon, we created a beta package
|
||||
of Dynare that you can try with it. See this forum thread for more details:
|
||||
https://forum.dynare.org/t/testers-wanted-release-of-dynare-5-x-beta-for-apple-silicon-m1-m2-chips/20499
|
||||
|
||||
Here is a list of the problems identified in version 5.3 and that have been
|
||||
fixed in version 5.4:
|
||||
|
||||
* Files installed through the Windows installer had too weak permissions and
|
||||
could be modified by unpriviledged local users, if the default installation
|
||||
location (`c:\dynare\`) had been chosen
|
||||
* Estimation:
|
||||
+ the `load_results_after_load_mh` option would not find the location of the
|
||||
results file
|
||||
+ the computation of prior/posterior statistics would crash if the value of
|
||||
the `filter step_ahead` option was greater than 1 without requesting a
|
||||
`forecast` or the `smoother`
|
||||
+ NaN or complex parameters returned by steady state files were not correctly
|
||||
handled
|
||||
+ `analytical_derivation` could be triggered with `endogenous_prior` but
|
||||
would not take the endogenous prior into account for the Jacobian and
|
||||
Hessian
|
||||
* OccBin:
|
||||
+ running the `calib_smoother` command with `smoother_inversion_filter` would
|
||||
crash unless `likelihood_inversion_filter` was also specified
|
||||
+ running the piecewise Kalman smoother would crash if an error was
|
||||
encountered during computation of the decision rules
|
||||
* PAC equation estimation through iterative OLS would crash if the auxiliary
|
||||
model contained a constant
|
||||
* The variable label was incorrect for leads and lags of exogenous variables in
|
||||
the display of decision rules and in the `model_info` command
|
||||
* Declaring a `trend_var` variable while not having a `var(deflator=...)`
|
||||
statement would cause the preprocessor to crash
|
||||
* Macro processor: error messages following a `@#define`, `@#include` or
|
||||
`@#includepath` directive could in some cases point to a line number off by 1
|
||||
* Perfect foresight simulations: the `debug` option would not preserve
|
||||
sparsity, causing out of memory errors
|
||||
|
||||
|
||||
Announcement for Dynare 5.3 (on 2022-11-21)
|
||||
===========================================
|
||||
|
||||
|
@ -563,6 +45,7 @@ fixed in version 5.3:
|
|||
* Problems related to Bayesian or ML estimation:
|
||||
+ `mh_recover` and `load_mh_file` would not find the saved proposal density
|
||||
and had to rely on the `_mode` file
|
||||
+ `load_results_after_load_mh` would not find the location of the `_results` file
|
||||
+ When requesting `bayesian_irf` together with `loglinear`, the resulting
|
||||
IRFs would be incorrect
|
||||
+ the diffuse Kalman smoother initialization (`lik_init=3`) was wrong when
|
||||
|
|
392
README.md
392
README.md
|
@ -33,6 +33,8 @@ This source can be retrieved in three forms:
|
|||
- using the stable source archive of the latest Dynare version from <https://www.dynare.org/download/>
|
||||
- using a source snapshot of the unstable version, also from <https://www.dynare.org/download/>
|
||||
|
||||
Note that if you obtain the source code via git, you will need to install more tools (see below).
|
||||
|
||||
The first section of this page gives general instructions, which apply to all platforms. Then some specific platforms are discussed.
|
||||
|
||||
**Note:** Here, when we refer to 32-bit or 64-bit, we refer to the type of
|
||||
|
@ -43,8 +45,8 @@ determine the type of your MATLAB/Octave installation, type:
|
|||
```matlab
|
||||
>> computer
|
||||
```
|
||||
at the MATLAB/Octave prompt. Under MATLAB, if it returns `PCWIN64`, `GLNX64`,
|
||||
`MACI64` or `MACA64` then it is a 64-bit MATLAB; if it returns `PCWIN`, `MACI` or `GLNX`,
|
||||
at the MATLAB/Octave prompt. Under MATLAB, if it returns `PCWIN64`, `GLNX64` or
|
||||
`MACI64`, then it is a 64-bit MATLAB; if it returns `PCWIN`, `MACI` or `GLNX`,
|
||||
then it is a 32-bit MATLAB. Under Octave, if it returns a string that begins
|
||||
with `x86_64`, it is a 64-bit Octave; if the strings begins with `i686`, it is
|
||||
a 32-bit Octave.
|
||||
|
@ -56,7 +58,6 @@ a 32-bit Octave.
|
|||
1. [**Fedora, CentOS or RHEL**](#fedora-centos-or-rhel)
|
||||
1. [**Windows**](#windows)
|
||||
1. [**macOS**](#macos)
|
||||
1. [**Docker**](#docker)
|
||||
|
||||
## General Instructions
|
||||
|
||||
|
@ -64,27 +65,28 @@ a 32-bit Octave.
|
|||
|
||||
A number of tools and libraries are needed in order to recompile everything. You don't necessarily need to install everything, depending on what you want to compile.
|
||||
|
||||
- A POSIX compliant shell and an implementation of Make (mandatory)
|
||||
- The [GNU Compiler Collection](https://gcc.gnu.org/), version 10 or later, with
|
||||
gcc, g++ and gfortran
|
||||
gcc, g++ and gfortran (mandatory)
|
||||
- [MATLAB](https://mathworks.com) (if you want to compile the MEX for MATLAB)
|
||||
- [GNU Octave](https://www.octave.org) with
|
||||
- the development headers (if you want to compile the MEX for Octave)
|
||||
- the development libraries corresponding to the [UMFPACK](https://people.engr.tamu.edu/davis/suitesparse.html) packaged with Octave (if you want to compile the MEX for Octave)
|
||||
- the [statistics](https://octave.sourceforge.io/statistics/) package and, optionally, the [control](https://octave.sourceforge.io/control/), [io](https://octave.sourceforge.io/io/) and [optimization](https://octave.sourceforge.io/optim/) packages, either installed via your package manager or through [Octave Forge](https://octave.sourceforge.io/)
|
||||
- [Meson](https://mesonbuild.com), version 0.64.0 or later
|
||||
- [Pkgconf](http://pkgconf.org/), or another pkg-config implementation
|
||||
- [Bash](https://www.gnu.org/software/bash/)
|
||||
- the development libraries corresponding to the [UMFPACK](https://people.engr.tamu.edu/davis/suitesparse.html) packaged with Octave
|
||||
- Optionally, the [Control](https://octave.sourceforge.io/control/), [IO](https://octave.sourceforge.io/io/), [Optimization](https://octave.sourceforge.io/optim/) and [Statistics](https://octave.sourceforge.io/statistics/) package either installed via your package manager or through [Octave Forge](https://octave.sourceforge.io/).
|
||||
- [Boost libraries](https://www.boost.org), version 1.36 or later
|
||||
- [Bison](https://www.gnu.org/software/bison/), version 3.2 or later
|
||||
- [Flex](https://github.com/westes/flex), version 2.5.4 or later
|
||||
- [MAT File I/O library](https://sourceforge.net/projects/matio/), version 1.5 or later (only when compiling for Octave)
|
||||
- [SLICOT](http://www.slicot.org)
|
||||
- [GSL library](https://www.gnu.org/software/gsl/)
|
||||
- [Bison](https://www.gnu.org/software/bison/), version 3.2 or later (only if you get the source through Git)
|
||||
- [Flex](https://github.com/westes/flex), version 2.5.4 or later (only if you get the source through Git)
|
||||
- [Autoconf](https://www.gnu.org/software/autoconf/), version 2.62 or later (only if you get the source through Git)
|
||||
- [Automake](https://www.gnu.org/software/automake/), version 1.11.2 or later (only if you get the source through Git)
|
||||
- [MAT File I/O library](https://sourceforge.net/projects/matio/), version 1.5 or later (if you want to compile Markov-Switching code, the estimation DLL, and the k-order DLL)
|
||||
- [SLICOT](http://www.slicot.org) (if you want to compile the Kalman steady state DLL)
|
||||
- [GSL library](https://www.gnu.org/software/gsl/) (if you want to compile Markov-Switching code)
|
||||
- A decent LaTeX distribution (if you want to compile PDF documentation),
|
||||
ideally with Beamer
|
||||
- For building the reference manual:
|
||||
- [Sphinx](https://www.sphinx-doc.org/)
|
||||
- [MathJax](https://www.mathjax.org/)
|
||||
- [Doxygen](https://www.doxygen.nl) (if you want to build Dynare preprocessor source documentation)
|
||||
- [X-13ARIMA-SEATS Seasonal Adjustment Program](https://www.census.gov/data/software/x13as.html)
|
||||
|
||||
### Preparing the sources
|
||||
|
@ -96,78 +98,107 @@ have the [Git LFS](https://git-lfs.github.com/) extension installed):
|
|||
```sh
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git
|
||||
cd dynare
|
||||
autoreconf -si
|
||||
```
|
||||
If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command.
|
||||
The last line runs Autoconf and Automake in order to prepare the build environment (this is not necessary if you got the sources from an official source archive or the source snapshot). If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command.
|
||||
|
||||
### Configuring the build directory
|
||||
### Configuring the build tree
|
||||
|
||||
If you want to compile for MATLAB, please run the following (after adapting the path to MATLAB):
|
||||
Simply launch the configure script from a terminal:
|
||||
```sh
|
||||
meson setup -Dmatlab_path=/usr/local/MATLAB/R2023b -Dbuildtype=debugoptimized build-matlab
|
||||
./configure --with-matlab=<…>
|
||||
```
|
||||
The build directory will thus be `build-matlab`.
|
||||
where the path to MATLAB is specified.
|
||||
|
||||
Or for Octave:
|
||||
```sh
|
||||
meson setup -Dbuild_for=octave -Dbuildtype=debugoptimized build-octave
|
||||
Some important options:
|
||||
|
||||
- `--disable-matlab`: skip the compilation of MEX files for MATLAB
|
||||
- `--disable-octave`: skip the compilation of MEX files for Octave
|
||||
- `--disable-doc`: skip the compilation of the documentation (PDF and HTML)
|
||||
|
||||
You may need to specify additional options to the configure script, see the output of the `--help` option, and also the platform specific instructions below. If the configuration goes well, the script will tell you which components are correctly configured and will be built.
|
||||
|
||||
Note that it is possible that some MEX files cannot be compiled, due to missing
|
||||
build dependencies. If you find no way of installing the missing dependencies,
|
||||
a workaround can be to give up on compiling these MEX files and rather use
|
||||
slower implementations (in the MATLAB/Octave language) that are available under
|
||||
the `matlab/missing/mex/` subdirectories. For example, if you fail to compile
|
||||
the gensylv MEX, you can type the following at the MATLAB/Octave prompt before
|
||||
running Dynare:
|
||||
```matlab
|
||||
addpath <DYNARE_ROOT>/matlab/missing/mex/gensylv
|
||||
```
|
||||
The build directory will thus be `build-octave`.
|
||||
|
||||
Note that if you do not chose `build-matlab` (under MATLAB) or `build-octave`
|
||||
(under Octave) as the build directory, you will need to set the environment
|
||||
variable `DYNARE_BUILD_DIR` to the full path of your build tree, before running
|
||||
MATLAB or Octave, if you want Dynare to be able to find the preprocessor and
|
||||
the MEX files.
|
||||
|
||||
It is possible to specify various Meson options, see the Meson documentation
|
||||
for more details. Modifying options of an existing build directory can be
|
||||
done using the `meson configure` command.
|
||||
(where you need to replace `<DYNARE_ROOT>` with the full path to your Dynare copy).
|
||||
|
||||
### Building
|
||||
|
||||
For compiling the preprocessor and the MEX files:
|
||||
Binaries are built with:
|
||||
```sh
|
||||
meson compile -C <builddir>
|
||||
make
|
||||
```
|
||||
where `<builddir>` is the build directory, typically either `build-matlab` or `build-octave`.
|
||||
|
||||
PDF and HTML documentation can be built with:
|
||||
PDF and HTML documentation are respectively built with:
|
||||
```sh
|
||||
meson compile -C <builddir> doc
|
||||
make pdf
|
||||
make html
|
||||
```
|
||||
|
||||
### Check
|
||||
|
||||
Dynare comes with unit tests (in the MATLAB functions) and integration tests (under the `tests` subfolder). All the tests can be run with:
|
||||
The Git source comes with unit tests (in the MATLAB functions) and integration tests (under the `tests` subfolder). All the tests can be run with:
|
||||
```sh
|
||||
meson test -C <builddir>
|
||||
make check
|
||||
```
|
||||
in the `tests` subfolder. If Dynare has been compiled against MATLAB and Octave, the tests will be run with both MATLAB and Octave. Depending on the performance of your machine, this can take several hours. It is possible to run the tests only with MATLAB:
|
||||
```sh
|
||||
make check-matlab
|
||||
```
|
||||
or only with Octave:
|
||||
```sh
|
||||
make check-octave
|
||||
```
|
||||
|
||||
Depending on the performance of your machine, this can take several hours.
|
||||
|
||||
Note that running the testsuite with Octave requires the additional packages `pstoedit`, `epstool`, `xfig`, and `gnuplot`.
|
||||
|
||||
Often, it does not make sense to run the complete testsuite. For instance, if you modify codes only related to the perfect foresight model solver, you can decide to run only a subset of the integration tests, with:
|
||||
A summary of the results is available in `tests/run_test_matlab_output.txt` or `tests/run_test_octave_output.txt`. Often, it does not make sense to run the complete testsuite. For instance, if you modify codes only related to the perfect foresight model solver, you can decide to run only a subset of the integration tests, with:
|
||||
```sh
|
||||
meson test -C <builddir> --suite deterministic_simulations
|
||||
make deterministic_simulations
|
||||
```
|
||||
This will run all the integration tests in `tests/deterministic_simulations`.
|
||||
This syntax also works with a nested directory (e.g. `--suite deterministic_simulations/purely_forward`).
|
||||
|
||||
Finally if you want to run a single integration test, e.g. `deterministic_simulations/lbj/rbc.mod`:
|
||||
This will run all the integration tests in `tests/deterministic_simulations` with MATLAB and Octave. Again, it is possible to do this only with MATLAB:
|
||||
```sh
|
||||
meson test -C <builddir> deterministic_simulations/lbj/rbc.mod
|
||||
make m/deterministic_simulations
|
||||
```
|
||||
NB: Some individual tests cannot be run using that syntax, if they are a dependency in a chain of tests (see the `mod_and_m_tests` variable `meson.build`); in that case, you should use the name of the last `.mod` file in the chain as the test name to be passed to `meson test`.
|
||||
or with Octave:
|
||||
```sh
|
||||
make o/deterministic_simulations
|
||||
```
|
||||
Finally if you want to run a single integration test, e.g. `deterministic_simulations/lbj/rbc.mod` with MATLAB:
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.m.trs
|
||||
```
|
||||
or with Octave:
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.o.trs
|
||||
```
|
||||
The result of the test (`PASSED` or `FAILED`) will be printed in the terminal, the produced log can be displayed with:
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.m.drs
|
||||
```
|
||||
or
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.o.drs
|
||||
```
|
||||
Note that only tests will be executed where the `m.trs/o.trs` does not yet exist. You can run
|
||||
```sh
|
||||
make clean
|
||||
```
|
||||
in the `tests` folder to delete files that were created by the run of the testsuite. You can also manually delete the desired `m.trs/o.trs` file(s).
|
||||
|
||||
## Debian or Ubuntu
|
||||
|
||||
All the prerequisites are packaged:
|
||||
|
||||
- `gcc`
|
||||
- `g++`
|
||||
- `build-essential` (for gcc, g++ and make)
|
||||
- `gfortran`
|
||||
- `octave-dev` (or `liboctave-dev` on older Debian/Ubuntu releases)
|
||||
- `liboctave-dev`
|
||||
- `libboost-graph-dev`
|
||||
- `libgsl-dev`
|
||||
- `libmatio-dev`
|
||||
|
@ -175,31 +206,40 @@ All the prerequisites are packaged:
|
|||
- `libsuitesparse-dev`
|
||||
- `flex` and `libfl-dev`
|
||||
- `bison`
|
||||
- `meson`
|
||||
- `pkgconf`
|
||||
- `autoconf`
|
||||
- `automake`
|
||||
- `texlive`
|
||||
- `texlive-publishers` (for Econometrica bibliographic style)
|
||||
- `texlive-latex-extra` (for fullpage.sty)
|
||||
- `texlive-fonts-extra` (for ccicons)
|
||||
- `texlive-latex-recommended`
|
||||
- `texlive-science` (for amstex)
|
||||
- `texlive-plain-generic`
|
||||
- `lmodern` (for macroprocessor PDF)
|
||||
- `python3-sphinx`
|
||||
- `tex-gyre`
|
||||
- `latexmk`
|
||||
- `libjs-mathjax`
|
||||
- `doxygen`
|
||||
- `x13as`
|
||||
|
||||
You can install them all at once with:
|
||||
```sh
|
||||
apt install gcc g++ gfortran octave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex libfl-dev bison meson pkgconf texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-science lmodern python3-sphinx make tex-gyre latexmk libjs-mathjax x13as
|
||||
apt install build-essential gfortran liboctave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex libfl-dev bison autoconf automake texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-latex-recommended texlive-science texlive-plain-generic lmodern python3-sphinx tex-gyre latexmk libjs-mathjax doxygen x13as
|
||||
```
|
||||
If you use MATLAB, we strongly advise to also `apt install matlab-support` and confirm to rename the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by your distribution.
|
||||
|
||||
Tested on
|
||||
- Debian “Buster” 10
|
||||
- Debian “Bullseye” 11
|
||||
- Ubuntu 20.04
|
||||
- Ubuntu 20.10
|
||||
|
||||
## Fedora, CentOS or RHEL
|
||||
|
||||
Almost all prerequisites are packaged:
|
||||
|
||||
- `gcc`, `gcc-c++`
|
||||
- `gcc`, `gcc-c++`, `make`
|
||||
- `gcc-gfortran`
|
||||
- `boost-devel`
|
||||
- `gsl-devel`
|
||||
|
@ -207,23 +247,24 @@ Almost all prerequisites are packaged:
|
|||
- `suitesparse-devel`
|
||||
- `flex`
|
||||
- `bison`
|
||||
- `meson`
|
||||
- `autoconf`
|
||||
- `automake`
|
||||
- `redhat-rpm-config`
|
||||
- `octave`, `octave-devel`, `octave-statistics`, `octave-io`, `octave-optim`, `octave-control`
|
||||
- `texlive-scheme-minimal`, `texlive-collection-publishers`, `texlive-collection-latexextra`, `texlive-collection-fontsextra`, `texlive-collection-latexrecommended`, `texlive-collection-science`, `texlive-collection-plaingeneric`, `texlive-lm`
|
||||
- `python3-sphinx`
|
||||
- `latexmk`
|
||||
- `mathjax`
|
||||
- `make` (for building Slicot)
|
||||
- `doxygen`
|
||||
|
||||
You can install them all at once with:
|
||||
```sh
|
||||
# Minimal packages
|
||||
dnf install -y gcc gcc-c++ make gcc-gfortran boost-devel gsl-devel matio-devel suitesparse-devel flex bison meson redhat-rpm-config
|
||||
# Octave packages
|
||||
# Minimal packages (use --disable-doc and --disable-octave flags)
|
||||
dnf install -y gcc gcc-c++ make gcc-gfortran boost-devel gsl-devel matio-devel suitesparse-devel flex bison autoconf automake redhat-rpm-config
|
||||
# Octave packages (use --disable-doc flag)
|
||||
dnf install octave octave-devel octave-statistics octave-io octave-optim octave-control
|
||||
# Documentation packages (only needed if you build documentation)
|
||||
dnf install texlive-scheme-minimal texlive-collection-publishers texlive-collection-latexextra texlive-collection-fontsextra texlive-collection-latexrecommended texlive-collection-science texlive-collection-plaingeneric texlive-lm python3-sphinx latexmk mathjax
|
||||
# Documentation packages
|
||||
dnf install texlive-scheme-minimal texlive-collection-publishers texlive-collection-latexextra texlive-collection-fontsextra texlive-collection-latexrecommended texlive-collection-science texlive-collection-plaingeneric texlive-lm python3-sphinx latexmk mathjax doxygen
|
||||
```
|
||||
In Fedora these are available from the default repositories; whereas for CentOS and RHEL you need to enable the [Extra Packages for Enterprise Linux (EPEL)](https://fedoraproject.org/wiki/EPEL) repository and either the PowerTools repository for CentOS or the CodeReady Linux Builder repository for RHEL:
|
||||
```sh
|
||||
|
@ -234,7 +275,7 @@ dnf config-manager --set-enabled PowerTools
|
|||
ARCH=$( /bin/arch )
|
||||
subscription-manager repos --enable "codeready-builder-for-rhel-8-${ARCH}-rpms"
|
||||
```
|
||||
The documentation packages have slightly different names in CentOS and RHEL, but this should only impact you if you build the documentation.
|
||||
The documentation packages have slightly different names in CentOS and RHEL, you can also choose to pass the `--disable-doc` flag to your configure script to skip these dependencies.
|
||||
|
||||
`Slicot` and `x13as` need to be compiled from source:
|
||||
|
||||
|
@ -245,19 +286,16 @@ cd /home/$USER/dynare/slicot
|
|||
wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
tar xf slicot_5.0+20101122.orig.tar.gz
|
||||
cd slicot-5.0+20101122
|
||||
mkdir -p /home/$USER/dynare/slicot/lib
|
||||
# The following two lines are only for MATLAB
|
||||
make FORTRAN=gfortran OPTS="-O2 -fPIC -fdefault-integer-8" LOADER=gfortran lib
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot64_pic.a
|
||||
# The following two lines are only for Octave
|
||||
make FORTRAN=gfortran OPTS="-O2 -fPIC" LOADER=gfortran lib
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot_pic.a
|
||||
mkdir -p /home/$USER/dynare/slicot/lib
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot64_pic.a #for matlab
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot_pic.a #for octave
|
||||
|
||||
# compile x13as from source and put it into /usr/bin/
|
||||
mkdir -p /home/$USER/dynare/x13as
|
||||
cd /home/$USER/dynare/x13as
|
||||
wget https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b60.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b60.tar.gz
|
||||
wget https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b58.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b58.tar.gz
|
||||
sed -i "s|-static| |" makefile.gf # this removes '-static' in the makefile.gf
|
||||
make -f makefile.gf FFLAGS="-O2 -std=legacy" PROGRAM=x13as
|
||||
sudo cp x13as /usr/bin/
|
||||
|
@ -265,16 +303,17 @@ sudo cp x13as /usr/bin/
|
|||
|
||||
If you use MATLAB, we strongly advise to also rename or exclude the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by Fedora, see e.g. [Matlab on Fedora 33](https://mutschler.eu/linux/install-guides/fedora-post-install/#matlab) or [MATLAB-ArchWiki](https://wiki.archlinux.org/index.php/MATLAB) for instructions.
|
||||
|
||||
Now use the following commands if using MATLAB (adapt them for Octave, see above):
|
||||
Keep in mind to use the `--with-slicot` option to the configure command, e.g.:
|
||||
```sh
|
||||
cd /home/$USER/dynare
|
||||
git clone --recurse-submodules https://git.dynare.org/dynare/dynare.git unstable
|
||||
cd unstable
|
||||
meson setup -Dmatlab_path=/usr/local/MATLAB/R2023b -Dfortran_args="[ '-B', '/home/$USER/dynare/slicot']" -Dbuildtype=debugoptimized build-matlab
|
||||
meson compile -C build-matlab
|
||||
autoreconf -si
|
||||
./configure --with-slicot=/home/$USER/dynare/slicot --with-matlab=/usr/local/MATLAB/R2020b
|
||||
make -j$(($(nproc)+1)) #rule of thumb: one more than CPUs as shown by e.g. lscpu
|
||||
```
|
||||
|
||||
If your distribution ships an older version of `bison`, compile it from source and append it *temporarily* to your path before running meson:
|
||||
If your distribution ships an older version of `bison`, compile it from source and append it *temporarily* to your path before calling the configure script:
|
||||
```sh
|
||||
bison --version # bison (GNU Bison) 3.0.4
|
||||
mkdir -p /home/$USER/dynare/bison
|
||||
|
@ -290,6 +329,12 @@ bison --version # bison (GNU Bison) 3.6.4
|
|||
```
|
||||
Now configure dynare as above.
|
||||
|
||||
Tested on
|
||||
- CentOS 8
|
||||
- Fedora Workstation 32
|
||||
- Fedora Workstation 33
|
||||
- Red Hat Enterprise Linux 8
|
||||
|
||||
## Windows
|
||||
|
||||
- Install [MSYS2](http://www.msys2.org)
|
||||
|
@ -303,9 +348,9 @@ pacman -Syu
|
|||
window to complete the upgrade.
|
||||
- Install all needed dependencies:
|
||||
```sh
|
||||
pacman -S git bison flex make tar mingw-w64-x86_64-meson mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-x86_64-boost mingw-w64-x86_64-gsl mingw-w64-x86_64-matio mingw-w64-x86_64-pkgconf
|
||||
pacman -S git autoconf automake-wrapper bison flex make tar texinfo mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-x86_64-boost mingw-w64-x86_64-gsl mingw-w64-x86_64-matio
|
||||
```
|
||||
- Compile and install SLICOT
|
||||
- Compile and install SLICOT, needed for the `kalman_steady_state` MEX file
|
||||
```sh
|
||||
wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
tar xf slicot_5.0+20101122.orig.tar.gz
|
||||
|
@ -319,10 +364,11 @@ cd ..
|
|||
```sh
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git
|
||||
cd dynare
|
||||
autoreconf -si
|
||||
```
|
||||
- Configure Dynare from the source directory:
|
||||
```sh
|
||||
meson setup -Dmatlab_path=<…> -Dbuildtype=debugoptimized -Dprefer_static=true -Dfortran_args="['-B','/usr/local/lib']" build-matlab
|
||||
./configure --with-slicot=/usr/local --with-matlab=<…> --disable-octave --disable-doc
|
||||
```
|
||||
where the path of MATLAB is specified. Note that you should use
|
||||
the MSYS2 notation and not put spaces in the MATLAB path, so you probably want
|
||||
|
@ -332,11 +378,11 @@ does not have short filenames (8dot3), then you can run `mkdir -p
|
|||
then pass `/usr/local/MATLAB/…` as MATLAB path to the configure script.
|
||||
- Compile:
|
||||
```sh
|
||||
meson compile -C build-matlab
|
||||
make
|
||||
```
|
||||
- Run the testsuite:
|
||||
```sh
|
||||
meson test -C build-matlab
|
||||
make -C tests check-matlab
|
||||
```
|
||||
|
||||
**Note:** The above assumes that you have a 64-bit version of MATLAB. It can be
|
||||
|
@ -351,168 +397,118 @@ adapted to a 32-bit MATLAB with the following modifications:
|
|||
currently not supported.
|
||||
|
||||
## macOS
|
||||
|
||||
Dynare supports both Intel and Apple Silicon chips and is compiled from source
|
||||
using a [Homebrew](https://brew.sh/) toolchain. If you have an Apple silicon processor
|
||||
(*M1/M2 PRO/MAX/ULTRA*), you can compile Dynare both for Intel's `x86_64` (using Rosetta 2)
|
||||
as well as Apple's native `arm64` platform by using the corresponding Homebrew packages.
|
||||
If you have an Intel chip you can only compile for `x86_64`.
|
||||
using a [Homebrew](https://brew.sh/) toolchain. However, if you have a *M1*, *M1 PRO*
|
||||
or *M1 MAX* processor, you need to make sure that you are not using the ARM
|
||||
Homebrew packages. This is due to the fact that although MATLAB runs natively on
|
||||
Intel, it is not yet available in an ARM version and therefore must be run with the
|
||||
Intel compatibility layer called Rosetta 2. Accordingly, if you are on Apple Silicon
|
||||
you need to compile Dynare under Rosetta 2 as well and use the Intel packages from
|
||||
Homebrew. You can check this by e.g. running `which brew` which should point to
|
||||
`/usr/local/bin/brew` and not to `/opt/homebrew/bin/brew`. In the steps below, we
|
||||
create a temporary alias to ensure that `brew` points to the Intel packages.
|
||||
|
||||
You can check the platform of your current Homebrew installation by e.g. running
|
||||
`which brew` which should point to `/opt/homebrew/bin/brew` for `arm64` and to
|
||||
`/usr/local/bin/brew` for `x86_64` systems. In the steps below, we
|
||||
create a temporary environment variable `BREWDIR` to ensure that the correct packages are used.
|
||||
For the following steps open Terminal.app and enter the commands listed below.
|
||||
|
||||
The following commands install all requirements and Dynare from source.
|
||||
They should be entered at the command prompt in Terminal.app.
|
||||
|
||||
### Preparatory work
|
||||
|
||||
- Install the Xcode Command Line Tools:
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
- Install Rosetta 2 (Apple Silicon only):
|
||||
```sh
|
||||
softwareupdate --install-rosetta --agree-to-license
|
||||
```
|
||||
|
||||
- Install the Xcode Command Line Tools:
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
- Install [Homebrew](https://brew.sh/):
|
||||
Create environment variables for which platform you want to compile for, i.e. either `arm64` or `x86_64`:
|
||||
|
||||
For `arm64` run the following commands:
|
||||
```sh
|
||||
export ARCH=arm64
|
||||
export BREWDIR=/opt/homebrew
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
The prefix `arch -x86_64` makes sure that you are using Rosetta 2 to install Homebrew.
|
||||
|
||||
- Apple Silicon only: Make a (temporary) alias to run `brew` under Rosetta 2:
|
||||
```sh
|
||||
alias brew='arch -x86_64 /usr/local/bin/brew'
|
||||
which brew
|
||||
#brew: aliased to arch -x86_64 /usr/local/bin/brew
|
||||
```
|
||||
|
||||
For `x86_64` run the following commands:
|
||||
- Install required Homebrew packages and link sphinx-doc:
|
||||
```sh
|
||||
export ARCH=x86_64
|
||||
export BREWDIR=/usr/local
|
||||
brew install automake bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc wget
|
||||
brew link --force sphinx-doc
|
||||
```
|
||||
|
||||
Install Homebrew using the environment variables:
|
||||
- Install [MacTeX](http://www.tug.org/mactex/index.html) using the universal installer. MacTeX runs natively on both ARM and Intel machines. On Apple Silicon, we need to put `pdflatex` and `bibtex` into our path:
|
||||
```sh
|
||||
arch -$ARCH /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
ln -s /Library/TeX/texbin/pdflatex /usr/local/bin/pdflatex
|
||||
ln -s /Library/TeX/texbin/bibtex /usr/local/bin/bibtex
|
||||
```
|
||||
The prefix `arch -arm64` or `arch -x86_64` makes sure that you are installing the correct packages.
|
||||
Don't forget to run the displayed commands (**Next steps**) in the terminal to add Homebrew to your PATH.
|
||||
Alternatively, if you don’t want to install MacTeX, you should pass the `--disable-doc` flag to the `configure` command below.
|
||||
|
||||
If you have both Homebrew installations installed, make sure that you are accessing the correct packages by temporarily (!) prepending it to the path:
|
||||
- Install MATLAB and additional toolboxes. We recommend, but don't require, the following: Optimization, Global Optimization, Statistics and Machine Learning, Econometrics, and Control System. As there is no ARM version of MATLAB yet, Rosetta 2 will be used on Apple Silicon machines. Don't forget to run MATLAB at least once to make sure you have a valid license.
|
||||
|
||||
- Compile and install SLICOT, needed for the `kalman_steady_state` MEX file.
|
||||
```sh
|
||||
export PATH="$BREWDIR/bin:$PATH"
|
||||
```
|
||||
|
||||
|
||||
- Install required Homebrew packages:
|
||||
```sh
|
||||
arch -$ARCH $BREWDIR/bin/brew install meson bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc docutils wget pkg-config git-lfs
|
||||
```
|
||||
If you are installing `git-lfs` for the first time, you need to run `git lfs install` once after installing it.
|
||||
|
||||
- Link the sphinx-doc package to be able to compile the documentation:
|
||||
```sh
|
||||
arch -$ARCH $BREWDIR/bin/brew link --force sphinx-doc
|
||||
```
|
||||
|
||||
- Install [MacTeX](http://www.tug.org/mactex/index.html) using the universal installer, if you want to build the documentation. MacTeX runs natively on both ARM and Intel machines. On Apple Silicon, it is advised to symlink `pdflatex`, `bibtex` and `latexmk` into `/usr/local/bin`:
|
||||
```sh
|
||||
sudo ln -s /Library/TeX/texbin/pdflatex /usr/local/bin/pdflatex
|
||||
sudo ln -s /Library/TeX/texbin/bibtex /usr/local/bin/bibtex
|
||||
sudo ln -s /Library/TeX/texbin/latexmk /usr/local/bin/latexmk
|
||||
```
|
||||
If you don't have admin privileges, then you can also symlink them into `$HOME/.local/bin` and add this folder to your PATH.
|
||||
|
||||
- Install MATLAB and additional toolboxes.
|
||||
We recommend, but don't require, the following: Optimization, Global Optimization, Statistics and Machine Learning, Econometrics, and Control System.
|
||||
For Apple Silicon: MATLAB offers a native Apple silicon version (arm64) as of version R2023b, see [the official instructions](https://de.mathworks.com/support/requirements/apple-silicon.html) how to install it.
|
||||
You can also run the Intel version (x86_64) under Rosetta 2.
|
||||
Don't forget to run MATLAB at least once to make sure you have a valid license.
|
||||
|
||||
- Create a folder for Dynare and its dependencies
|
||||
```sh
|
||||
export DYNAREDIR=$HOME/dynare
|
||||
```
|
||||
|
||||
- Compile and install SLICOT
|
||||
```sh
|
||||
mkdir -p $DYNAREDIR/slicot/lib
|
||||
cd $DYNAREDIR/slicot
|
||||
curl -O https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
mkdir -p $HOME/dynare/slicot
|
||||
cd $HOME/dynare/slicot
|
||||
wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
tar xf slicot_5.0+20101122.orig.tar.gz
|
||||
cd slicot-5.0+20101122
|
||||
make -j$(sysctl -n hw.ncpu) FORTRAN=$BREWDIR/bin/gfortran OPTS="-O2" LOADER=gfortran lib
|
||||
cp slicot.a $DYNAREDIR/slicot/lib/libslicot_pic.a
|
||||
make -j$(sysctl -n hw.physicalcpu) FORTRAN=gfortran OPTS="-O2" LOADER=gfortran lib
|
||||
cp slicot.a /usr/local/lib/libslicot_pic.a
|
||||
make clean
|
||||
make -j$(sysctl -n hw.ncpu) FORTRAN=$BREWDIR/bin/gfortran OPTS="-O2 -fdefault-integer-8" LOADER=gfortran lib
|
||||
cp slicot.a $DYNAREDIR/slicot/lib/libslicot64_pic.a
|
||||
make -j$(sysctl -n hw.physicalcpu) FORTRAN=gfortran OPTS="-O2 -fdefault-integer-8" LOADER=gfortran lib
|
||||
cp slicot.a /usr/local/lib/libslicot64_pic.a
|
||||
cd $HOME/dynare
|
||||
```
|
||||
|
||||
- Compile and install the X-13ARIMA-SEATS Seasonal Adjustment Program
|
||||
```sh
|
||||
mkdir -p $DYNAREDIR/x13as
|
||||
cd $DYNAREDIR/x13as
|
||||
curl -O https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b60.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b60.tar.gz
|
||||
mkdir -p $HOME/dynare/x13as
|
||||
cd $HOME/dynare/x13as
|
||||
wget https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b58.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b58.tar.gz
|
||||
sed -i '' 's/-static//g' makefile.gf
|
||||
make -j$(sysctl -n hw.ncpu) -f makefile.gf FC=$BREWDIR/bin/gfortran LINKER=$BREWDIR/bin/gcc-13 FFLAGS="-O2 -std=legacy" LDFLAGS=-static-libgcc LIBS="$BREWDIR/lib/gcc/current/libgfortran.a /$BREWDIR/lib/gcc/current/libquadmath.a" PROGRAM=x13as
|
||||
sudo cp $DYNAREDIR/x13as/x13as /usr/local/bin/x13as
|
||||
cd $DYNAREDIR
|
||||
make -j$(sysctl -n hw.physicalcpu) -f makefile.gf FC=gfortran LINKER=gfortran FFLAGS="-O2 -std=legacy" PROGRAM=x13as
|
||||
cp x13as /usr/local/bin/x13as
|
||||
cd ;
|
||||
x13as
|
||||
```
|
||||
Alternatively, if you don't have admin privileges you can install it into `$HOME/.local/bin` and add this folder to your PATH.
|
||||
|
||||
### Compile Dynare from source
|
||||
The following commands will download the Dynare source code and compile
|
||||
it. They should be entered at the command prompt in Terminal.app from the
|
||||
folder where you want Dynare installed.
|
||||
folder where you want Dynare installed. Apple Silicon: make sure `brew`
|
||||
points towards `/usr/local/bin/brew` (see above).
|
||||
|
||||
- Prepare the Dynare sources for the unstable version:
|
||||
```sh
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git $DYNAREDIR/unstable
|
||||
cd $DYNAREDIR/unstable
|
||||
mkdir -p $HOME/dynare/unstable
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git $HOME/dynare/unstable
|
||||
cd $HOME/dynare/unstable
|
||||
arch -x86_64 autoreconf -si
|
||||
```
|
||||
If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command.
|
||||
You can also choose a specific version of Dynare by checking out the corresponding branch or a specific tag with git.
|
||||
|
||||
- Configure Dynare from the source directory:
|
||||
```sh
|
||||
export BUILDDIR=build-matlab
|
||||
export MATLABPATH=/Applications/MATLAB_R2023b.app
|
||||
arch -$ARCH meson setup --native-file macOS/homebrew-native-$ARCH.ini -Dmatlab_path=$MATLABPATH -Dbuildtype=debugoptimized -Dfortran_args="['-B','$DYNAREDIR/slicot/lib']" $BUILDDIR
|
||||
arch -x86_64 ./configure CC=gcc-12 CXX=g++-12 CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib LEX=/usr/local/opt/flex/bin/flex YACC=/usr/local/opt/bison/bin/bison --with-matlab=/Applications/MATLAB_R2021b.app
|
||||
```
|
||||
where you need to adapt the path to MATLAB.
|
||||
Similarly, if you want to compile for Octave, replace the `-Dmatlab_path` option by `-Dbuild_for=octave`, and change the build directory to `build-octave`.
|
||||
where you need to adapt the path to MATLAB. If you don’t have MATLAB, simply replace `--with-matlab=<…>` by `--disable-matlab`. Check the output of the command whether Dynare is configured for building everything except the internal docs of Dynare and M2HTML.
|
||||
|
||||
- Compile:
|
||||
```sh
|
||||
arch -$ARCH meson compile -C $BUILDDIR
|
||||
arch -x86_64 make -j$(sysctl -n hw.physicalcpu)
|
||||
```
|
||||
If no errors occured, you are done. Dynare is now ready to use.
|
||||
|
||||
- If you additionally want to compile the documentation run:
|
||||
```sh
|
||||
arch -$ARCH meson compile -C $BUILDDIR doc
|
||||
```
|
||||
|
||||
- Optionally, run the testsuite:
|
||||
```sh
|
||||
arch -$ARCH meson test -C $BUILDDIR --num-processes=$(sysctl -n hw.perflevel0.physicalcpu)
|
||||
```
|
||||
where `--num-processes` specifies the number of parallel processes to use for the testsuite (here set to the number of performance cores on your mac).
|
||||
|
||||
### Optional: pass the full PATH to MATLAB to run system commands
|
||||
If you start MATLAB from a terminal, you will get the PATH inherited from the shell.
|
||||
However, when you click on the application icon in macOS, you are not running at the terminal level:
|
||||
the program is run by launcher, which does not go through a shell login session.
|
||||
In other words, you get the system default PATH which includes `/usr/bin:/bin:/usr/sbin:/sbin`, but not `/usr/local/bin` or `$HOME/.local/bin`.
|
||||
So if you want to use system commands like `pdflatex`, `latexmk` or `x13as` you should either call them by their full path (e.g `/Library/TeX/texbin/pdflatex`)
|
||||
or append the PATH by running `setenv('PATH', [getenv('PATH') ':/usr/local/bin:$HOME/.local/bin:/Library/TeX/texbin']);` in your MATLAB command line once,
|
||||
e.g. by adding this to your mod file. Alternatively, you can create a `startup.m` file or change the system default PATH in the `/etc/paths` file.
|
||||
If you start MATLAB from a terminal, you will get the PATH inherited from the shell. However, when you click on the icon in macOS, you are not running at the terminal: the program is run by launcher, which does not go through a shell login session. You get the system default PATH which includes `/usr/bin:/bin:/usr/sbin:/sbin`, but not `/usr/local/bin` or `$HOME/.local/bin`. So if you want to use system commands like `pdflatex` or `x13as` you should either call them by their full path (e.g `/Library/TeX/texbin/pdflatex`) or append the PATH in MATLAB by running `setenv('PATH', [getenv('PATH') ':/usr/local/bin:$HOME/.local/bin:/Library/TeX/texbin']);`. Alternatively, you can create a `startup.m` file or change the system default PATH in the `/etc/paths` file.
|
||||
|
||||
|
||||
## Docker
|
||||
We offer a variety of pre-configured Docker containers for Dynare, pre-configured with Octave and MATLAB including all recommended toolboxes.
|
||||
These are readily available for your convenience on [Docker Hub](https://hub.docker.com/r/dynare/dynare).
|
||||
The `scripts/docker` folder contains [information and instructions](scripts/docker/README.md) to interact, built and customize the containers.
|
||||
Tested on
|
||||
- macOS Monterey 12.1 (Apple M1 Virtual Machine)
|
||||
- macOS Monterey 12.1 (MacBook Air Intel)
|
||||
- macOS Monterey 12.1 (MacBook Air M1)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
@PACKAGE_VERSION@
|
|
@ -0,0 +1,151 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
dnl Copyright © 2009-2023 Dynare Team
|
||||
dnl
|
||||
dnl This file is part of Dynare.
|
||||
dnl
|
||||
dnl Dynare is free software: you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation, either version 3 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl Dynare is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AC_PREREQ([2.62])
|
||||
AC_INIT([dynare], [6-unstable])
|
||||
AC_CONFIG_SRCDIR([preprocessor/src/DynareMain.cc])
|
||||
AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax])
|
||||
|
||||
AC_CONFIG_SUBDIRS([preprocessor])
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
case ${host_os} in
|
||||
*cygwin*)
|
||||
AC_MSG_WARN([You are compiling for the Cygwin target. This means that the preprocessor will])
|
||||
AC_MSG_WARN([not run from MATLAB unless you add the Cygwin DLL to the path.])
|
||||
AC_MSG_WARN([This is probably not what you want. Consider using a MinGW cross-compiler.])
|
||||
if test -z "$F77"; then
|
||||
# On Cygwin 1.7, g77 comes has version 3, and is not compatible with default gcc/g++ which has version 4
|
||||
# And by default, the AC_PROG_F77 will pick up g77 if it is present (even if gfortran is also here)
|
||||
F77=gfortran
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Use C++ for testing headers
|
||||
AC_LANG([C++])
|
||||
|
||||
AM_CXXFLAGS="-std=gnu++20 -Wall -Wno-dangling-else -Wextra -Wno-unused-parameter -Wold-style-cast"
|
||||
AC_SUBST([AM_CXXFLAGS])
|
||||
|
||||
# If default 'ar' is not available, try to find one with a host prefix (see ticket #145)
|
||||
AC_CHECK_PROGS([AR], [ar ${host_alias}-ar])
|
||||
|
||||
AC_PROG_RANLIB
|
||||
AM_PROG_AR
|
||||
|
||||
AX_PROG_LN_S
|
||||
|
||||
AC_PROG_MKDIR_P
|
||||
|
||||
# Define optional components and their corresponding flags and Automake conditionals
|
||||
AC_ARG_ENABLE([doc], AS_HELP_STRING([--disable-doc], [disable compilation of documentation]), [], [enable_doc=yes])
|
||||
AM_CONDITIONAL([ENABLE_DOC], [test "$enable_doc" = yes])
|
||||
|
||||
AC_ARG_ENABLE([matlab], AS_HELP_STRING([--disable-matlab], [disable compilation of MEX files for MATLAB]), [], [enable_matlab=yes])
|
||||
AM_CONDITIONAL([ENABLE_MATLAB], [test "$enable_matlab" = yes])
|
||||
|
||||
AC_ARG_ENABLE([octave], AS_HELP_STRING([--disable-octave], [disable compilation of MEX files for Octave]), [], [enable_octave=yes])
|
||||
AM_CONDITIONAL([ENABLE_OCTAVE], [test "$enable_octave" = yes])
|
||||
|
||||
AC_ARG_ENABLE([org-export], AS_HELP_STRING([--enable-org-export], [enable exporting of Org files (requires Emacs, org-mode and other external programs)]))
|
||||
AM_CONDITIONAL([ENABLE_ORG_EXPORT], [test -n "$enable_org_export"])
|
||||
|
||||
# Check utilities needed for documentation
|
||||
if test "$enable_doc" = yes; then
|
||||
AC_CHECK_PROG([PDFLATEX], [pdflatex], [pdflatex], [no])
|
||||
test "$PDFLATEX" = no && AC_MSG_ERROR([pdflatex cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])
|
||||
AC_CHECK_PROG([BIBTEX], [bibtex], [bibtex], [no])
|
||||
test "$BIBTEX" = no && AC_MSG_ERROR([bibtex cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])
|
||||
AC_CHECK_PROG([SPHINXBUILD], [sphinx-build], [sphinx-build], [no])
|
||||
test "$SPHINXBUILD" = no && AC_MSG_ERROR([sphinx-build cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])
|
||||
AX_LATEX_CLASS([beamer], [ax_latex_have_beamer], [], [AC_MSG_ERROR([beamer cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])])
|
||||
fi
|
||||
|
||||
# Check for MATLAB
|
||||
if test "$enable_matlab" = yes; then
|
||||
AC_CONFIG_SUBDIRS([mex/build/matlab])
|
||||
AX_MATLAB
|
||||
AX_MATLAB_BATCH_OPTIONS
|
||||
test "$ax_enable_matlab" != yes && AC_MSG_ERROR([MATLAB cannot be found. If you want to compile Dynare without MATLAB support, pass the --disable-matlab flag.])
|
||||
fi
|
||||
|
||||
# Check for Octave
|
||||
if test "$enable_octave" = yes; then
|
||||
AC_CONFIG_SUBDIRS([mex/build/octave])
|
||||
AX_OCTAVE
|
||||
test "$ax_enable_octave" != yes && AC_MSG_ERROR([Octave cannot be found. If you want to compile Dynare without Octave support, pass the --disable-octave flag.])
|
||||
fi
|
||||
|
||||
# Construct final output message
|
||||
if test "$enable_doc" = yes; then
|
||||
BUILD_DOC="yes"
|
||||
else
|
||||
BUILD_DOC="no"
|
||||
fi
|
||||
|
||||
if test -n "$enable_org_export"; then
|
||||
BUILD_INTERNAL_DOC="yes"
|
||||
else
|
||||
BUILD_INTERNAL_DOC="no"
|
||||
fi
|
||||
|
||||
if test "$enable_matlab" = yes; then
|
||||
TESTSUITE_MATLAB="yes"
|
||||
else
|
||||
TESTSUITE_MATLAB="no"
|
||||
fi
|
||||
|
||||
if test "$enable_octave" = yes; then
|
||||
TESTSUITE_OCTAVE="yes"
|
||||
else
|
||||
TESTSUITE_OCTAVE="no"
|
||||
fi
|
||||
|
||||
AC_MSG_NOTICE([
|
||||
|
||||
Dynare is now configured for building the following components...
|
||||
|
||||
Documentation (with "make html pdf"):
|
||||
Manual and other documents $BUILD_DOC
|
||||
Dynare internal doc: $BUILD_INTERNAL_DOC
|
||||
|
||||
Testsuites (run with "make check"):
|
||||
Dynare for MATLAB: $TESTSUITE_MATLAB
|
||||
Dynare for Octave: $TESTSUITE_OCTAVE
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
VERSION
|
||||
doc/Makefile
|
||||
doc/manual/Makefile
|
||||
doc/manual/utils/version.py
|
||||
doc/parallel/Makefile
|
||||
doc/internals/Makefile
|
||||
doc/gsa/Makefile
|
||||
doc/dseries-and-reporting/Makefile
|
||||
tests/Makefile
|
||||
matlab/dynare_version.m
|
||||
mex/sources/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 5a58fafdca239e61be4d7b2270307b2445bb571a
|
|
@ -1 +1 @@
|
|||
Subproject commit 391689d9f1bea4bd68ef6641dc2dc4a1bd867850
|
||||
Subproject commit f1d0fd61ea6d9c4f8694b373780d6c372e344f6e
|
|
@ -1 +1 @@
|
|||
Subproject commit ac6d0ae1b69cda26aa9486188d54c8c010f115c4
|
||||
Subproject commit 216abedb9ab4df5dd4dca07c721f7c07392801e9
|
|
@ -0,0 +1,26 @@
|
|||
SUBDIRS = parallel internals gsa dseries-and-reporting
|
||||
|
||||
if ENABLE_DOC
|
||||
SUBDIRS += manual
|
||||
pdf-local: guide.pdf bvar-a-la-sims.pdf dr.pdf
|
||||
endif
|
||||
|
||||
EXTRA_DIST = guide.tex guide.bbl bibmad.sty bvar-a-la-sims.tex dr.tex dr.bib dynare.plots
|
||||
|
||||
guide.pdf: guide.tex guide.bbl bibmad.sty
|
||||
$(PDFLATEX) guide
|
||||
$(PDFLATEX) guide
|
||||
|
||||
bvar-a-la-sims.pdf: bvar-a-la-sims.tex
|
||||
$(PDFLATEX) bvar-a-la-sims
|
||||
$(PDFLATEX) bvar-a-la-sims
|
||||
|
||||
dr.pdf: dr.tex
|
||||
$(PDFLATEX) dr
|
||||
$(BIBTEX) dr
|
||||
$(PDFLATEX) dr
|
||||
$(PDFLATEX) dr
|
||||
|
||||
clean-local:
|
||||
# Do not delete guide.bbl which is not autogenerated
|
||||
rm -f *~ *.pdf *.log *.aux *.out *.blg dr.bbl
|
|
@ -0,0 +1,105 @@
|
|||
\message{harvard bibliography,}
|
||||
|
||||
\def\@hiteml[#1]#2#3#4{\item[]\if@filesw%
|
||||
{ \def\protect##1{\string ##1\space}\immediate%
|
||||
\write\@auxout{\string\harvardcite{#4}{#2}{#1}{#3}}}\fi%
|
||||
\protect\hspace*{-\labelwidth}\protect\hspace*{-\labelsep}\ignorespaces}
|
||||
|
||||
\def\@hitem#1#2#3{\item[]\if@filesw%
|
||||
{ \def\protect##1{\string ##1\space}\immediate%
|
||||
\write\@auxout{\string\harvardcite{#3}{#1}{#1}{#2}}}\fi%
|
||||
\protect\hspace*{-\labelwidth}\protect\hspace*{-\labelsep}\ignorespaces}
|
||||
|
||||
\def\harvarditem{\@ifnextchar [{\@hiteml}{\@hitem}}
|
||||
|
||||
\def\harvardcite#1#2#3#4{
|
||||
\global\@namedef{bhf@#1}{#2}
|
||||
\global\@namedef{bha@#1}{#3}
|
||||
\global\@namedef{bhy@#1}{#4}\global\@namedef{b@#1}{\csname bhf@#1\endcsname}
|
||||
}
|
||||
|
||||
\def\citeasnoun{\@ifnextchar [{\@tempswatrue\@citex}{\@tempswafalse\@citex[]}}
|
||||
\def\cite{\@ifnextchar [{\@tempswatrue\@citexasnoun}
|
||||
{\@tempswafalse\@citexasnoun[]}
|
||||
}
|
||||
\def\citeyear{\@ifnextchar [{\@tempswatrue\@citexyear}
|
||||
{\@tempswafalse\@citexyear[]}
|
||||
}
|
||||
\def\citename{\@ifnextchar [{\@tempswatrue\@citexname}
|
||||
{\@tempswafalse\@citexname[]}
|
||||
}
|
||||
|
||||
% \def\@enamedef#1{\expandafter\edef\csname #1\endcsname}
|
||||
% Previous line should be replaced by the following to prevent
|
||||
% problems with the NFSS. Solution by Bernd Raichle.
|
||||
\def\@enamedef#1{\expandafter\def\csname #1\expandafter\endcsname\expandafter}
|
||||
|
||||
\def\@citex[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi
|
||||
\def\@citea{}\@cite{\@for\@citeb:=#2\do
|
||||
{\@citea\def\@citea{\@hisep\penalty\@m\ }\@ifundefined
|
||||
{b@\@citeb}{{\bf ?}\@warning
|
||||
{Citation `\@citeb' on page \thepage \space undefined}}%
|
||||
{{\csname b@\@citeb\endcsname\@hysep\csname bhy@\@citeb\endcsname}%
|
||||
\global\@enamedef{b@\@citeb}{\csname bha@\@citeb\endcsname}}%
|
||||
}}{#1}}
|
||||
|
||||
\def\@citexasnoun[#1]#2{%
|
||||
\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi%
|
||||
\@citeasnoun{{\@ifundefined%
|
||||
{b@#2}%
|
||||
{[{\bf ?}\@warning{Citation `#2' on page \thepage \space undefined}}%
|
||||
{{\csname b@#2\endcsname\ [\csname bhy@#2\endcsname}%
|
||||
\global\@namedef{b@#2}{\csname bha@#2\endcsname}}%
|
||||
}}{#1}}
|
||||
|
||||
\def\@citexname[#1]#2{%
|
||||
\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi%
|
||||
\@citename{{\@ifundefined%
|
||||
{b@#2}%
|
||||
{{\bf ?}\@warning{Citation `#2' on page \thepage \space undefined}}%
|
||||
{{\csname bhf@#2\endcsname}}%
|
||||
}}{#1}}
|
||||
|
||||
\def\@citexyear[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi
|
||||
\def\@citeayear{}\@cite{\@for\@citebyear:=#2\do
|
||||
{\@citeayear\def\@citeayear{\@hisep\penalty\@m\ }\@ifundefined
|
||||
{b@\@citebyear}{{\bf ?}\@warning
|
||||
{Citation `\@citebyear' on page \thepage \space undefined}}%
|
||||
{{\csname bhy@\@citebyear\endcsname}%
|
||||
}%
|
||||
}}{#1}}
|
||||
|
||||
\gdef\hysep@agsm{\ }\gdef\hisep@agsm{,}%
|
||||
\gdef\hysep@dcu{, }\gdef\hisep@dcu{;}%
|
||||
\let\@hysep\hysep@agsm \let\@hisep\hisep@agsm
|
||||
\def\citationstyle#1{%
|
||||
\global\@namedef{@hysep}{\csname hysep@#1\endcsname}%
|
||||
\global\@namedef{@hisep}{\csname hisep@#1\endcsname}}
|
||||
|
||||
%DEFAULT DEFINITIONS
|
||||
\def\@cite#1#2{({#1\if@tempswa , #2\fi})}
|
||||
\def\@citeasnoun#1#2{{#1\if@tempswa , #2\fi]}}
|
||||
\def\@citename#1#2{{#1\if@tempswa \ (#2)\fi}}
|
||||
|
||||
% CHANGE \end{document} - to handle double definitions
|
||||
\def\enddocument{\@checkend{document}\clearpage\begingroup
|
||||
\if@filesw \immediate\closeout\@mainaux
|
||||
\def\global\@namedef##1##2{}\def\newlabel{\@testdef r}%
|
||||
\def\bibcite{\@testdef b}%
|
||||
\def\harvardcite{\@testbibh}\@tempswafalse \makeatletter\input \jobname.aux
|
||||
\if@tempswa \@warning{Label(s) may have changed. Rerun to get
|
||||
cross-references right}\fi\fi\endgroup\deadcycles\z@\@@end}
|
||||
|
||||
\def\@testbibh #1#2#3{
|
||||
\def\@tempa{#2}\expandafter
|
||||
\ifx \csname bhf@#1\endcsname \@tempa
|
||||
\def\@tempa{#3}\expandafter
|
||||
\ifx \csname bha@#1\endcsname \@tempa
|
||||
\else \@tempswatrue
|
||||
\fi
|
||||
\else
|
||||
\@tempswatrue
|
||||
\fi
|
||||
}
|
||||
|
||||
%
|
|
@ -26,7 +26,7 @@
|
|||
}}
|
||||
|
||||
\author{S\'ebastien Villemot\thanks{Paris School of Economics and
|
||||
CEPREMAP.} \and Johannes Pfeifer\thanks{University of the Bundeswehr Munich. E-mail: \href{mailto:johannes.pfeifer@unibw.de}{\texttt{johannes.pfeifer@unibw.de}}.}}
|
||||
CEPREMAP.} \and Johannes Pfeifer\thanks{Universität der Bundeswehr München. E-mail: \href{mailto:johannes.pfeifer@unibw.de}{\texttt{johannes.pfeifer@unibw.de}}.}}
|
||||
\date{First version: September 2007 \hspace{1cm} This version: May 2017}
|
||||
|
||||
\maketitle
|
||||
|
|
|
@ -650,7 +650,7 @@ equation is:
|
|||
In the general case, this equation is a specialized Sylvester equation, which
|
||||
can be solved using the algorithm proposed by
|
||||
\citet{kamenik:2004}\footnote{This paper is distributed with Dynare, in the
|
||||
\texttt{sylvester.pdf} file under the documentation directory.}.
|
||||
\texttt{sylvester.pdf} file under the Dynare++ documentation directory.}.
|
||||
|
||||
\bibliographystyle{elsarticle-harv}
|
||||
\bibliography{dr}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
if ENABLE_DOC
|
||||
pdf-local: dseriesReporting.pdf
|
||||
endif
|
||||
|
||||
SRC = dseriesReporting.tex
|
||||
|
||||
EXTRA_DIST = $(SRC)
|
||||
|
||||
dseriesReporting.pdf: $(SRC)
|
||||
$(PDFLATEX) dseriesReporting
|
||||
$(PDFLATEX) dseriesReporting
|
||||
|
||||
clean-local:
|
||||
rm -f dseriesReporting.pdf *.toc *.aux *.log *.nav *.snm *.vrb *.out *~
|
|
@ -0,0 +1,16 @@
|
|||
if ENABLE_DOC
|
||||
pdf-local: gsa.pdf
|
||||
endif
|
||||
|
||||
SRC = gsa.tex marco.bib
|
||||
|
||||
EXTRA_DIST = $(SRC)
|
||||
|
||||
gsa.pdf: $(SRC)
|
||||
$(PDFLATEX) gsa
|
||||
$(BIBTEX) gsa
|
||||
$(PDFLATEX) gsa
|
||||
$(PDFLATEX) gsa
|
||||
|
||||
clean-local:
|
||||
rm -f *.pdf *.log *.aux *.toc *.lof *.blg *.bbl *.out *~
|
139
doc/gsa/gsa.tex
139
doc/gsa/gsa.tex
|
@ -22,7 +22,7 @@
|
|||
\begin{document}
|
||||
|
||||
% ----------------------------------------------------------------
|
||||
\title{Sensitivity Analysis Toolbox for Dynare\thanks{Copyright \copyright~2012-2024 Dynare
|
||||
\title{Sensitivity Analysis Toolbox for DYNARE\thanks{Copyright \copyright~2012 Dynare
|
||||
Team. Permission is granted to copy, distribute and/or modify
|
||||
this document under the terms of the GNU Free Documentation
|
||||
License, Version 1.3 or any later version published by the Free
|
||||
|
@ -32,9 +32,9 @@
|
|||
|
||||
\author{Marco Ratto\\
|
||||
European Commission, Joint Research Centre \\
|
||||
TP581\\21027 Ispra
|
||||
TP361, IPSC, \\21027 Ispra
|
||||
(VA) Italy\\
|
||||
\texttt{Marco.Ratto@ec.europa.eu}
|
||||
\texttt{marco.ratto@jrc.ec.europa.eu}
|
||||
\thanks{The author gratefully thanks Christophe Planas, Kenneth Judd, Michel Juillard,
|
||||
Alessandro Rossi, Frank Schorfheide and the participants to the
|
||||
Courses on Global Sensitivity Analysis for Macroeconomic
|
||||
|
@ -52,21 +52,21 @@ helpful suggestions.}}
|
|||
|
||||
%-----------------------------------------------------------------------
|
||||
\begin{abstract}
|
||||
\noindent The Sensitivity Analysis Toolbox for Dynare is a set of
|
||||
\noindent The Sensitivity Analysis Toolbox for DYNARE is a set of
|
||||
MATLAB routines for the analysis of DSGE models with global
|
||||
sensitivity analysis. The routines are thought to be used within
|
||||
the Dynare 6 environment.
|
||||
the DYNARE v4 environment.
|
||||
|
||||
|
||||
\begin{description}
|
||||
\item \textbf{Keywords}: Stability Mapping , Reduced form solution, DSGE models,
|
||||
Monte Carlo filtering, Global Sensitivity Analysis.
|
||||
Monte Carlo filtering, Global Sensitivity Analysis.
|
||||
\end{description}
|
||||
\end{abstract}
|
||||
\newpage
|
||||
% ----------------------------------------------------------------
|
||||
\section{Introduction} \label{s:intro}
|
||||
The Sensitivity Analysis Toolbox for Dynare is a collection of
|
||||
The Sensitivity Analysis Toolbox for DYNARE is a collection of
|
||||
MATLAB routines implemented to answer the following questions: (i)
|
||||
Which is the domain of structural coefficients assuring the
|
||||
stability and determinacy of a DSGE model? (ii) Which parameters
|
||||
|
@ -81,18 +81,20 @@ described in \cite{Ratto_CompEcon_2008}.
|
|||
|
||||
|
||||
\section{Use of the Toolbox}
|
||||
The Dynare parser now recognizes sensitivity analysis commands.
|
||||
The DYNARE parser now recognizes sensitivity analysis commands.
|
||||
The syntax is based on a single command:
|
||||
\vspace{0.5cm}
|
||||
|
||||
\verb"sensitivity(option1=<opt1_val>,option2=<opt2_val>,...)"
|
||||
\verb"dynare_sensitivity(option1=<opt1_val>,option2=<opt2_val>,...)"
|
||||
|
||||
\vspace{0.5cm} \noindent with a list of options described in the
|
||||
next section.
|
||||
|
||||
In order to work properly, the sensitivity analysis Toolbox does not need
|
||||
a Dynare estimation environment to be set up. Rather, \verb"sensitivity"
|
||||
is the only command to run to
|
||||
With respect to the previous version of the toolbox, in order to
|
||||
work properly, the sensitivity analysis Toolbox \emph{no longer}
|
||||
needs that the DYNARE estimation environment is set-up.
|
||||
|
||||
Therefore, \verb"dynare_sensitivity" is the only command to run to
|
||||
make a sensitivity analysis on a DSGE model\footnote{Of course,
|
||||
when the user needs to perform the mapping of the fit with a
|
||||
posterior sample, a Bayesian estimation has to be performed
|
||||
|
@ -206,17 +208,16 @@ a multivariate normal MC sample, with covariance matrix based on
|
|||
the inverse Hessian at the optimum: this analysis is useful when
|
||||
ML estimation is done (i.e. no Bayesian estimation);
|
||||
\item when \verb"ppost=1" the Toolbox analyses
|
||||
the RMSE's for the posterior sample obtained by Dynare's
|
||||
the RMSE's for the posterior sample obtained by DYNARE's
|
||||
Metropolis procedure.
|
||||
\end{enumerate}
|
||||
|
||||
The use of cases 2. and 3. require an estimation step beforehand!
|
||||
The use of cases 2. and 3. requires an estimation step beforehand!
|
||||
To facilitate the sensitivity analysis after estimation, the
|
||||
\verb"sensitivity" command also allows to indicate some
|
||||
options of \verb"estimation". These are:
|
||||
\verb"dynare_sensitivity" command also allows to indicate some
|
||||
options of \verb"dynare_estimation". These are:
|
||||
\begin{itemize}
|
||||
\item \verb"datafile"
|
||||
\item \verb"diffuse_filter"
|
||||
\item \verb"mode_file"
|
||||
\item \verb"first_obs"
|
||||
\item \verb"lik_init"
|
||||
|
@ -277,10 +278,10 @@ identifiable.
|
|||
\end{tabular}
|
||||
|
||||
\vspace{1cm}
|
||||
\noindent For example, the following commands in the Dynare model file
|
||||
\noindent For example, the following commands in the DYNARE model file
|
||||
|
||||
\vspace{1cm}
|
||||
\noindent\verb"sensitivity(identification=1, morris=2);"
|
||||
\noindent\verb"dynare_sensitivity(identification=1, morris=2);"
|
||||
|
||||
\vspace{1cm}
|
||||
\noindent trigger the identification analysis using \cite{Iskrev2010,Iskrev2011}, jointly with the mapping of the acceptable region.
|
||||
|
@ -292,75 +293,75 @@ Sensitivity analysis results are saved on the hard-disk of the
|
|||
computer. The Toolbox uses a dedicated folder called \verb"GSA",
|
||||
located in \\
|
||||
\\
|
||||
\verb"<Dynare_file>\GSA", \\
|
||||
\verb"<DYNARE_file>\GSA", \\
|
||||
\\
|
||||
where \verb"<Dynare_file>.mod" is the name of the Dynare model
|
||||
where \verb"<DYNARE_file>.mod" is the name of the DYNARE model
|
||||
file.
|
||||
|
||||
\subsection{Binary data files}
|
||||
A set of binary data files is saved in the \verb"GSA" folder:
|
||||
\begin{description}
|
||||
\item[]\verb"<Dynare_file>_prior.mat": this file stores
|
||||
\item[]\verb"<DYNARE_file>_prior.mat": this file stores
|
||||
information about the analyses performed sampling from the prior
|
||||
ranges, i.e. \verb"pprior=1" and \verb"ppost=0";
|
||||
\item[]\verb"<Dynare_file>_mc.mat": this file stores
|
||||
\item[]\verb"<DYNARE_file>_mc.mat": this file stores
|
||||
information about the analyses performed sampling from
|
||||
multivariate normal, i.e. \verb"pprior=0" and \verb"ppost=0";
|
||||
\item[]\verb"<Dynare_file>_post.mat": this file stores information
|
||||
\item[]\verb"<DYNARE_file>_post.mat": this file stores information
|
||||
about analyses performed using the Metropolis posterior sample,
|
||||
i.e. \verb"ppost=1".
|
||||
\end{description}
|
||||
|
||||
\begin{description}
|
||||
\item[]\verb"<Dynare_file>_prior_*.mat": these files store
|
||||
\item[]\verb"<DYNARE_file>_prior_*.mat": these files store
|
||||
the filtered and smoothed variables for the prior MC sample,
|
||||
generated when doing RMSE analysis (\verb"pprior=1" and
|
||||
\verb"ppost=0");
|
||||
\item[]\verb"<Dynare_file>_mc_*.mat": these files store
|
||||
\item[]\verb"<DYNARE_file>_mc_*.mat": these files store
|
||||
the filtered and smoothed variables for the multivariate normal MC
|
||||
sample, generated when doing RMSE analysis (\verb"pprior=0" and
|
||||
\verb"ppost=0").
|
||||
\end{description}
|
||||
|
||||
\subsection{Stability analysis}
|
||||
Figure files \verb"<Dynare_file>_prior_*.fig" store results for
|
||||
Figure files \verb"<DYNARE_file>_prior_*.fig" store results for
|
||||
the stability mapping from prior MC samples:
|
||||
\begin{description}
|
||||
\item[]\verb"<Dynare_file>_prior_stab_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the CDF of the sample fulfilling
|
||||
Blanchard-Kahn conditions with the CDF of the rest of the sample;
|
||||
\item[]\verb"<Dynare_file>_prior_stab_indet_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the CDF of the sample producing
|
||||
indeterminacy with the CDF of the original prior sample;
|
||||
\item[]\verb"<Dynare_file>_prior_stab_unst_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the CDF of the sample producing unstable
|
||||
(explosive roots) behaviour with the CDF of the original prior
|
||||
\item[]\verb"<DYNARE_file>_prior_stab_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the cdf of the sample fulfilling
|
||||
Blanchard-Kahn conditions with the cdf of the rest of the sample;
|
||||
\item[]\verb"<DYNARE_file>_prior_stab_indet_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the cdf of the sample producing
|
||||
indeterminacy with the cdf of the original prior sample;
|
||||
\item[]\verb"<DYNARE_file>_prior_stab_unst_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the cdf of the sample producing unstable
|
||||
(explosive roots) behaviour with the cdf of the original prior
|
||||
sample;
|
||||
\item[]\verb"<Dynare_file>_prior_stable_corr_*.fig": plots of
|
||||
\item[]\verb"<DYNARE_file>_prior_stable_corr_*.fig": plots of
|
||||
bivariate projections of the sample fulfilling Blanchard-Kahn
|
||||
conditions;
|
||||
\item[]\verb"<Dynare_file>_prior_indeterm_corr_*.fig": plots of
|
||||
\item[]\verb"<DYNARE_file>_prior_indeterm_corr_*.fig": plots of
|
||||
bivariate projections of the sample producing indeterminacy;
|
||||
\item[]\verb"<Dynare_file>_prior_unstable_corr_*.fig": plots of
|
||||
\item[]\verb"<DYNARE_file>_prior_unstable_corr_*.fig": plots of
|
||||
bivariate projections of the sample producing instability;
|
||||
\item[]\verb"<Dynare_file>_prior_unacceptable_corr_*.fig": plots of
|
||||
\item[]\verb"<DYNARE_file>_prior_unacceptable_corr_*.fig": plots of
|
||||
bivariate projections of the sample producing unacceptable
|
||||
solutions, i.e. either instability or indeterminacy or the
|
||||
solution could not be found (e.g. the steady state solution could
|
||||
not be found by the solver).
|
||||
\end{description}
|
||||
Similar conventions apply for \verb"<Dynare_file>_mc_*.fig" files,
|
||||
Similar conventions apply for \verb"<DYNARE_file>_mc_*.fig" files,
|
||||
obtained when samples from multivariate normal are used.
|
||||
|
||||
\subsection{RMSE analysis}
|
||||
Figure files \verb"<Dynare_file>_rmse_*.fig" store results for the
|
||||
Figure files \verb"<DYNARE_file>_rmse_*.fig" store results for the
|
||||
RMSE analysis.
|
||||
\begin{description}
|
||||
\item[]\verb"<Dynare_file>_rmse_prior*.fig": save results for
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior*.fig": save results for
|
||||
the analysis using prior MC samples;
|
||||
\item[]\verb"<Dynare_file>_rmse_mc*.fig": save results for
|
||||
\item[]\verb"<DYNARE_file>_rmse_mc*.fig": save results for
|
||||
the analysis using multivariate normal MC samples;
|
||||
\item[]\verb"<Dynare_file>_rmse_post*.fig": save results for
|
||||
\item[]\verb"<DYNARE_file>_rmse_post*.fig": save results for
|
||||
the analysis using Metropolis posterior samples.
|
||||
\end{description}
|
||||
|
||||
|
@ -368,33 +369,33 @@ The following types of figures are saved (we show prior sample to
|
|||
fix ideas, but the same conventions are used for multivariate
|
||||
normal and posterior):
|
||||
\begin{description}
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_*.fig": for each parameter, plots the CDF's
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_*.fig": for each parameter, plots the cdf's
|
||||
corresponding to the best 10\% RMES's of each observed series;
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_dens_*.fig": for each parameter, plots the pdf's
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_dens_*.fig": for each parameter, plots the pdf's
|
||||
corresponding to the best 10\% RMES's of each observed series;
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_<name of observedseries>_corr_*.fig": for each observed series plots the
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_<name of observedseries>_corr_*.fig": for each observed series plots the
|
||||
bi-dimensional projections of samples with the best 10\% RMSE's,
|
||||
when the correlation is significant;
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lnlik*.fig": for each observed
|
||||
series, plots \emph{in red} the CDF of the log-likelihood
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the CDF of
|
||||
the rest of the sample and \emph{in blue }the CDF of the full
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lnlik*.fig": for each observed
|
||||
series, plots \emph{in red} the cdf of the log-likelihood
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the cdf of
|
||||
the rest of the sample and \emph{in blue }the cdf of the full
|
||||
sample; this allows to see the presence of some idiosyncratic
|
||||
behaviour;
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lnpost*.fig": for each observed
|
||||
series, plots \emph{in red} the CDF of the log-posterior
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the CDF of
|
||||
the rest of the sample and \emph{in blue }the CDF of the full
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lnpost*.fig": for each observed
|
||||
series, plots \emph{in red} the cdf of the log-posterior
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the cdf of
|
||||
the rest of the sample and \emph{in blue }the cdf of the full
|
||||
sample; this allows to see idiosyncratic behaviour;
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lnprior*.fig": for each observed
|
||||
series, plots \emph{in red} the CDF of the log-prior corresponding
|
||||
to the best 10\% RMSE's, \emph{in green} the CDF of the rest of
|
||||
the sample and \emph{in blue }the CDF of the full sample; this
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lnprior*.fig": for each observed
|
||||
series, plots \emph{in red} the cdf of the log-prior corresponding
|
||||
to the best 10\% RMSE's, \emph{in green} the cdf of the rest of
|
||||
the sample and \emph{in blue }the cdf of the full sample; this
|
||||
allows to see idiosyncratic behaviour;
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lik_SA_*.fig": when
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lik_SA_*.fig": when
|
||||
\verb"lik_only=1", this shows the Smirnov tests for the filtering
|
||||
of the best 10\% log-likelihood values;
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_post_SA_*.fig": when
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_post_SA_*.fig": when
|
||||
\verb"lik_only=1", this shows the Smirnov test for the filtering
|
||||
of the best 10\% log-posterior values.
|
||||
\end{description}
|
||||
|
@ -404,19 +405,19 @@ In the case of the mapping of the reduced form solution, synthetic
|
|||
figures are saved in the \verb"\GSA" folder:
|
||||
|
||||
\begin{description}
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
shows bar charts of the sensitivity indices for the \emph{ten most
|
||||
important} parameters driving the reduced form coefficients of the
|
||||
selected endogenous variables (\verb"namendo") versus lagged
|
||||
endogenous variables (\verb"namlagendo"); suffix \verb"log"
|
||||
indicates the results for log-transformed entries;
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
shows bar charts of the sensitivity indices for the \emph{ten most
|
||||
important} parameters driving the reduced form coefficients of the
|
||||
selected endogenous variables (\verb"namendo") versus exogenous
|
||||
variables (\verb"namexo"); suffix \verb"log" indicates the results
|
||||
for log-transformed entries;
|
||||
\item[]\verb"<Dynare_file>_redform_GSA(_log).fig": shows bar chart of
|
||||
\item[]\verb"<DYNARE_file>_redform_GSA(_log).fig": shows bar chart of
|
||||
all sensitivity indices for each parameter: this allows to notice
|
||||
parameters that have a minor effect for \emph{any} of the reduced
|
||||
form coefficients,
|
||||
|
@ -448,24 +449,24 @@ without the need of any user's intervention.
|
|||
\subsection{Screening analysis}
|
||||
The results of the screening analysis with Morris sampling design
|
||||
are stored in the subfolder \verb"\GSA\SCREEN". The data file
|
||||
\verb"<Dynare_file>_prior" stores all the information of the
|
||||
\verb"<DYNARE_file>_prior" stores all the information of the
|
||||
analysis (Morris sample, reduced form coefficients, etc.).
|
||||
|
||||
Screening analysis merely concerns reduced form coefficients.
|
||||
Similar synthetic bar charts as for the reduced form analysis with
|
||||
MC samples are saved:
|
||||
\begin{description}
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
shows bar charts of the elementary effect tests for the \emph{ten
|
||||
most important} parameters driving the reduced form coefficients
|
||||
of the selected endogenous variables (\verb"namendo") versus
|
||||
lagged endogenous variables (\verb"namlagendo");
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
shows bar charts of the elementary effect tests for the \emph{ten
|
||||
most important} parameters driving the reduced form coefficients
|
||||
of the selected endogenous variables (\verb"namendo") versus
|
||||
exogenous variables (\verb"namexo");
|
||||
\item[]\verb"<Dynare_file>_redform_screen.fig": shows bar chart of
|
||||
\item[]\verb"<DYNARE_file>_redform_screen.fig": shows bar chart of
|
||||
all elementary effect tests for each parameter: this allows to
|
||||
identify parameters that have a minor effect for \emph{any} of the
|
||||
reduced form coefficients.
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
\ifx\undefined\bysame
|
||||
\newcommand{\bysame}{\leavevmode\hbox to\leftmargin{\hrulefill\,\,}}
|
||||
\fi
|
||||
\begin{thebibliography}{xx}
|
||||
|
||||
\harvarditem[Collard and Juillard]{Collard and Juillard}{2001}{COLL/JUIL/01a}
|
||||
{ Collard, F. and M.~Juillard}, Accuracy of stochastic perturbation methods:
|
||||
The case of asset pricing models, {\it Journal of Economic Dynamics and
|
||||
Control}, 2001, {\it 25}, 979--999.
|
||||
|
||||
\harvarditem[Schmitt-Grohe and Uribe]{Schmitt-Grohe and Uribe}{2002}{SGU/02}
|
||||
{ Schmitt-Grohe, S. and M.~Uribe}, {\it Solving Dynamic General Equilibrium
|
||||
Models Using a Second-Order Approximation to the Policy Function}, technical
|
||||
working paper, Rutgers Univsersity 2002.
|
||||
|
||||
\end{thebibliography}
|
|
@ -0,0 +1,9 @@
|
|||
EXTRA_DIST = dynare-internals.org
|
||||
|
||||
if ENABLE_ORG_EXPORT
|
||||
html-local:
|
||||
emacs --batch --visit=dynare-internals.org --funcall org-html-export-to-html
|
||||
endif
|
||||
|
||||
clean-local:
|
||||
rm -rf *.html ltxpng
|
|
@ -2,6 +2,7 @@ function build_internal_documentation()
|
|||
% The name of the function should be explicit...
|
||||
|
||||
datafiles = [];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'initialize_dataset'}];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'descriptive_statistics'}];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'compute_stdv'}];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'compute_cova'}];
|
||||
|
@ -80,4 +81,4 @@ if rows(miscfiles)
|
|||
fprintf(fid,'\n\n\n');
|
||||
end
|
||||
end
|
||||
fclose(fid);
|
||||
fclose(fid);
|
|
@ -0,0 +1,19 @@
|
|||
EXTRA_DIST = source \
|
||||
utils/dynare_dom.py \
|
||||
utils/dynare_lex.py
|
||||
|
||||
SRC = $(wildcard source/*.rst)
|
||||
|
||||
html-local: build/html/index.html
|
||||
|
||||
build/html/index.html: $(SRC) source/conf.py
|
||||
$(SPHINXBUILD) -M html source build
|
||||
|
||||
pdf-local: build/latex/dynare-manual.pdf
|
||||
|
||||
build/latex/dynare-manual.pdf: $(SRC) source/conf.py
|
||||
$(SPHINXBUILD) -M latexpdf source build
|
||||
|
||||
clean-local:
|
||||
rm -rf build
|
||||
rm -rf utils/__pycache__
|
|
@ -1,53 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="87.89pt" height="34.182pt" viewBox="0 0 87.89 34.182" version="1.1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86.514pt" height="34.182pt" viewBox="0 0 86.514 34.182" version="1.1">
|
||||
<defs>
|
||||
<g>
|
||||
<symbol overflow="visible" id="glyph0-0">
|
||||
<path style="stroke:none;" d="M 3.09375 -14.140625 L 3.6875 -13.203125 C 3.78125 -13.015625 3.921875 -12.921875 4.140625 -12.921875 C 4.21875 -12.921875 4.34375 -12.953125 4.453125 -13.03125 C 4.5625 -13.109375 4.703125 -13.203125 4.875 -13.28125 C 5.03125 -13.375 5.234375 -13.453125 5.46875 -13.53125 C 5.703125 -13.609375 5.984375 -13.640625 6.3125 -13.640625 C 6.796875 -13.640625 7.171875 -13.515625 7.484375 -13.265625 C 7.78125 -13.015625 7.9375 -12.6875 7.9375 -12.265625 C 7.9375 -11.9375 7.875 -11.640625 7.734375 -11.40625 C 7.59375 -11.171875 7.4375 -10.953125 7.234375 -10.765625 C 7.03125 -10.578125 6.828125 -10.390625 6.59375 -10.234375 C 6.375 -10.078125 6.171875 -9.90625 5.96875 -9.71875 C 5.796875 -9.546875 5.65625 -9.34375 5.53125 -9.140625 C 5.421875 -8.921875 5.390625 -8.6875 5.421875 -8.40625 L 5.578125 -6.953125 L 7.09375 -6.953125 L 7.296875 -8.25 C 7.328125 -8.4375 7.421875 -8.609375 7.5625 -8.765625 C 7.703125 -8.921875 7.875 -9.0625 8.078125 -9.234375 C 8.28125 -9.390625 8.484375 -9.546875 8.703125 -9.734375 C 8.9375 -9.90625 9.140625 -10.125 9.3125 -10.359375 C 9.515625 -10.609375 9.671875 -10.890625 9.78125 -11.21875 C 9.90625 -11.5625 9.96875 -11.9375 9.96875 -12.40625 C 9.96875 -12.859375 9.890625 -13.28125 9.71875 -13.65625 C 9.546875 -14.03125 9.3125 -14.359375 9.015625 -14.625 C 8.703125 -14.875 8.34375 -15.09375 7.9375 -15.234375 C 7.5 -15.375 7.03125 -15.453125 6.5 -15.453125 C 6.125 -15.453125 5.78125 -15.40625 5.453125 -15.34375 C 5.125 -15.28125 4.8125 -15.171875 4.53125 -15.0625 C 4.25 -14.9375 3.984375 -14.8125 3.765625 -14.640625 C 3.515625 -14.484375 3.3125 -14.328125 3.09375 -14.140625 Z M 4.90625 -3.625 C 4.90625 -3.234375 5.03125 -2.90625 5.296875 -2.65625 C 5.546875 -2.375 5.875 -2.25 6.265625 -2.25 C 6.453125 -2.25 6.625 -2.296875 6.796875 -2.359375 C 6.953125 -2.421875 7.09375 -2.53125 7.21875 -2.65625 C 7.328125 -2.78125 7.4375 -2.921875 7.515625 -3.078125 C 7.578125 -3.25 7.609375 -3.4375 7.609375 -3.625 C 7.609375 -3.796875 7.578125 -3.984375 7.515625 -4.15625 C 7.4375 -4.328125 7.328125 -4.46875 7.21875 -4.59375 C 7.09375 -4.71875 6.953125 -4.8125 6.796875 -4.875 C 6.625 -4.953125 6.453125 -5 6.265625 -5 C 5.875 -5 5.546875 -4.859375 5.296875 -4.59375 C 5.03125 -4.34375 4.90625 -4 4.90625 -3.625 Z M 0.5625 -17.75 L 0.5625 0 L 12.625 0 L 12.625 -17.75 Z M 1.171875 -0.671875 L 1.171875 -17.078125 L 11.921875 -17.078125 L 11.921875 -0.671875 Z M 1.171875 -0.671875 "/>
|
||||
<path style="stroke:none;" d="M 3.09375 -14.140625 L 3.6875 -13.203125 C 3.78125 -13.015625 3.921875 -12.921875 4.140625 -12.921875 C 4.21875 -12.921875 4.328125 -12.953125 4.453125 -13.03125 C 4.5625 -13.109375 4.703125 -13.1875 4.875 -13.28125 C 5.03125 -13.375 5.234375 -13.453125 5.46875 -13.53125 C 5.6875 -13.609375 5.96875 -13.640625 6.3125 -13.640625 C 6.796875 -13.640625 7.171875 -13.515625 7.46875 -13.265625 C 7.765625 -13.015625 7.9375 -12.6875 7.9375 -12.265625 C 7.9375 -11.9375 7.859375 -11.640625 7.734375 -11.40625 C 7.59375 -11.15625 7.4375 -10.953125 7.234375 -10.765625 C 7.03125 -10.5625 6.8125 -10.390625 6.59375 -10.234375 C 6.375 -10.0625 6.15625 -9.890625 5.96875 -9.71875 C 5.78125 -9.546875 5.640625 -9.34375 5.53125 -9.125 C 5.421875 -8.921875 5.390625 -8.671875 5.421875 -8.40625 L 5.578125 -6.953125 L 7.09375 -6.953125 L 7.296875 -8.25 C 7.328125 -8.4375 7.40625 -8.609375 7.5625 -8.765625 C 7.703125 -8.90625 7.875 -9.0625 8.078125 -9.234375 C 8.28125 -9.375 8.484375 -9.546875 8.703125 -9.734375 C 8.9375 -9.90625 9.125 -10.109375 9.3125 -10.359375 C 9.5 -10.609375 9.671875 -10.890625 9.78125 -11.21875 C 9.90625 -11.546875 9.96875 -11.9375 9.96875 -12.40625 C 9.96875 -12.859375 9.890625 -13.28125 9.71875 -13.65625 C 9.546875 -14.03125 9.3125 -14.34375 9.015625 -14.625 C 8.703125 -14.875 8.34375 -15.078125 7.921875 -15.234375 C 7.5 -15.375 7.03125 -15.453125 6.5 -15.453125 C 6.125 -15.453125 5.765625 -15.40625 5.4375 -15.34375 C 5.125 -15.265625 4.8125 -15.171875 4.53125 -15.046875 C 4.25 -14.9375 3.984375 -14.796875 3.75 -14.640625 C 3.515625 -14.484375 3.296875 -14.3125 3.09375 -14.140625 Z M 4.90625 -3.625 C 4.90625 -3.21875 5.03125 -2.90625 5.296875 -2.640625 C 5.53125 -2.375 5.875 -2.25 6.265625 -2.25 C 6.4375 -2.25 6.609375 -2.28125 6.796875 -2.359375 C 6.953125 -2.421875 7.09375 -2.53125 7.21875 -2.65625 C 7.328125 -2.78125 7.421875 -2.90625 7.5 -3.078125 C 7.578125 -3.25 7.609375 -3.421875 7.609375 -3.625 C 7.609375 -3.796875 7.578125 -3.984375 7.5 -4.15625 C 7.421875 -4.328125 7.328125 -4.46875 7.21875 -4.59375 C 7.09375 -4.71875 6.953125 -4.8125 6.796875 -4.875 C 6.609375 -4.953125 6.4375 -5 6.265625 -5 C 5.875 -5 5.53125 -4.859375 5.296875 -4.59375 C 5.03125 -4.328125 4.90625 -4 4.90625 -3.625 Z M 0.5625 -17.75 L 0.5625 0 L 12.625 0 L 12.625 -17.75 Z M 1.171875 -0.671875 L 1.171875 -17.078125 L 11.921875 -17.078125 L 11.921875 -0.671875 Z M 1.171875 -0.671875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-1">
|
||||
<path style="stroke:none;" d="M 17.546875 -8.875 C 17.546875 -10.203125 17.328125 -11.40625 16.90625 -12.5 C 16.484375 -13.59375 15.890625 -14.515625 15.125 -15.3125 C 14.359375 -16.078125 13.4375 -16.6875 12.359375 -17.125 C 11.28125 -17.546875 10.09375 -17.75 8.796875 -17.75 L 2.15625 -17.75 L 2.15625 0 L 8.796875 0 C 10.09375 0 11.28125 -0.203125 12.359375 -0.640625 C 13.4375 -1.0625 14.359375 -1.65625 15.125 -2.4375 C 15.890625 -3.21875 16.484375 -4.15625 16.90625 -5.234375 C 17.328125 -6.328125 17.546875 -7.546875 17.546875 -8.875 Z M 15.078125 -8.875 C 15.078125 -7.78125 14.9375 -6.796875 14.640625 -5.953125 C 14.34375 -5.09375 13.921875 -4.359375 13.375 -3.765625 C 12.828125 -3.1875 12.171875 -2.71875 11.390625 -2.421875 C 10.609375 -2.109375 9.75 -1.953125 8.796875 -1.953125 L 4.578125 -1.953125 L 4.578125 -15.8125 L 8.796875 -15.8125 C 9.75 -15.8125 10.609375 -15.65625 11.390625 -15.34375 C 12.171875 -15.03125 12.828125 -14.578125 13.375 -13.984375 C 13.921875 -13.375 14.34375 -12.65625 14.640625 -11.796875 C 14.9375 -10.9375 15.078125 -9.96875 15.078125 -8.875 Z M 15.078125 -8.875 "/>
|
||||
<path style="stroke:none;" d="M 17.65625 -8.875 C 17.65625 -10.203125 17.453125 -11.40625 17.03125 -12.5 C 16.609375 -13.59375 16.015625 -14.515625 15.234375 -15.296875 C 14.46875 -16.078125 13.546875 -16.6875 12.46875 -17.109375 C 11.390625 -17.53125 10.203125 -17.75 8.890625 -17.75 L 2.265625 -17.75 L 2.265625 0 L 8.890625 0 C 10.203125 0 11.390625 -0.203125 12.46875 -0.625 C 13.546875 -1.046875 14.46875 -1.65625 15.234375 -2.4375 C 16.015625 -3.203125 16.609375 -4.15625 17.03125 -5.234375 C 17.453125 -6.328125 17.65625 -7.53125 17.65625 -8.875 Z M 15.1875 -8.875 C 15.1875 -7.78125 15.046875 -6.796875 14.75 -5.953125 C 14.453125 -5.078125 14.03125 -4.359375 13.484375 -3.765625 C 12.9375 -3.171875 12.265625 -2.71875 11.5 -2.421875 C 10.71875 -2.09375 9.84375 -1.953125 8.890625 -1.953125 L 4.671875 -1.953125 L 4.671875 -15.8125 L 8.890625 -15.8125 C 9.84375 -15.8125 10.71875 -15.65625 11.5 -15.34375 C 12.265625 -15.015625 12.9375 -14.578125 13.484375 -13.984375 C 14.03125 -13.375 14.453125 -12.65625 14.75 -11.796875 C 15.046875 -10.921875 15.1875 -9.96875 15.1875 -8.875 Z M 15.1875 -8.875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-2">
|
||||
<path style="stroke:none;" d="M 5.484375 3.703125 L 12.484375 -12.546875 L 10.734375 -12.546875 C 10.59375 -12.546875 10.453125 -12.515625 10.328125 -12.421875 C 10.21875 -12.34375 10.140625 -12.234375 10.09375 -12.09375 L 6.828125 -4.203125 C 6.75 -4.015625 6.6875 -3.828125 6.625 -3.640625 C 6.5625 -3.453125 6.515625 -3.265625 6.453125 -3.078125 C 6.421875 -3.265625 6.375 -3.453125 6.3125 -3.640625 C 6.25 -3.828125 6.1875 -4 6.125 -4.1875 L 2.765625 -12.09375 C 2.71875 -12.203125 2.640625 -12.3125 2.53125 -12.421875 C 2.421875 -12.5 2.265625 -12.546875 2.078125 -12.546875 L 0.171875 -12.546875 L 5.359375 -0.734375 L 3.0625 4.25 L 4.703125 4.25 C 4.9375 4.25 5.109375 4.203125 5.203125 4.09375 C 5.328125 4 5.421875 3.859375 5.484375 3.703125 Z M 5.484375 3.703125 "/>
|
||||
<path style="stroke:none;" d="M 12.578125 -12.546875 L 10.828125 -12.546875 C 10.6875 -12.546875 10.546875 -12.5 10.421875 -12.421875 C 10.296875 -12.328125 10.21875 -12.21875 10.171875 -12.09375 L 6.90625 -4.203125 C 6.78125 -3.859375 6.65625 -3.484375 6.546875 -3.09375 C 6.4375 -3.46875 6.328125 -3.84375 6.203125 -4.1875 L 2.84375 -12.09375 C 2.796875 -12.203125 2.71875 -12.296875 2.609375 -12.40625 C 2.5 -12.5 2.359375 -12.546875 2.171875 -12.546875 L 0.265625 -12.546875 L 5.4375 -0.734375 L 3.140625 4.25 L 4.78125 4.25 C 5 4.25 5.171875 4.203125 5.296875 4.09375 C 5.40625 4 5.5 3.875 5.578125 3.703125 Z M 12.578125 -12.546875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-3">
|
||||
<path style="stroke:none;" d="M 1.8125 0 L 4.015625 0 L 4.015625 -9.25 C 4.5 -9.78125 5.015625 -10.203125 5.578125 -10.515625 C 6.140625 -10.828125 6.75 -10.984375 7.40625 -10.984375 C 8.296875 -10.984375 8.96875 -10.734375 9.390625 -10.203125 C 9.84375 -9.671875 10.046875 -8.953125 10.046875 -7.984375 L 10.046875 0 L 12.25 0 L 12.25 -7.984375 C 12.25 -8.703125 12.171875 -9.359375 11.984375 -9.9375 C 11.796875 -10.515625 11.53125 -11.03125 11.171875 -11.453125 C 10.828125 -11.859375 10.390625 -12.1875 9.859375 -12.421875 C 9.34375 -12.640625 8.734375 -12.75 8.046875 -12.75 C 7.171875 -12.75 6.390625 -12.5625 5.71875 -12.1875 C 5.046875 -11.828125 4.4375 -11.34375 3.890625 -10.734375 L 3.71875 -12.09375 C 3.625 -12.40625 3.4375 -12.546875 3.125 -12.546875 L 1.8125 -12.546875 Z M 1.8125 0 "/>
|
||||
<path style="stroke:none;" d="M 3.828125 -10.734375 L 3.65625 -12.09375 C 3.578125 -12.390625 3.375 -12.546875 3.078125 -12.546875 L 1.75 -12.546875 L 1.75 0 L 3.96875 0 L 3.96875 -9.25 C 4.4375 -9.78125 4.953125 -10.203125 5.53125 -10.515625 C 6.09375 -10.828125 6.703125 -10.984375 7.359375 -10.984375 C 8.234375 -10.984375 8.890625 -10.71875 9.328125 -10.203125 C 9.765625 -9.671875 9.984375 -8.9375 9.984375 -7.984375 L 9.984375 0 L 12.203125 0 L 12.203125 -7.984375 C 12.203125 -8.703125 12.109375 -9.34375 11.9375 -9.9375 C 11.75 -10.515625 11.46875 -11.015625 11.125 -11.4375 C 10.78125 -11.859375 10.328125 -12.1875 9.8125 -12.40625 C 9.296875 -12.625 8.6875 -12.75 8 -12.75 C 7.5625 -12.75 7.140625 -12.703125 6.75 -12.59375 C 6.375 -12.5 6.015625 -12.359375 5.65625 -12.1875 C 5.3125 -12.015625 5 -11.8125 4.703125 -11.5625 C 4.390625 -11.3125 4.09375 -11.03125 3.828125 -10.734375 Z M 3.828125 -10.734375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-4">
|
||||
<path style="stroke:none;" d="M 11.03125 0 L 11.03125 -8.03125 C 11.03125 -8.734375 10.921875 -9.375 10.75 -9.96875 C 10.5625 -10.546875 10.265625 -11.046875 9.90625 -11.46875 C 9.53125 -11.875 9.0625 -12.1875 8.53125 -12.421875 C 7.984375 -12.65625 7.359375 -12.78125 6.65625 -12.78125 C 5.671875 -12.78125 4.796875 -12.609375 3.984375 -12.28125 C 3.1875 -11.9375 2.4375 -11.453125 1.75 -10.78125 L 2.140625 -10.078125 C 2.203125 -9.96875 2.296875 -9.859375 2.40625 -9.78125 C 2.53125 -9.703125 2.65625 -9.671875 2.796875 -9.671875 C 2.984375 -9.671875 3.1875 -9.734375 3.375 -9.859375 C 3.5625 -10.015625 3.796875 -10.15625 4.0625 -10.328125 C 4.34375 -10.5 4.65625 -10.65625 5.03125 -10.78125 C 5.390625 -10.921875 5.84375 -10.984375 6.375 -10.984375 C 7.203125 -10.984375 7.8125 -10.75 8.234375 -10.234375 C 8.65625 -9.734375 8.859375 -9.015625 8.859375 -8.03125 L 8.859375 -7.046875 C 7.4375 -7.015625 6.234375 -6.890625 5.25 -6.671875 C 4.28125 -6.4375 3.46875 -6.140625 2.875 -5.78125 C 2.25 -5.421875 1.828125 -5.03125 1.546875 -4.5625 C 1.28125 -4.109375 1.140625 -3.625 1.140625 -3.140625 C 1.140625 -2.5625 1.234375 -2.0625 1.40625 -1.65625 C 1.609375 -1.234375 1.859375 -0.890625 2.171875 -0.625 C 2.484375 -0.34375 2.84375 -0.15625 3.265625 0 C 3.703125 0.125 4.15625 0.203125 4.640625 0.203125 C 5.125 0.203125 5.5625 0.15625 5.953125 0.078125 C 6.34375 -0.015625 6.71875 -0.125 7.0625 -0.296875 C 7.40625 -0.453125 7.75 -0.640625 8.046875 -0.890625 C 8.359375 -1.109375 8.6875 -1.390625 9.015625 -1.6875 L 9.265625 -0.515625 C 9.3125 -0.3125 9.390625 -0.15625 9.53125 -0.09375 C 9.671875 -0.03125 9.84375 0 10.046875 0 Z M 5.296875 -1.34375 C 5.015625 -1.34375 4.75 -1.390625 4.5 -1.46875 C 4.25 -1.53125 4.046875 -1.640625 3.859375 -1.78125 C 3.671875 -1.953125 3.53125 -2.140625 3.421875 -2.375 C 3.3125 -2.609375 3.265625 -2.90625 3.265625 -3.234375 C 3.265625 -3.578125 3.359375 -3.890625 3.5625 -4.171875 C 3.765625 -4.453125 4.09375 -4.703125 4.53125 -4.90625 C 4.984375 -5.125 5.5625 -5.28125 6.265625 -5.40625 C 6.96875 -5.53125 7.84375 -5.609375 8.859375 -5.65625 L 8.859375 -3.03125 C 8.609375 -2.78125 8.34375 -2.546875 8.109375 -2.328125 C 7.828125 -2.125 7.5625 -1.953125 7.28125 -1.8125 C 6.984375 -1.65625 6.6875 -1.546875 6.375 -1.46875 C 6.046875 -1.390625 5.6875 -1.34375 5.296875 -1.34375 Z M 5.296875 -1.34375 "/>
|
||||
<path style="stroke:none;" d="M 8.546875 -5.65625 L 8.546875 -3.046875 C 8.296875 -2.78125 8.046875 -2.546875 7.78125 -2.34375 C 7.515625 -2.125 7.25 -1.953125 6.96875 -1.8125 C 6.671875 -1.65625 6.375 -1.53125 6.0625 -1.46875 C 5.734375 -1.390625 5.375 -1.34375 5 -1.34375 C 4.703125 -1.34375 4.421875 -1.375 4.171875 -1.453125 C 3.921875 -1.53125 3.703125 -1.640625 3.515625 -1.78125 C 3.328125 -1.9375 3.1875 -2.125 3.078125 -2.375 C 2.96875 -2.609375 2.921875 -2.90625 2.921875 -3.234375 C 2.921875 -3.578125 3.015625 -3.890625 3.21875 -4.171875 C 3.421875 -4.453125 3.75 -4.703125 4.203125 -4.90625 C 4.640625 -5.109375 5.234375 -5.28125 5.953125 -5.40625 C 6.671875 -5.53125 7.53125 -5.609375 8.546875 -5.65625 Z M 1.421875 -10.78125 L 1.828125 -10.078125 C 1.890625 -9.953125 1.984375 -9.84375 2.09375 -9.78125 C 2.1875 -9.703125 2.328125 -9.671875 2.484375 -9.671875 C 2.65625 -9.671875 2.84375 -9.734375 3.046875 -9.859375 C 3.25 -10 3.46875 -10.140625 3.734375 -10.328125 C 4.015625 -10.5 4.328125 -10.640625 4.703125 -10.78125 C 5.0625 -10.921875 5.53125 -10.984375 6.078125 -10.984375 C 6.875 -10.984375 7.5 -10.734375 7.921875 -10.234375 C 8.34375 -9.734375 8.546875 -9 8.546875 -8.03125 L 8.546875 -7.046875 C 7.109375 -7.015625 5.90625 -6.875 4.9375 -6.65625 C 3.9375 -6.4375 3.140625 -6.140625 2.546875 -5.78125 C 1.921875 -5.421875 1.484375 -5.015625 1.21875 -4.5625 C 0.9375 -4.09375 0.8125 -3.625 0.8125 -3.140625 C 0.8125 -2.5625 0.890625 -2.0625 1.078125 -1.640625 C 1.265625 -1.234375 1.515625 -0.890625 1.828125 -0.625 C 2.15625 -0.34375 2.53125 -0.140625 2.96875 0 C 3.375 0.140625 3.84375 0.203125 4.34375 0.203125 C 4.8125 0.203125 5.234375 0.15625 5.640625 0.078125 C 6.03125 -0.015625 6.40625 -0.140625 6.75 -0.296875 C 7.09375 -0.453125 7.421875 -0.65625 7.75 -0.890625 C 8.046875 -1.125 8.375 -1.40625 8.703125 -1.703125 L 8.953125 -0.515625 C 9.015625 -0.3125 9.109375 -0.171875 9.234375 -0.09375 C 9.34375 -0.03125 9.5 0 9.734375 0 L 10.703125 0 L 10.703125 -8.03125 C 10.703125 -8.71875 10.609375 -9.375 10.421875 -9.96875 C 10.21875 -10.546875 9.953125 -11.046875 9.578125 -11.46875 C 9.203125 -11.875 8.75 -12.1875 8.203125 -12.421875 C 7.65625 -12.65625 7.03125 -12.78125 6.328125 -12.78125 C 5.359375 -12.78125 4.453125 -12.59375 3.671875 -12.28125 C 2.859375 -11.9375 2.125 -11.453125 1.421875 -10.78125 Z M 1.421875 -10.78125 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-5">
|
||||
<path style="stroke:none;" d="M 1.8125 0 L 4.015625 0 L 4.015625 -7.984375 C 4.359375 -8.84375 4.796875 -9.484375 5.296875 -9.9375 C 5.828125 -10.390625 6.46875 -10.609375 7.234375 -10.609375 C 7.671875 -10.609375 8 -10.5625 8.234375 -10.484375 C 8.46875 -10.40625 8.65625 -10.375 8.765625 -10.375 C 8.96875 -10.375 9.09375 -10.46875 9.15625 -10.6875 L 9.4375 -12.328125 C 9.203125 -12.46875 8.953125 -12.578125 8.65625 -12.65625 C 8.375 -12.734375 8.0625 -12.78125 7.71875 -12.78125 C 6.859375 -12.78125 6.125 -12.53125 5.5 -12.046875 C 4.859375 -11.546875 4.34375 -10.859375 3.90625 -9.984375 L 3.75 -11.9375 C 3.71875 -12.171875 3.65625 -12.328125 3.5625 -12.421875 C 3.484375 -12.5 3.3125 -12.546875 3.078125 -12.546875 L 1.8125 -12.546875 Z M 1.8125 0 "/>
|
||||
<path style="stroke:none;" d="M 3.84375 -10.03125 L 3.6875 -11.9375 C 3.65625 -12.171875 3.59375 -12.3125 3.5 -12.421875 C 3.40625 -12.5 3.25 -12.546875 3.015625 -12.546875 L 1.75 -12.546875 L 1.75 0 L 3.96875 0 L 3.96875 -7.9375 C 4.109375 -8.34375 4.28125 -8.734375 4.484375 -9.0625 C 4.6875 -9.40625 4.890625 -9.6875 5.140625 -9.90625 C 5.390625 -10.140625 5.65625 -10.3125 5.96875 -10.4375 C 6.28125 -10.546875 6.640625 -10.609375 7.03125 -10.609375 C 7.3125 -10.609375 7.578125 -10.578125 7.796875 -10.53125 C 8.015625 -10.484375 8.171875 -10.453125 8.296875 -10.453125 C 8.5 -10.453125 8.625 -10.5625 8.671875 -10.765625 L 8.828125 -12.421875 C 8.640625 -12.546875 8.421875 -12.625 8.171875 -12.6875 C 7.9375 -12.734375 7.6875 -12.78125 7.421875 -12.78125 C 6.578125 -12.78125 5.875 -12.53125 5.296875 -12.046875 C 4.71875 -11.5625 4.234375 -10.890625 3.84375 -10.03125 Z M 3.84375 -10.03125 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-6">
|
||||
<path style="stroke:none;" d="M 6.78125 -12.75 C 5.875 -12.75 5.0625 -12.59375 4.328125 -12.265625 C 3.59375 -11.953125 2.984375 -11.515625 2.484375 -10.953125 C 1.96875 -10.40625 1.59375 -9.734375 1.3125 -8.984375 C 1.046875 -8.234375 0.921875 -7.40625 0.921875 -6.53125 C 0.921875 -5.453125 1.0625 -4.484375 1.359375 -3.65625 C 1.65625 -2.828125 2.078125 -2.125 2.609375 -1.5625 C 3.140625 -0.984375 3.765625 -0.5625 4.515625 -0.265625 C 5.234375 0.03125 6.03125 0.171875 6.90625 0.171875 C 7.359375 0.171875 7.8125 0.140625 8.28125 0.046875 C 8.734375 -0.03125 9.1875 -0.140625 9.609375 -0.296875 C 10.0625 -0.453125 10.453125 -0.65625 10.84375 -0.890625 C 11.21875 -1.140625 11.546875 -1.421875 11.828125 -1.765625 L 11.203125 -2.5625 C 11.109375 -2.703125 10.96875 -2.78125 10.78125 -2.78125 C 10.640625 -2.78125 10.46875 -2.71875 10.28125 -2.578125 C 10.09375 -2.453125 9.84375 -2.3125 9.546875 -2.171875 C 9.265625 -2.015625 8.921875 -1.890625 8.53125 -1.765625 C 8.109375 -1.625 7.640625 -1.5625 7.09375 -1.5625 C 6.5 -1.5625 5.953125 -1.65625 5.484375 -1.859375 C 5 -2.046875 4.578125 -2.34375 4.234375 -2.71875 C 3.890625 -3.125 3.625 -3.625 3.421875 -4.203125 C 3.21875 -4.78125 3.109375 -5.484375 3.09375 -6.265625 L 11.453125 -6.265625 C 11.65625 -6.265625 11.796875 -6.328125 11.875 -6.4375 C 11.9375 -6.546875 11.984375 -6.796875 11.984375 -7.140625 C 11.984375 -8.03125 11.84375 -8.828125 11.59375 -9.515625 C 11.328125 -10.21875 10.96875 -10.796875 10.5 -11.28125 C 10.046875 -11.765625 9.484375 -12.125 8.859375 -12.359375 C 8.234375 -12.625 7.53125 -12.75 6.78125 -12.75 Z M 6.828125 -11.125 C 7.328125 -11.125 7.78125 -11.046875 8.171875 -10.875 C 8.5625 -10.703125 8.890625 -10.453125 9.171875 -10.15625 C 9.4375 -9.84375 9.65625 -9.484375 9.78125 -9.046875 C 9.921875 -8.625 10 -8.15625 10 -7.640625 L 3.171875 -7.640625 C 3.328125 -8.734375 3.703125 -9.59375 4.3125 -10.203125 C 4.921875 -10.8125 5.765625 -11.125 6.828125 -11.125 Z M 6.828125 -11.125 "/>
|
||||
<path style="stroke:none;" d="M 10.140625 -7.640625 L 3.28125 -7.640625 C 3.4375 -8.734375 3.796875 -9.578125 4.421875 -10.203125 C 5.046875 -10.8125 5.875 -11.125 6.9375 -11.125 C 7.4375 -11.125 7.890625 -11.046875 8.296875 -10.859375 C 8.6875 -10.6875 9.015625 -10.453125 9.296875 -10.140625 C 9.5625 -9.84375 9.78125 -9.46875 9.921875 -9.046875 C 10.078125 -8.625 10.140625 -8.15625 10.140625 -7.640625 Z M 11.9375 -1.765625 L 11.3125 -2.5625 C 11.21875 -2.703125 11.0625 -2.78125 10.890625 -2.78125 C 10.75 -2.78125 10.578125 -2.703125 10.390625 -2.578125 C 10.1875 -2.453125 9.953125 -2.3125 9.671875 -2.171875 C 9.375 -2.015625 9.015625 -1.875 8.625 -1.75 C 8.234375 -1.625 7.75 -1.5625 7.203125 -1.5625 C 6.609375 -1.5625 6.0625 -1.640625 5.59375 -1.84375 C 5.109375 -2.046875 4.703125 -2.328125 4.34375 -2.71875 C 4 -3.125 3.734375 -3.609375 3.53125 -4.203125 C 3.328125 -4.78125 3.234375 -5.484375 3.203125 -6.265625 L 11.59375 -6.265625 C 11.796875 -6.265625 11.9375 -6.3125 12.015625 -6.4375 C 12.09375 -6.546875 12.125 -6.796875 12.125 -7.140625 C 12.125 -8.03125 12 -8.828125 11.734375 -9.515625 C 11.46875 -10.203125 11.109375 -10.796875 10.625 -11.28125 C 10.15625 -11.75 9.609375 -12.125 8.96875 -12.359375 C 8.328125 -12.609375 7.625 -12.75 6.890625 -12.75 C 5.96875 -12.75 5.15625 -12.59375 4.4375 -12.265625 C 3.703125 -11.9375 3.078125 -11.515625 2.59375 -10.953125 C 2.078125 -10.390625 1.703125 -9.734375 1.421875 -8.984375 C 1.15625 -8.21875 1.03125 -7.390625 1.03125 -6.53125 C 1.03125 -5.4375 1.171875 -4.484375 1.46875 -3.65625 C 1.765625 -2.8125 2.1875 -2.125 2.71875 -1.546875 C 3.25 -0.984375 3.875 -0.5625 4.609375 -0.265625 C 5.34375 0.03125 6.140625 0.171875 7.015625 0.171875 C 7.453125 0.171875 7.921875 0.140625 8.390625 0.0625 C 8.84375 -0.015625 9.296875 -0.140625 9.734375 -0.296875 C 10.15625 -0.453125 10.5625 -0.640625 10.953125 -0.890625 C 11.328125 -1.140625 11.65625 -1.421875 11.9375 -1.765625 Z M 11.9375 -1.765625 "/>
|
||||
</symbol>
|
||||
</g>
|
||||
<clipPath id="clip1">
|
||||
<path d="M 0 6 L 22 6 L 22 34.183594 L 0 34.183594 Z M 0 6 "/>
|
||||
<path d="M 0 6 L 21 6 L 21 34.183594 L 0 34.183594 Z M 0 6 "/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="surface1">
|
||||
<g style="fill:rgb(67.059326%,70.196533%,72.941589%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="3.321" y="24.097"/>
|
||||
<use xlink:href="#glyph0-2" x="21.985686" y="24.097"/>
|
||||
<use xlink:href="#glyph0-3" x="34.676682" y="24.097"/>
|
||||
<use xlink:href="#glyph0-4" x="48.458309" y="24.097"/>
|
||||
<use xlink:href="#glyph0-5" x="61.025369" y="24.097"/>
|
||||
<use xlink:href="#glyph0-6" x="71.01457" y="24.097"/>
|
||||
<use xlink:href="#glyph0-1" x="3.32" y="24.072"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,49.804688%,39.99939%);stroke-opacity:1;stroke-miterlimit:10;" d="M -13.323406 -17.010156 C -13.323406 -17.010156 0.785969 14.802344 5.387531 15.591406 C 9.989094 16.376563 16.891437 -8.35 19.844562 -11.338281 C 22.793781 -14.326562 24.797687 -6.029687 26.645344 -5.951562 C 28.493 -5.873437 31.434406 -10.455469 33.164875 -10.771875 C 34.895344 -11.088281 37.504719 -8.299219 39.118 -8.221094 C 40.731281 -8.142969 43.215656 -10.127344 44.789875 -10.205469 C 46.360187 -10.283594 48.883625 -8.865625 50.457844 -8.7875 C 52.032062 -8.709375 54.551594 -9.6 56.125812 -9.639062 C 57.700031 -9.678125 60.301594 -9.111719 61.797687 -9.072656 C 63.289875 -9.033594 66.89925 -9.353906 66.89925 -9.353906 " transform="matrix(1,0,0,-1,15.882,16.775)"/>
|
||||
<g style="fill:rgb(67.059326%,70.196533%,72.941589%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-2" x="22.096228" y="24.072"/>
|
||||
<use xlink:href="#glyph0-3" x="34.873978" y="24.072"/>
|
||||
<use xlink:href="#glyph0-4" x="48.70518" y="24.072"/>
|
||||
<use xlink:href="#glyph0-5" x="61.024369" y="24.072"/>
|
||||
</g>
|
||||
<g style="fill:rgb(67.059326%,70.196533%,72.941589%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-6" x="69.551131" y="24.072"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(49.412537%,80.784607%,99.215698%);stroke-opacity:1;stroke-miterlimit:10;" d="M -13.322906 -17.010156 C -13.322906 -17.010156 0.782563 14.802344 5.384125 15.591406 C 9.985688 16.376563 16.891938 -8.35 19.841156 -11.338281 C 22.794281 -14.326562 24.798188 -6.029687 26.645844 -5.951562 C 28.4935 -5.873437 31.434906 -10.455469 33.165375 -10.771875 C 34.895844 -11.088281 37.505219 -8.299219 39.1185 -8.221094 C 40.731781 -8.142969 43.216156 -10.127344 44.786469 -10.205469 C 46.360687 -10.283594 48.884125 -8.865625 50.458344 -8.7875 C 52.028656 -8.709375 54.552094 -9.6 56.126312 -9.639062 C 57.700531 -9.678125 60.302094 -9.111719 61.794281 -9.072656 C 63.290375 -9.033594 66.89975 -9.353906 66.89975 -9.353906 " transform="matrix(1,0,0,-1,15.194,16.775)"/>
|
||||
<g style="fill:rgb(12.940979%,52.157593%,77.253723%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="3.888" y="23.53"/>
|
||||
<use xlink:href="#glyph0-2" x="22.552686" y="23.53"/>
|
||||
<use xlink:href="#glyph0-3" x="35.243681" y="23.53"/>
|
||||
<use xlink:href="#glyph0-4" x="49.025309" y="23.53"/>
|
||||
<use xlink:href="#glyph0-5" x="61.592369" y="23.53"/>
|
||||
<use xlink:href="#glyph0-6" x="71.58157" y="23.53"/>
|
||||
<use xlink:href="#glyph0-1" x="3.888" y="23.505"/>
|
||||
</g>
|
||||
<g style="fill:rgb(12.940979%,52.157593%,77.253723%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-2" x="22.664228" y="23.505"/>
|
||||
<use xlink:href="#glyph0-3" x="35.441978" y="23.505"/>
|
||||
<use xlink:href="#glyph0-4" x="49.27318" y="23.505"/>
|
||||
<use xlink:href="#glyph0-5" x="61.592369" y="23.505"/>
|
||||
</g>
|
||||
<g style="fill:rgb(12.940979%,52.157593%,77.253723%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-6" x="70.094344" y="23.505"/>
|
||||
</g>
|
||||
<g clip-path="url(#clip1)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,49.804688%,39.99939%);stroke-opacity:1;stroke-miterlimit:10;" d="M -9.128094 -7.935937 C -9.128094 -7.935937 -5.753094 -1.135156 -5.753094 -1.135156 " transform="matrix(1,0,0,-1,15.882,16.775)"/>
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(49.412537%,80.784607%,99.215698%);stroke-opacity:1;stroke-miterlimit:10;" d="M -9.127594 -7.935937 C -9.127594 -7.935937 -5.752594 -1.135156 -5.752594 -1.135156 " transform="matrix(1,0,0,-1,15.194,16.775)"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1 @@
|
|||
/usr/share/javascript/mathjax/
|
|
@ -13,23 +13,20 @@ Bibliography
|
|||
* Andrews, Donald W.K (1991): “Heteroskedasticity and autocorrelation consistent covariance matrix estimation”, *Econometrica*, 59(3), 817–858.
|
||||
* Backus, David K., Patrick J. Kehoe, and Finn E. Kydland (1992): “International Real Business Cycles,” *Journal of Political Economy*, 100(4), 745–775.
|
||||
* Baxter, Marianne and Robert G. King (1999): “Measuring Business Cycles: Approximate Band-pass Filters for Economic Time Series,” *Review of Economics and Statistics*, 81(4), 575–593.
|
||||
* Bini, Dario A., Guy Latouche, and Beatrice Meini (2002): “Solving matrix polynomial equations arising in queueing problems,” *Linear Algebra and its Applications*, 340, 225–244.
|
||||
* Born, Benjamin and Johannes Pfeifer (2014): “Policy risk and the business cycle”, *Journal of Monetary Economics*, 68, 68-85.
|
||||
* Boucekkine, Raouf (1995): “An alternative methodology for solving nonlinear forward-looking models,” *Journal of Economic Dynamics and Control*, 19, 711–734.
|
||||
* Brayton, Flint and Peter Tinsley (1996): “A Guide to FRB/US: A Macroeconomic Model of the United States,” *Finance and Economics Discussion Series*, 1996-42.
|
||||
* Brayton, Flint, Morris Davis and Peter Tulip (2000): “Polynomial Adjustment Costs in FRB/US,” *Unpublished manuscript*.
|
||||
* Brayton, Flint and Peter Tinsley (1996): "A Guide to FRB/US: A Macroeconomic Model of the United States", *Finance and Economics Discussion Series*, 1996-42.
|
||||
* Brayton, Flint, Morris Davis and Peter Tulip (2000): "Polynomial Adjustment Costs in FRB/US", *Unpublished manuscript*.
|
||||
* Brooks, Stephen P., and Andrew Gelman (1998): “General methods for monitoring convergence of iterative simulations,” *Journal of Computational and Graphical Statistics*, 7, pp. 434–455.
|
||||
* Cardoso, Margarida F., R. L. Salcedo and S. Feyo de Azevedo (1996): “The simplex simulated annealing approach to continuous non-linear optimization,” *Computers & Chemical Engineering*, 20(9), 1065-1080.
|
||||
* Chib, Siddhartha and Srikanth Ramamurthy (2010): “Tailored randomized block MCMC methods with application to DSGE models,” *Journal of Econometrics*, 155, 19–38.
|
||||
* Christiano, Lawrence J., Martin Eichenbaum and Charles L. Evans (2005): “Nominal Rigidities and the Dynamic Effects of a Shock to Monetary Policy,” *Journal of Political Economy*, 113(1), 1–45.
|
||||
* Christiano, Lawrence J., Mathias Trabandt, and Karl Walentin (2010): “DSGE Models for Monetary Policy Analysis,” In: *Handbook of Monetary Economics 3*, 285–367.
|
||||
* Christiano, Lawrence J., Mathias Trabandt and Karl Walentin (2011): “Introducing financial frictions and unemployment into a small open economy model,” *Journal of Economic Dynamics and Control*, 35(12), 1999–2041.
|
||||
* Christoffel, Kai, Günter Coenen and Anders Warne (2010): “Forecasting with DSGE models,” *ECB Working Paper Series*, 1185.
|
||||
* Collard, Fabrice (2001): “Stochastic simulations with Dynare: A practical guide”.
|
||||
* Collard, Fabrice and Michel Juillard (2001a): “Accuracy of stochastic perturbation methods: The case of asset pricing models,” *Journal of Economic Dynamics and Control*, 25, 979–999.
|
||||
* Collard, Fabrice and Michel Juillard (2001b): “A Higher-Order Taylor Expansion Approach to Simulation of Stochastic Forward-Looking Models with an Application to a Non-Linear Phillips Curve,” *Computational Economics*, 17, 125–139.
|
||||
* Corana, Angelo, M. Marchesi, Claudio Martini, and Sandro Ridella (1987): “Minimizing multimodal functions of continuous variables with the “simulated annealing” algorithm”, *ACM Transactions on Mathematical Software*, 13(3), 262–280.
|
||||
* Cuba-Borda, Pablo, Luca Guerrieri, Matteo Iacoviello, and Molin Zhong (2019): “Likelihood evaluation of models with occasionally binding constraints,” Journal of Applied Econometrics, 34(7), 1073-1085
|
||||
* Cuba-Borda, Pablo, Luca Guerrieri, Matteo Iacoviello, and Molin Zhong (2019): "Likelihood evaluation of models with occasionally binding constraints", Journal of Applied Econometrics, 34(7), 1073-1085
|
||||
* Del Negro, Marco and Frank Schorfheide (2004): “Priors from General Equilibrium Models for VARs”, *International Economic Review*, 45(2), 643–673.
|
||||
* Dennis, Richard (2007): “Optimal Policy In Rational Expectations Models: New Solution Algorithms”, *Macroeconomic Dynamics*, 11(1), 31–55.
|
||||
* Duffie, Darrel and Kenneth J. Singleton (1993): “Simulated Moments Estimation of Markov Models of Asset Prices”, *Econometrica*, 61(4), 929-952.
|
||||
|
@ -49,7 +46,6 @@ Bibliography
|
|||
* Hansen, Lars P. (1982): “Large sample properties of generalized method of moments estimators,” Econometrica, 50(4), 1029–1054.
|
||||
* Hansen, Nikolaus and Stefan Kern (2004): “Evaluating the CMA Evolution Strategy on Multimodal Test Functions”. In: *Eighth International Conference on Parallel Problem Solving from Nature PPSN VIII*, Proceedings, Berlin: Springer, 282–291.
|
||||
* Harvey, Andrew C. and Garry D.A. Phillips (1979): “Maximum likelihood estimation of regression models with autoregressive-moving average disturbances,” *Biometrika*, 66(1), 49–58.
|
||||
* Herbst, Edward and Schorfheide, Frank (2014): “Sequential Monte Carlo Sampling for DSGE Models,” *Journal of Applied Econometrics*, 29, 1073-1098.
|
||||
* Herbst, Edward (2015): “Using the “Chandrasekhar Recursions” for Likelihood Evaluation of DSGE Models,” *Computational Economics*, 45(4), 693–705.
|
||||
* Ireland, Peter (2004): “A Method for Taking Models to the Data,” *Journal of Economic Dynamics and Control*, 28, 1205–26.
|
||||
* Iskrev, Nikolay (2010): “Local identification in DSGE models,” *Journal of Monetary Economics*, 57(2), 189–202.
|
||||
|
@ -86,5 +82,5 @@ Bibliography
|
|||
* Smets, Frank and Rafael Wouters (2003): “An Estimated Dynamic Stochastic General Equilibrium Model of the Euro Area,” *Journal of the European Economic Association*, 1(5), 1123–1175.
|
||||
* Stock, James H. and Mark W. Watson (1999). “Forecasting Inflation,”, *Journal of Monetary Economics*, 44(2), 293–335.
|
||||
* Uhlig, Harald (2001): “A Toolkit for Analysing Nonlinear Dynamic Stochastic Models Easily,” in *Computational Methods for the Study of Dynamic Economies*, Eds. Ramon Marimon and Andrew Scott, Oxford University Press, 30–61.
|
||||
* U.S. Census Bureau (2020): “X-13 ARIMA-SEATS Reference Manual, Version 1.1”, Center for Statistical Research and Methodology, U.S. Census Bureau, https://www.census.gov/data/software/x13as.html
|
||||
* U.S. Census Bureau (2017): “X-13 ARIMA-SEATS Reference Manual”.
|
||||
* Villemot, Sébastien (2011): “Solving rational expectations models at first order: what Dynare does,” *Dynare Working Papers*, 2, CEPREMAP.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright © 2018-2024 Dynare Team
|
||||
# Copyright © 2018-2022 Dynare Team
|
||||
#
|
||||
# This file is part of Dynare.
|
||||
#
|
||||
|
@ -31,14 +31,20 @@ templates_path = ['_templates']
|
|||
|
||||
html_static_path = ['_static']
|
||||
|
||||
mathjax_path = 'mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
|
||||
|
||||
master_doc = 'index'
|
||||
|
||||
project = u'Dynare'
|
||||
copyright = u'1996–2024 Dynare Team'
|
||||
copyright = u'1996–2022 Dynare Team'
|
||||
author = u'Dynare Team'
|
||||
|
||||
add_function_parentheses = False
|
||||
|
||||
# See ../utils/version.py, which is generated by autoconf
|
||||
from version import version
|
||||
from version import release
|
||||
|
||||
language = 'en'
|
||||
|
||||
exclude_patterns = []
|
||||
|
@ -71,11 +77,12 @@ latex_elements = {
|
|||
warningBorderColor={RGB}{255,50,50},OuterLinkColor={RGB}{34,139,34}, \
|
||||
InnerLinkColor={RGB}{51,51,255},TitleColor={RGB}{51,51,255}',
|
||||
'papersize': 'a4paper',
|
||||
'preamble': r'\DeclareUnicodeCharacter{200B}{}', # Part of the workaround for #1707
|
||||
}
|
||||
|
||||
latex_documents = [
|
||||
(master_doc, 'dynare-manual.tex', u'Dynare Reference Manual',
|
||||
u'Dynare Team', 'manual'),
|
||||
u'Dynare team', 'manual'),
|
||||
]
|
||||
|
||||
man_pages = [
|
||||
|
|
|
@ -8,25 +8,11 @@
|
|||
Dynare misc commands
|
||||
####################
|
||||
|
||||
.. matcomm:: send_endogenous_variables_to_workspace ;
|
||||
|
||||
Puts the simulation results for the endogenous variables stored in ``oo_.endo_simul``
|
||||
into vectors with the same name as the respective variables into the base workspace.
|
||||
|
||||
.. matcomm:: send_exogenous_variables_to_workspace ;
|
||||
|
||||
Puts the simulation results for the exogenous variables stored in ``oo_.exo_simul``
|
||||
into vectors with the same name as the respective variables into the base workspace.
|
||||
|
||||
.. matcomm:: send_irfs_to_workspace ;
|
||||
|
||||
Puts the IRFs stored in ``oo_.irfs`` into vectors with the same name into the base workspace.
|
||||
|
||||
.. command:: prior_function(OPTIONS);
|
||||
|
||||
Executes a user-defined function on parameter draws from the prior
|
||||
|br| Executes a user-defined function on parameter draws from the prior
|
||||
distribution. Dynare returns the results of the computations for
|
||||
all draws in an `ndraws` by :math:`n` cell array named
|
||||
all draws in an $ndraws$ by $n$ cell array named
|
||||
``oo_.prior_function_results``.
|
||||
|
||||
*Options*
|
||||
|
@ -44,11 +30,9 @@ Dynare misc commands
|
|||
|
||||
Number of draws used for sampling. Default: 500.
|
||||
|
||||
|br|
|
||||
|
||||
.. command:: posterior_function(OPTIONS);
|
||||
|
||||
Same as the :comm:`prior_function` command but for the
|
||||
|br| Same as the :comm:`prior_function` command but for the
|
||||
posterior distribution. Results returned in
|
||||
``oo_.posterior_function_results``.
|
||||
|
||||
|
@ -62,28 +46,23 @@ Dynare misc commands
|
|||
|
||||
See :opt:`prior_function_sampling_draws <sampling_draws = INTEGER>`.
|
||||
|
||||
|br|
|
||||
|
||||
.. command:: generate_trace_plots(CHAIN_NUMBER);
|
||||
|
||||
Generates trace plots of the MCMC draws for all estimated
|
||||
parameters and the posterior density for the specified Markov Chain(s)
|
||||
``CHAIN_NUMBER``. If ``CHAIN_NUMBER`` is a vector of integers, the trace plots
|
||||
will plot contains separate lines for each chain.
|
||||
|
||||
|br|
|
||||
|br| Generates trace plots of the MCMC draws for all estimated
|
||||
parameters and the posterior density in the specified Markov Chain
|
||||
``CHAIN_NUMBER``.
|
||||
|
||||
.. matcomm:: internals FLAG ROUTINENAME[.m]|MODFILENAME
|
||||
|
||||
Depending on the value of ``FLAG``, the ``internals`` command
|
||||
can be used to run unitary tests specific to a MATLAB/Octave
|
||||
routine (if available), to display documentation about a
|
||||
MATLAB/Octave routine, or to extract some informations about the
|
||||
state of Dynare.
|
||||
|br| Depending on the value of ``FLAG``, the ``internals`` command
|
||||
can be used to run unitary tests specific to a MATLAB/Octave
|
||||
routine (if available), to display documentation about a
|
||||
MATLAB/Octave routine, or to extract some informations about the
|
||||
state of Dynare.
|
||||
|
||||
*Flags*
|
||||
*Flags*
|
||||
|
||||
``--test``
|
||||
``--test``
|
||||
|
||||
Performs the unitary test associated to ROUTINENAME (if this
|
||||
routine exists and if the matlab/octave ``.m`` file has
|
||||
|
@ -100,7 +79,28 @@ Dynare misc commands
|
|||
|
||||
>> internals --test ../matlab/fr/ROUTINENAME
|
||||
|
||||
``--display-mh-history``
|
||||
``--info``
|
||||
|
||||
Prints on screen the internal documentation of ROUTINENAME (if
|
||||
this routine exists and if this routine has a texinfo internal
|
||||
documentation header). The path to ``ROUTINENAME`` has to be
|
||||
provided, if the routine is not in the current directory.
|
||||
|
||||
*Example*
|
||||
|
||||
::
|
||||
|
||||
>> internals --doc ../matlab/fr/ROUTINENAME
|
||||
|
||||
At this time, will work properly for only a small number
|
||||
of routines. At the top of the (available) MATLAB/Octave
|
||||
routines a commented block for the internal documentation
|
||||
is written in the GNU texinfo documentation format. This
|
||||
block is processed by calling texinfo from
|
||||
MATLAB. Consequently, texinfo has to be installed on your
|
||||
machine.
|
||||
|
||||
``--display-mh-history``
|
||||
|
||||
Displays information about the previously saved MCMC draws
|
||||
generated by a ``.mod`` file named MODFILENAME. This file must
|
||||
|
@ -112,9 +112,9 @@ Dynare misc commands
|
|||
|
||||
>> internals --display-mh-history MODFILENAME
|
||||
|
||||
``--load-mh-history``
|
||||
``--load-mh-history``
|
||||
|
||||
Loads into the MATLAB/Octave’s workspace informations
|
||||
|br| Loads into the MATLAB/Octave’s workspace informations
|
||||
about the previously saved MCMC draws generated by a ``.mod``
|
||||
file named MODFILENAME.
|
||||
|
||||
|
@ -167,160 +167,56 @@ Dynare misc commands
|
|||
|
||||
A ``1*Nblck`` array of doubles. Current acceptance ratios.
|
||||
|
||||
|br|
|
||||
.. matcomm:: prior [OPTIONS[, ...]];
|
||||
|
||||
.. matcomm:: prior [OPTIONS[ ...]];
|
||||
Prints information about the prior distribution given the provided
|
||||
options. If no options are provided, the command returns the list of
|
||||
available options.
|
||||
|
||||
Prints information about the prior distribution given the provided
|
||||
options. If no options are provided, the command returns the list of
|
||||
available options.
|
||||
*Options*
|
||||
|
||||
*Options*
|
||||
.. option:: table
|
||||
|
||||
.. option:: table
|
||||
Prints a table describing the marginal prior distributions
|
||||
(mean, mode, std., lower and upper bounds, HPD interval).
|
||||
|
||||
Prints a table describing the marginal prior distributions
|
||||
(mean, mode, std., lower and upper bounds, HPD interval).
|
||||
.. option:: moments
|
||||
|
||||
.. option:: moments
|
||||
Computes and displays first and second order moments of the
|
||||
endogenous variables at the prior mode (considering the
|
||||
linearized version of the model).
|
||||
|
||||
Computes and displays first and second order moments of the
|
||||
endogenous variables at the prior mode (considering the
|
||||
linearized version of the model).
|
||||
.. option:: moments(distribution)
|
||||
|
||||
.. option:: moments(distribution)
|
||||
Computes and displays the prior mean and prior standard
|
||||
deviation of the first and second moments of the endogenous
|
||||
variables (considering the linearized version of the model) by
|
||||
randomly sampling from the prior. The results will also be
|
||||
stored in the ``prior`` subfolder in a
|
||||
``_endogenous_variables_prior_draws.mat`` file.
|
||||
|
||||
Computes and displays the prior mean and prior standard
|
||||
deviation of the first and second moments of the endogenous
|
||||
variables (considering the linearized version of the model) by
|
||||
randomly sampling from the prior. The results will also be
|
||||
stored in the ``prior`` subfolder in a
|
||||
``_endogenous_variables_prior_draws.mat`` file.
|
||||
.. option:: optimize
|
||||
|
||||
.. option:: optimize
|
||||
Optimizes the prior density (starting from a random initial
|
||||
guess). The parameters such that the steady state does not
|
||||
exist or does not satisfy the Blanchard and Kahn conditions
|
||||
are penalized, as they would be when maximizing the posterior
|
||||
density. If a significant proportion of the prior mass is
|
||||
defined over such regions, the optimization algorithm may fail
|
||||
to converge to the true solution (the prior mode).
|
||||
|
||||
Optimizes the prior density (starting from a random initial
|
||||
guess). The parameters such that the steady state does not
|
||||
exist or does not satisfy the Blanchard and Kahn conditions
|
||||
are penalized, as they would be when maximizing the posterior
|
||||
density. If a significant proportion of the prior mass is
|
||||
defined over such regions, the optimization algorithm may fail
|
||||
to converge to the true solution (the prior mode).
|
||||
.. option:: simulate
|
||||
|
||||
.. option:: simulate
|
||||
Computes the effective prior mass using a Monte-Carlo. Ideally
|
||||
the effective prior mass should be equal to 1, otherwise
|
||||
problems may arise when maximising the posterior density and
|
||||
model comparison based on marginal densities may be
|
||||
unfair. When comparing models, say :math:`A` and :math:`B`,
|
||||
the marginal densities, :math:`m_A` and :math:`m_B`, should be
|
||||
corrected for the estimated effective prior mass
|
||||
:math:`p_A\neq p_B \leq 1` so that the prior mass of the
|
||||
compared models are identical.
|
||||
|
||||
Computes the effective prior mass using a Monte-Carlo. Ideally
|
||||
the effective prior mass should be equal to 1, otherwise
|
||||
problems may arise when maximising the posterior density and
|
||||
model comparison based on marginal densities may be
|
||||
unfair. When comparing models, say :math:`A` and :math:`B`,
|
||||
the marginal densities, :math:`m_A` and :math:`m_B`, should be
|
||||
corrected for the estimated effective prior mass
|
||||
:math:`p_A\neq p_B \leq 1` so that the prior mass of the
|
||||
compared models are identical.
|
||||
.. option:: plot
|
||||
|
||||
.. option:: plot
|
||||
|
||||
Plots the marginal prior density.
|
||||
|
||||
|br|
|
||||
|
||||
.. matcomm:: search VARIABLENAME[ OPTION]
|
||||
|
||||
Searches all occurrences of a variable in a model, and prints the
|
||||
equations where the variable appear in the command line window. If OPTION is
|
||||
set to `withparamvalues`, the values of the parameters (if available) are
|
||||
displayed instead of the name of the parameters. Requires the `json` command
|
||||
line option to be set.
|
||||
|
||||
*Example*
|
||||
|
||||
Assuming that we already ran a `.mod` file and that the workspace has not
|
||||
been cleaned after, we can search for all the equations containing variable `X`
|
||||
|
||||
::
|
||||
|
||||
>> search X
|
||||
|
||||
Y = alpha*X/(1-X)+e;
|
||||
|
||||
diff(X) = beta*(X(-1)-mX) + gamma1*Z + gamma2*R + u;
|
||||
|
||||
To replace the parameters with estimated or calibrated parameters:
|
||||
|
||||
::
|
||||
|
||||
>> search X withparamvalues
|
||||
|
||||
Y = 1.254634*X/(1-X)+e;
|
||||
|
||||
diff(X) = -0.031459*(X(-1)-mX) + 0.1*Z - 0.2*R + u;
|
||||
|
||||
|br|
|
||||
|
||||
|
||||
.. matcomm:: dplot [OPTION VALUE[ ...]]
|
||||
|
||||
Plot expressions extracting data from different dseries objects.
|
||||
|
||||
*Options*
|
||||
|
||||
.. option:: --expression EXPRESSION
|
||||
|
||||
``EXPRESSION`` is a mathematical expression involving variables
|
||||
available in the dseries objects, dseries methods, numbers or
|
||||
parameters. All the referenced objects are supposed to be
|
||||
available in the calling workspace.
|
||||
|
||||
.. option:: --dseries NAME
|
||||
|
||||
``NAME`` is the name of a dseries object from which the
|
||||
variables involved in ``EXPRESSION`` will be extracted.
|
||||
|
||||
.. option:: --range DATE1:DATE2
|
||||
|
||||
This option is not mandatory and allows to plot the expressions
|
||||
only over a sub-range. ``DATE1`` and ``DATE2`` must be dates as
|
||||
defined in :ref:`dates in a mod file`.
|
||||
|
||||
.. option:: --style MATLAB_SCRIPT_NAME
|
||||
|
||||
Name of a Matlab script (without extension) containing Matlab
|
||||
commands to customize the produced figure.
|
||||
|
||||
.. option:: --title MATLAB_STRING
|
||||
|
||||
Adds a title to the figure.
|
||||
|
||||
.. option:: --with-legend
|
||||
|
||||
Prints a legend below the produced plot.
|
||||
|
||||
*Remarks*
|
||||
|
||||
- More than one --expression argument is allowed, and they must come first.
|
||||
|
||||
- For each dseries object we plot all the expressions. We use two
|
||||
nested loops, the outer loop is over the dseries objects and the
|
||||
inner loop over the expressions. This determines the ordering of
|
||||
the plotted lines.
|
||||
|
||||
- All dseries objects must be defined in the calling workspace, if a
|
||||
dseries object is missing the routine throws a warning (we only
|
||||
build the plots for the available dseries objects), if all dseries
|
||||
objects are missing the routine throws an error.
|
||||
|
||||
- If the range is not provided, the expressions cannot involve leads or lags.
|
||||
|
||||
*Example*
|
||||
|
||||
::
|
||||
|
||||
>> toto = dseries(randn(100,3), dates('2000Q1'), {'x','y','z'});
|
||||
>> noddy = dseries(randn(100,3), dates('2000Q1'), {'x','y','z'});
|
||||
>> b = 3;
|
||||
>> dplot --expression 2/b*cumsum(x/y(-1)-1) --dseries toto --dseries noddy --range 2001Q1:2024Q1 --title 'This is my plot'
|
||||
|
||||
will produce plots for ``2/b*cumsum(x/y(-1)-1)``, where ``x`` and
|
||||
``y`` are variables in dseries objects ``toto`` and ``noddy``, in
|
||||
the same figure.
|
||||
Plots the marginal prior density.
|
||||
|
|
|
@ -5,13 +5,13 @@ Currently the development team of Dynare is composed of:
|
|||
|
||||
* Stéphane Adjemian (Le Mans Université, Gains)
|
||||
* Michel Juillard (Banque de France)
|
||||
* Sumudu Kankanamge (Le Mans Université and CEPREMAP)
|
||||
* Sumudu Kankanamge (Toulouse School of Economics and CEPREMAP)
|
||||
* Frédéric Karamé (Le Mans Université, Gains and CEPREMAP)
|
||||
* Junior Maih (Norges Bank)
|
||||
* Willi Mutschler (University of Tübingen)
|
||||
* Johannes Pfeifer (University of the Bundeswehr Munich)
|
||||
* Johannes Pfeifer (Universität der Bundeswehr München)
|
||||
* Marco Ratto (European Commission, Joint Research Centre - JRC)
|
||||
* Normann Rion (CEPREMAP)
|
||||
* Normann Rion (CY Cergy Paris Université and CEPREMAP)
|
||||
* Sébastien Villemot (CEPREMAP)
|
||||
|
||||
The following people used to be members of the team:
|
||||
|
@ -26,7 +26,7 @@ The following people used to be members of the team:
|
|||
* Ferhat Mihoubi
|
||||
* George Perendia
|
||||
|
||||
Copyright © 1996-2024, Dynare Team.
|
||||
Copyright © 1996-2023, Dynare Team.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@ Software requirements
|
|||
=====================
|
||||
|
||||
Packaged versions of Dynare are available for Windows (10 and 11), several
|
||||
GNU/Linux distributions (Debian, Ubuntu, Linux Mint, Arch Linux), macOS (13
|
||||
Ventura), and FreeBSD. Dynare should work on other systems, but some
|
||||
GNU/Linux distributions (Debian, Ubuntu, Linux Mint, Arch Linux), macOS (12
|
||||
“Monterey”), and FreeBSD. Dynare should work on other systems, but some
|
||||
compilation steps are necessary in that case.
|
||||
|
||||
In order to run Dynare, you need one of the following:
|
||||
|
||||
* MATLAB, any version ranging from 9.5 (R2018b) to 23.2 (R2023b);
|
||||
* GNU Octave, any version ranging from 7.1.0 to 8.4.0, with the ``statistics`` package
|
||||
* MATLAB, any version ranging from 8.3 (R2014a) to 9.13 (R2022b);
|
||||
* GNU Octave, any version ranging from 6.2.0 to 7.3.0, with the statistics package
|
||||
from `Octave-Forge`_. Note however that the Dynare installer for Windows
|
||||
requires a more specific version of Octave, as indicated on the download
|
||||
page.
|
||||
|
@ -26,8 +26,8 @@ extra features, but are in no way required:
|
|||
* If under MATLAB: the Optimization Toolbox, the Statistics Toolbox,
|
||||
the Control System Toolbox;
|
||||
|
||||
* If under Octave, the following `Octave-Forge`_ packages: ``optim``, ``io``,
|
||||
``control``.
|
||||
* If under Octave, the following `Octave-Forge`_ packages: ``optim, io,
|
||||
control``.
|
||||
|
||||
|
||||
Installation of Dynare
|
||||
|
@ -80,12 +80,8 @@ On Arch Linux, the Dynare package is not in the official repositories, but is
|
|||
available in the `Arch User Repository`_. The needed sources can be
|
||||
downloaded from the `package status in Arch Linux`_.
|
||||
|
||||
There is also a Dynare package for openSUSE, see the `package status in
|
||||
openSUSE`_.
|
||||
|
||||
Dynare will be installed under ``/usr/lib/dynare`` (or ``/usr/lib64/dynare`` on
|
||||
openSUSE). Documentation will be under ``/usr/share/doc/dynare`` (only on
|
||||
Debian, Ubuntu and Linux Mint).
|
||||
Dynare will be installed under ``/usr/lib/dynare``. Documentation will
|
||||
be under ``/usr/share/doc/dynare`` (only on Debian, Ubuntu and Linux Mint).
|
||||
|
||||
|
||||
On macOS
|
||||
|
@ -95,23 +91,29 @@ With MATLAB
|
|||
^^^^^^^^^^^
|
||||
|
||||
To install Dynare for use with MATLAB, execute the automated installer called
|
||||
``dynare-x.y-arch.pkg`` (where *x.y* is the version number and *arch* is either arm64 for Apple Silicon or x86_64 for Intel architectures),
|
||||
and follow the instructions.
|
||||
This installation does not require administrative privileges.
|
||||
If for some reason admin rights are requested, use *Change Install Location* and select *Install for me only*.
|
||||
The default installation directory is ``/Applications/Dynare/x.y-arch``.
|
||||
Installing into ``/Applications/dynare`` might fail if you have older versions of Dynare already installed in ``/Applications/Dynare``.
|
||||
To fix this, modify the ownership by executing the following command in Terminal.app::
|
||||
``dynare-x.y.pkg`` (where *x.y* is the version number), and follow the
|
||||
instructions. The default installation directory is
|
||||
``/Applications/Dynare/x.y``. After installation, this directory will contain
|
||||
several sub-directories, among which are ``matlab``, ``mex``, and ``doc``.
|
||||
|
||||
sudo chown -R "$USER":staff /Applications/Dynare
|
||||
Note that several versions of Dynare can coexist (by default in
|
||||
``/Applications/Dynare``), as long as you correctly adjust your path
|
||||
settings (see :ref:`words-warning`).
|
||||
|
||||
Alternatively, you can modify the installation path in the automated installed using *Customize* and *Location*.
|
||||
After installation, the folder will contain several sub-directories, among which are ``matlab``, ``mex``, and ``doc``.
|
||||
Several versions of Dynare can coexist (by default in ``/Applications/Dynare``),
|
||||
as long as you correctly adjust your path settings (see :ref:`words-warning`).
|
||||
By default, the installer installs a version of GCC (for use with :opt:`use_dll`)
|
||||
in the installation directory, under the ``.brew`` folder. To do so, it also
|
||||
installs a version of Homebrew_ in the same folder and
|
||||
Xcode Command Line Tools (this is an Apple product) in a system folder.
|
||||
|
||||
It is recommended to install the Xcode Command Line Tools (this is an Apple product)
|
||||
and GCC via Homebrew_ (see :ref:`prerequisites-macos`).
|
||||
All of this requires a bit of time and hard disk space. The amount of time it
|
||||
takes will depend on your computing power and internet connection. To reduce
|
||||
the time the Dynare installer takes, you can install Xcode Command Line Tools
|
||||
yourself (see :ref:`prerequisites-macos`). Dynare, Homebrew, and GCC use
|
||||
about 600 MB of disk space while the Xcode Command Line Tools require about 400
|
||||
MB.
|
||||
|
||||
If you do not use the :opt:`use_dll` option, you have the choice to forgo the
|
||||
installation of GCC and hence Dynare will only take about 50 MB of disk space.
|
||||
|
||||
With Octave
|
||||
^^^^^^^^^^^
|
||||
|
@ -186,33 +188,15 @@ Dynare now ships a compilation environment that can be used with the
|
|||
:opt:`use_dll` option. To install this environment correctly, the Dynare
|
||||
installer ensures that the Xcode Command Line Tools (an Apple product) have
|
||||
been installed on a system folder. To install the Xcode Command Line Tools
|
||||
yourself, simply type ``xcode-select --install`` into the terminal
|
||||
yourself, simply type ``xcode-select --install`` into the Terminal
|
||||
(``/Applications/Utilities/Terminal.app``) prompt.
|
||||
Additionally, to make MATLAB aware that you agree to the terms of Xcode, run the following two commands in the Terminal prompt::
|
||||
|
||||
CLT_VERSION=$(pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep version | awk '{print $2}' | cut -d'.' -f1-2)
|
||||
defaults write com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense "${CLT_VERSION}"
|
||||
defaults read com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense
|
||||
|
||||
Otherwise you will see a warning that Xcode is installed, but its license has not been accepted.
|
||||
You can check this e.g. by running the following command in the MATLAB command window::
|
||||
|
||||
mex -setup
|
||||
|
||||
Moreover, we recommend making use of optimized compilation flags when using :opt:`use_dll` and for this you need to install GCC via Homebrew_::
|
||||
|
||||
brew install gcc
|
||||
|
||||
If you already have installed GCC, Dynare will automatically prefer it for :opt:`use_dll`
|
||||
if the binaries are either in ``/opt/homebrew/bin`` on Apple Silicon (arm64) or in ``/usr/local/bin`` on Intel (x86_64) systems.
|
||||
Otherwise, it will fall back to Clang in ``/usr/bin/clang``, which works both on arm64 and x86_64 systems.
|
||||
|
||||
With Octave
|
||||
^^^^^^^^^^^
|
||||
|
||||
The compiler can be installed via Homebrew_. In a terminal, run::
|
||||
|
||||
brew install gcc
|
||||
brew install gcc-12
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
@ -319,7 +303,6 @@ Dynare unusable.
|
|||
.. _Package status in Ubuntu: https://launchpad.net/ubuntu/+source/dynare
|
||||
.. _Package status in Linux Mint: https://community.linuxmint.com/software/view/dynare
|
||||
.. _Package status in Arch Linux: https://aur.archlinux.org/packages/dynare/
|
||||
.. _Package status in openSUSE: https://software.opensuse.org/package/dynare
|
||||
.. _Arch User Repository: https://wiki.archlinux.org/index.php/Arch_User_Repository
|
||||
.. _Dynare website: https://www.dynare.org/
|
||||
.. _Dynare wiki: https://git.dynare.org/Dynare/dynare/wikis
|
||||
|
|
|
@ -94,24 +94,26 @@ Citing Dynare in your research
|
|||
You should cite Dynare if you use it in your research. The
|
||||
recommended way todo this is to cite the present manual, as:
|
||||
|
||||
Stéphane Adjemian, Michel Juillard, Frédéric Karamé, Willi Mutschler,
|
||||
Johannes Pfeifer, Marco Ratto, Normann Rion and Sébastien Villemot (2024),
|
||||
“Dynare: Reference Manual, Version 6,” *Dynare Working Papers*, 80, CEPREMAP
|
||||
Stéphane Adjemian, Houtan Bastani, Michel Juillard, Frédéric Karamé,
|
||||
Ferhat Mihoubi, Willi Mutschler, Johannes Pfeifer, Marco Ratto,
|
||||
Normann Rion and Sébastien Villemot (2022), “Dynare: Reference Manual,
|
||||
Version 5,” *Dynare Working Papers*, 72, CEPREMAP
|
||||
|
||||
For convenience, you can copy and paste the following into your BibTeX file:
|
||||
|
||||
.. code-block:: bibtex
|
||||
|
||||
@TechReport{Adjemianetal2024,
|
||||
author = {Adjemian, St\'ephane and Juillard, Michel and
|
||||
Karam\'e, Fr\'ederic and Mutschler, Willi and
|
||||
Pfeifer, Johannes and Ratto, Marco and
|
||||
@TechReport{Adjemianetal2022,
|
||||
author = {Adjemian, St\'ephane and Bastani, Houtan and
|
||||
Juillard, Michel and Karam\'e, Fr\'ederic and
|
||||
Mihoubi, Ferhat and Mutschler, Willi
|
||||
and Pfeifer, Johannes and Ratto, Marco and
|
||||
Rion, Normann and Villemot, S\'ebastien},
|
||||
title = {Dynare: Reference Manual, Version 6},
|
||||
year = {2024},
|
||||
title = {Dynare: Reference Manual Version 5},
|
||||
year = {2022},
|
||||
institution = {CEPREMAP},
|
||||
type = {Dynare Working Papers},
|
||||
number = {80},
|
||||
number = {72},
|
||||
}
|
||||
|
||||
If you want to give a URL, use the address of the Dynare website:
|
||||
|
|
|
@ -204,7 +204,7 @@ by the ``dynare`` command.
|
|||
.. option:: params_derivs_order=0|1|2
|
||||
|
||||
When :comm:`identification`, :comm:`dynare_sensitivity` (with
|
||||
identification), or :ref:`estimation <estim-comm>` are
|
||||
identification), or :ref:`estimation_cmd <estim-comm>` are
|
||||
present, this option is used to limit the order of the
|
||||
derivatives with respect to the parameters that are calculated
|
||||
by the preprocessor. 0 means no derivatives, 1 means first
|
||||
|
@ -315,7 +315,7 @@ by the ``dynare`` command.
|
|||
Prevent Dynare from printing the output of the steps leading up to the
|
||||
preprocessor as well as the preprocessor output itself.
|
||||
|
||||
.. option:: mexext=mex|mexw64|mexmaci64|mexmaca64|mexa64
|
||||
.. option:: mexext=mex|mexw32|mexw64|mexmaci64|mexa64
|
||||
|
||||
The mex extension associated with your platform to be used
|
||||
when compiling output associated with :opt:`use_dll`.
|
||||
|
@ -363,8 +363,7 @@ by the ``dynare`` command.
|
|||
For local execution under Windows operating system,
|
||||
set ``parallel_use_psexec=false`` to use ``start``
|
||||
instead of ``psexec``, to properly allocate affinity when there are
|
||||
more than 32 cores in the local machine. This option is also helpful if
|
||||
``psexec`` cannot be executed due to missing admininstrator privileges. [default=true]
|
||||
more than 32 cores in the local machine. [default=true]
|
||||
|
||||
.. option:: -DMACRO_VARIABLE[=MACRO_EXPRESSION]
|
||||
|
||||
|
@ -409,11 +408,9 @@ by the ``dynare`` command.
|
|||
|
||||
.. option:: fast
|
||||
|
||||
Don’t rewrite the output files otherwise written to the disk by the preprocessor
|
||||
when re-running the same model file while the lists of variables and the equations
|
||||
haven’t changed. Note that the whole model still needs to be preprocessed. This option
|
||||
is most useful with model option :opt:`use_dll`, because
|
||||
the time-consuming compilation of the MEX files will be skipped. We use a 32
|
||||
Only useful with model option :opt:`use_dll`. Don’t recompile the
|
||||
MEX files when running again the same model file and the lists
|
||||
of variables and the equations haven’t changed. We use a 32
|
||||
bit checksum, stored in ``<model filename>/checksum``. There
|
||||
is a very small probability that the preprocessor misses a
|
||||
change in the model. In case of doubt, re-run without the fast
|
||||
|
@ -554,13 +551,13 @@ by the ``dynare`` command.
|
|||
executing the ``dynare`` command will leave variables containing
|
||||
results in the workspace available for further processing. More
|
||||
details are given under the relevant computing tasks. The
|
||||
``M_``, ``oo_``, and ``options_`` structures are saved in a file
|
||||
``M_``,``oo_``, and ``options_`` structures are saved in a file
|
||||
called ``FILENAME_results.mat`` located in the ``MODFILENAME/Output`` folder.
|
||||
If they exist, ``estim_params_``,
|
||||
``bayestopt_``, ``dataset_``, ``oo_recursive_`` and
|
||||
``estimation_info`` are saved in the same file. Note that MATLAB
|
||||
by default only allows ``.mat`` files up to 2GB. You can lift this
|
||||
restriction by enabling the ``save -v7.3`` option in
|
||||
``estimation_info`` are saved in the same file. Note that Matlab
|
||||
by default only allows ``.mat``-files up to 2GB. You can lift this
|
||||
restriction by enabling the ``save -v7.3``-option in
|
||||
``Preferences -> General -> MAT-Files``.
|
||||
|
||||
.. matvar:: M_
|
||||
|
@ -675,7 +672,7 @@ parser would continue processing.
|
|||
|
||||
It is also helpful to keep in mind that any piece of code that does not violate
|
||||
Dynare syntax, but at the same time is not recognized by the parser, is interpreted
|
||||
as native MATLAB code. This code will be directly passed to the driver script.
|
||||
Investigating the ``driver.m`` file then helps with debugging. Such problems most often
|
||||
as native MATLAB code. This code will be directly passed to the ``driver`` script.
|
||||
Investigating ``driver.m`` file then helps with debugging. Such problems most often
|
||||
occur when defined variable or parameter names have been misspelled so that Dynare's
|
||||
parser is unable to recognize them.
|
||||
|
|
|
@ -15,16 +15,11 @@ related to the model (and hence not placed in the model file). At the
|
|||
moment, it is only used when using Dynare to run parallel
|
||||
computations.
|
||||
|
||||
On Linux and macOS, the configuration file is searched by default under
|
||||
``dynare/dynare.ini`` in the configuration directories defined by the XDG
|
||||
specification (typically ``$HOME/.config/dynare/dynare.ini`` for the
|
||||
user-specific configuration and ``/etc/xdg/dynare/dynare.ini`` for the
|
||||
system-wide configuration, the former having precedence over the latter). Under
|
||||
Windows, the configuration file is searched by default in
|
||||
``%APPDATA%\dynare\dynare.ini`` (typically
|
||||
``c:\Users\USERNAME\AppData\Roaming\dynare\dynare.ini``). You can specify a non
|
||||
standard location using the ``conffile`` option of the ``dynare`` command (see
|
||||
:ref:`dyn-invoc`).
|
||||
On Linux and macOS, the default location of the configuration file is
|
||||
``$HOME/.dynare``, while on Windows it is ``%APPDATA%\dynare.ini``
|
||||
(typically ``c:\Users\USERNAME\AppData\dynare.ini``). You
|
||||
can specify a non standard location using the ``conffile`` option of
|
||||
the ``dynare`` command (see :ref:`dyn-invoc`).
|
||||
|
||||
The parsing of the configuration file is case-sensitive and it should
|
||||
take the following form, with each option/choice pair placed on a
|
||||
|
@ -59,7 +54,7 @@ conventions such as ``USER_NAME`` have been excluded for concision):
|
|||
``PATH_AND_FILE``
|
||||
|
||||
Indicates a valid path to a file in the underlying operating
|
||||
system (e.g. ``/usr/local/MATLAB/R2023b/bin/matlab``).
|
||||
system (e.g. ``/usr/local/MATLAB/R2010b/bin/matlab``).
|
||||
|
||||
``BOOLEAN``
|
||||
|
||||
|
@ -81,15 +76,8 @@ processing. Currently, there is only one option available.
|
|||
|
||||
.. option:: GlobalInitFile = PATH_AND_FILE
|
||||
|
||||
The location of a global initialization file that can be used to
|
||||
customize some Dynare internals (typically default option values). This
|
||||
is a MATLAB/Octave script.
|
||||
|
||||
If this option is not specified, Dynare will look for a
|
||||
``global_init.m`` file in its configuration directory (typically
|
||||
``$HOME/.config/dynare/global_init.m`` under Linux and macOS, and
|
||||
``c:\Users\USERNAME\AppData\Roaming\dynare\global_init.m`` under
|
||||
Windows).
|
||||
The location of the global initialization file to be run at
|
||||
the end of ``global_initialization.m``.
|
||||
|
||||
*Example*
|
||||
|
||||
|
@ -282,42 +270,18 @@ lines starting with a hashtag (#).
|
|||
.. option:: MatlabOctavePath = PATH_AND_FILE
|
||||
|
||||
The path to the MATLAB or Octave executable. The default value
|
||||
is ``matlab`` as MATLAB’s executable is typically in the %PATH% environment
|
||||
variable. When using full paths on Windows, you may need to enclose the path
|
||||
in quoted strings, e.g. ``MatlabOctavePath="C:\Program Files\MATLAB\R2023b\bin\matlab.exe"``
|
||||
is ``matlab``.
|
||||
|
||||
.. option:: NumberOfThreadsPerJob = INTEGER
|
||||
|
||||
This option controls the distribution of jobs (e.g. MCMC chains) across additional MATLAB instances that are run in parallel.
|
||||
Needs to be an exact divisor of the number of cores.
|
||||
The formula :opt:`CPUnbr <CPUnbr = INTEGER | [INTEGER:INTEGER]>` divided by :opt:`NumberOfThreadsPerJob <NumberOfThreadsPerJob = INTEGER>`
|
||||
calculates the number of MATLAB/Octave instances that will be launched in parallel,
|
||||
where each instance will then execute a certain number of jobs sequentially.
|
||||
For example, if you run a MCMC estimation with 24 chains on a 12 core machine, setting ``CPUnbr = 12`` and ``NumberOfThreadsPerJob = 4``
|
||||
will launch 3 MATLAB instances in parallel, each of which will compute 8 chains sequentially.
|
||||
Note that this option does not dictate the number of maximum threads utilized by each MATLAB/Octave instance,
|
||||
see related option :opt:`SingleCompThread <SingleCompThread = BOOLEAN>` for this.
|
||||
Particularly for very large models, setting this option to 2 might distribute the workload in a
|
||||
more efficient manner, depending on your hardware and task specifics.
|
||||
It’s advisable to experiment with different values to achieve optimal performance.
|
||||
The default value is ``1``.
|
||||
|
||||
For Windows nodes, sets the number of threads assigned to each
|
||||
remote MATLAB/Octave run. The default value is 1.
|
||||
|
||||
.. option:: SingleCompThread = BOOLEAN
|
||||
|
||||
This option allows you to enable or disable MATLAB’s native multithreading capability. When set to ``true``,
|
||||
the additional MATLAB instances are initiated in single thread mode utilizing the ``-singleCompThread`` startup option,
|
||||
thereby disabling MATLAB’s native multithreading. When set to ``false``, MATLAB’s native multithreading
|
||||
is enabled, e.g. the actual number of threads utilized by each MATLAB instance is usually determined by the number of CPU cores
|
||||
(you can check this by running ``maxNumCompThreads`` in MATLAB’s command window).
|
||||
Note: While MATLAB aims to accelerate calculations by distributing them across your computer’s threads,
|
||||
certain tasks, like MCMC estimations, may exhibit slowdowns with MATLAB’s multitasking especially when Dynare’s parallel computing is turned on
|
||||
as we do not use MATLAB’s parallel toolbox.
|
||||
So in many cases it is advisable to set this setting to ``true``.
|
||||
If you want to have more control, you can manually add the MATLAB command `maxNumCompThreads(N)` at the beginning of `fParallel.m`.
|
||||
The default value is ``false``. This option is ineffective under Octave.
|
||||
Whether or not to disable MATLAB’s native multithreading. The
|
||||
default value is ``false``. Option meaningless under Octave.
|
||||
|
||||
|
||||
.. option:: OperatingSystem = OPERATING_SYSTEM
|
||||
|
||||
The operating system associated with a node. Only necessary
|
||||
|
@ -359,9 +323,7 @@ Windows Step-by-Step Guide
|
|||
==========================
|
||||
|
||||
This section outlines the steps necessary on most Windows systems to
|
||||
set up Dynare for parallel execution. Note that the steps 3 to 6 are
|
||||
required unless parallel execution is confined to a local pool
|
||||
with the ``parallel_use_psexec=false`` option.
|
||||
set up Dynare for parallel execution.
|
||||
|
||||
1. Write a configuration file containing the options you want. A
|
||||
mimimum working example setting up a cluster consisting of two
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,15 +15,13 @@ class and methods for dates. Below, you will first find the class and
|
|||
methods used for creating and dealing with dates and then the class
|
||||
used for using time series. Dynare also provides an interface to the
|
||||
X-13 ARIMA-SEATS seasonal adjustment program produced, distributed, and
|
||||
maintained by the U.S. Census Bureau (2020).
|
||||
maintained by the US Census Bureau (2017).
|
||||
|
||||
|
||||
Dates
|
||||
=====
|
||||
.. highlight:: matlab
|
||||
|
||||
.. _dates in a mod file:
|
||||
|
||||
Dates in a mod file
|
||||
-------------------
|
||||
|
||||
|
@ -719,7 +717,7 @@ The dates class
|
|||
|
||||
|br| Overloads the MATLAB/Octave ``mtimes`` operator
|
||||
(``*``). ``A`` and ``B`` are respectively expected to be a
|
||||
``dates`` object and a scalar integer. Returns ``dates``
|
||||
``dseries`` object and a scalar integer. Returns ``dates``
|
||||
object ``A`` replicated ``B`` times.
|
||||
|
||||
*Example*
|
||||
|
@ -1027,7 +1025,7 @@ The dseries class
|
|||
``.xls/.xlsx`` (Octave only supports ``.xlsx`` files and the
|
||||
`io <https://octave.sourceforge.io/io/>`__ package from
|
||||
Octave-Forge must be installed). The extension of the file
|
||||
should be explicitly provided.
|
||||
should be explicitly provided.
|
||||
|
||||
A typical ``.m`` file will have the following form::
|
||||
|
||||
|
@ -1054,10 +1052,10 @@ The dseries class
|
|||
typically usefull if ``INIT__`` is not provided in the data
|
||||
file.
|
||||
|
||||
If an ``.xlsx`` file is used, the first row should be a header
|
||||
containing the variable names. The first column may contain date
|
||||
information that must correspond to a valid date format recognized
|
||||
by Dynare. If such date information is specified in the first column,
|
||||
If an ``.xlsx`` file is used, the first row should be a header
|
||||
containing the variable names. The first column may contain date
|
||||
information that must correspond to a valid date format recognized
|
||||
by Dynare. If such date information is specified in the first column,
|
||||
its header name must be left empty.
|
||||
|
||||
.. construct:: dseries (DATA_MATRIX[,INITIAL_DATE[,LIST_OF_NAMES[,TEX_NAMES]]])
|
||||
|
@ -1965,13 +1963,6 @@ The dseries class
|
|||
|br| Returns the last period where all the variables in ``dseries`` object ``A`` are observed (non NaN).
|
||||
|
||||
|
||||
.. dseriesmethod:: f = lastobservedperiods (A)
|
||||
|
||||
|br| Returns for each variable the last period without missing
|
||||
observations in ``dseries`` object ``A``. Output argument ``f`` is a
|
||||
structure, each field name is the name of a variable in ``A``, each field
|
||||
content is a singleton ``date`` object.
|
||||
|
||||
.. dseriesmethod:: B = lead (A[, p])
|
||||
lead_ (A[, p])
|
||||
|
||||
|
@ -2600,10 +2591,8 @@ The dseries class
|
|||
.. dseriesmethod:: C = remove (A, B)
|
||||
remove_ (A, B)
|
||||
|
||||
|br| If ``B`` is a row char array, the name of a variable, these methods
|
||||
are aliases for ``pop`` and ``pop_`` methods with two arguments. They
|
||||
remove variable ``B`` from ``dseries`` object ``A``. To remove more than
|
||||
one variable, one can pass a cell of row char arrays for ``B``.
|
||||
|br| Alias for the ``pop`` method with two arguments. Removes
|
||||
variable ``B`` from ``dseries`` object ``A``.
|
||||
|
||||
*Example*
|
||||
|
||||
|
@ -2957,8 +2946,8 @@ X-13 ARIMA-SEATS interface
|
|||
|
||||
|br| The x13 class provides a method for each X-13 command as
|
||||
documented in the X-13 ARIMA-SEATS reference manual (`x11`,
|
||||
`automdl`, `estimate`, ...). The respective options (see Chapter 7 of U.S. Census Bureau (2020))
|
||||
can then be passed by key/value pairs. The ``x13`` class has 22 members:
|
||||
`automdl`, `estimate`, ...), options can then be passed by
|
||||
key/value pairs. The ``x13`` class has 22 members:
|
||||
|
||||
:arg y: ``dseries`` object with a single variable.
|
||||
:arg x: ``dseries`` object with an arbitrary number of variables (to be used in the REGRESSION block).
|
||||
|
@ -3002,7 +2991,7 @@ X-13 ARIMA-SEATS interface
|
|||
same time span.
|
||||
|
||||
|
||||
The following methods allow to set sequence of X-13 commands, write an `.spc` file, and run the X-13 binary:
|
||||
The Following methods allow to set sequence of X-13 commands, write an `.spc` file and run the X-13 binary:
|
||||
|
||||
|
||||
.. x13method:: A = arima (A, key, value[, key, value[, [...]]])
|
||||
|
@ -3037,10 +3026,7 @@ X-13 ARIMA-SEATS interface
|
|||
|
||||
Interface to the ``transform`` command, see the X-13
|
||||
ARIMA-SEATS reference manual. All the options must be passed
|
||||
by key/value pairs. For example, the key/value pair ``function,log``
|
||||
instructs the use of a multiplicative instead of an additive seasonal pattern,
|
||||
while ``function,auto`` triggers an automatic selection between the two based
|
||||
on their fit.
|
||||
by key/value pairs.
|
||||
|
||||
|
||||
.. x13method:: A = outlier (A, key, value[, key, value[, [...]]])
|
||||
|
@ -3148,11 +3134,6 @@ X-13 ARIMA-SEATS interface
|
|||
``A.results``. When it makes sense these results are saved in
|
||||
``dseries`` objects (*e.g.* for forecasts or filtered variables).
|
||||
|
||||
.. x13method:: clean (A)
|
||||
|
||||
Removes the temporary files created by an x13 run that store the intermediate
|
||||
results. This method allows keeping the main folder clean but will also
|
||||
delete potentially important debugging information.
|
||||
|
||||
*Example*
|
||||
|
||||
|
@ -3170,57 +3151,6 @@ X-13 ARIMA-SEATS interface
|
|||
|
||||
>> o.run();
|
||||
|
||||
The above example shows a run of X13 with various commands an options specified.
|
||||
|
||||
|
||||
*Example*
|
||||
|
||||
::
|
||||
|
||||
% 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960
|
||||
y = [112 115 145 171 196 204 242 284 315 340 360 417 ... % Jan
|
||||
118 126 150 180 196 188 233 277 301 318 342 391 ... % Feb
|
||||
132 141 178 193 236 235 267 317 356 362 406 419 ... % Mar
|
||||
129 135 163 181 235 227 269 313 348 348 396 461 ... % Apr
|
||||
121 125 172 183 229 234 270 318 355 363 420 472 ... % May
|
||||
135 149 178 218 243 264 315 374 422 435 472 535 ... % Jun
|
||||
148 170 199 230 264 302 364 413 465 491 548 622 ... % Jul
|
||||
148 170 199 242 272 293 347 405 467 505 559 606 ... % Aug
|
||||
136 158 184 209 237 259 312 355 404 404 463 508 ... % Sep
|
||||
119 133 162 191 211 229 274 306 347 359 407 461 ... % Oct
|
||||
104 114 146 172 180 203 237 271 305 310 362 390 ... % Nov
|
||||
118 140 166 194 201 229 278 306 336 337 405 432 ]'; % Dec
|
||||
|
||||
ts = dseries(y,'1949M1');
|
||||
o = x13(ts);
|
||||
o.transform('function','auto','savelog','atr');
|
||||
o.automdl('savelog','all');
|
||||
o.x11('save','(d11 d10)');
|
||||
o.run();
|
||||
o.clean();
|
||||
|
||||
y_SA=o.results.d11;
|
||||
y_seasonal_pattern=o.results.d10;
|
||||
|
||||
figure('Name','Comparison raw data and SAed data');
|
||||
plot(ts.dates,log(o.y.data),ts.dates,log(y_SA.data),ts.dates,log(y_seasonal_pattern.data))
|
||||
|
||||
|
||||
The above example shows how to remove a seasonal pattern from a time series.
|
||||
``o.transform('function','auto','savelog','atr')`` instructs the subsequent
|
||||
``o.automdl()`` command to check whether an additional or a multiplicative
|
||||
pattern fits the data better and to save the result. The result is saved in
|
||||
`o.results.autotransform`, which in the present example indicates that a
|
||||
log transformation, i.e. a multiplicative model was preferred. The ``o.automdl('savelog','all')`` automatically selects a fitting
|
||||
ARIMA model and saves all relevant output to the .log-file. The ``o.x11('save','(d11, d10)')`` instructs
|
||||
``x11`` to save both the final seasonally adjusted series ``d11`` and the final seasonal factor ``d10``
|
||||
into ``dseries`` with the respective names in the output structure ``o.results``. ``o.clean()`` removes the
|
||||
temporary files created by ``o.run()``. Among these are the ``.log``-file storing
|
||||
summary information, the ``.err``-file storing information on problems encountered,
|
||||
the ``.out``-file storing the raw output, and the `.spc`-file storing the specification for the `x11` run.
|
||||
There may be further files depending on the output requested. The last part of the example reads out the
|
||||
results and plots a comparison of the logged raw data and its log-additive decomposition into a
|
||||
seasonal pattern and the seasonally adjusted series.
|
||||
|
||||
Miscellaneous
|
||||
=============
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright © 2018-2024 Dynare Team
|
||||
# Copyright © 2018-2019 Dynare Team
|
||||
#
|
||||
# This file is part of Dynare.
|
||||
#
|
||||
|
@ -80,7 +80,9 @@ class DynObject(ObjectDescription):
|
|||
signode += addnodes.desc_name(name, name)
|
||||
|
||||
if self.has_arguments:
|
||||
if arglist:
|
||||
if not arglist:
|
||||
signode += addnodes.desc_parameterlist()
|
||||
else:
|
||||
signode += addnodes.desc_addname(arglist,arglist)
|
||||
return fullname, prefix
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class DynareLexer(RegexLexer):
|
|||
"addSeries","addParagraph","addVspace","write","compile")
|
||||
|
||||
operators = (
|
||||
"STEADY_STATE","EXPECTATION","var_expectation","pac_expectation","pac_target_nonstationary")
|
||||
"STEADY_STATE","EXPECTATION","var_expectation","pac_expectation")
|
||||
|
||||
macro_dirs = (
|
||||
"@#includepath", "@#include", "@#define", "@#if",
|
||||
|
@ -83,8 +83,7 @@ class DynareLexer(RegexLexer):
|
|||
'osr_params_bounds','ramsey_constraints','irf_calibration',
|
||||
'moment_calibration','identification','svar_identification',
|
||||
'matched_moments','occbin_constraints','surprise','overwrite','bind','relax',
|
||||
'verbatim','end','node','cluster','paths','hooks','target','pac_target_info','auxname_target_nonstationary',
|
||||
'component', 'growth', 'auxname', 'kind'), prefix=r'\b', suffix=r'\s*\b'),Keyword.Reserved),
|
||||
'verbatim','end','node','cluster','paths','hooks'), prefix=r'\b', suffix=r'\s*\b'),Keyword.Reserved),
|
||||
|
||||
# FIXME: Commands following multiline comments are not highlighted properly.
|
||||
(words(commands + report_commands,
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
version = u'@PACKAGE_VERSION@'
|
||||
release = u'@PACKAGE_VERSION@'
|
|
@ -0,0 +1,29 @@
|
|||
if ENABLE_DOC
|
||||
pdf-local: parallel.pdf
|
||||
endif
|
||||
|
||||
SRC = AvenueParadigm.pdf iVaNo_gain.pdf iVaNo_time_comp.pdf marco.bib \
|
||||
netbook_complete_comp.pdf netbook_complete_openclose.pdf \
|
||||
netbook_partial_comp.pdf netbook_partial_openclose.pdf parallel.tex \
|
||||
quest_complete_comp.pdf quest_complete_openclose.pdf quest_partial_comp.pdf \
|
||||
quest_partial_openclose.pdf RWMH_quest1_PriorsAndPosteriors1Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors2Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors3Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors4Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors5Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors6Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors7Comp.pdf waitbars1.pdf waitbars2.pdf \
|
||||
waitbarsP.pdf
|
||||
|
||||
EXTRA_DIST = $(SRC)
|
||||
|
||||
parallel.pdf: $(SRC)
|
||||
$(PDFLATEX) parallel
|
||||
$(BIBTEX) parallel
|
||||
$(PDFLATEX) parallel
|
||||
$(PDFLATEX) parallel
|
||||
$(PDFLATEX) parallel
|
||||
|
||||
clean-local:
|
||||
rm -f *.log *.aux *.toc *.blg *.bbl *.out
|
||||
rm -f parallel.pdf
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,11 @@
|
|||
SUBDIRS = utils/cc sylv parser/cc tl doc integ kord src tests
|
||||
|
||||
EXTRA_DIST = dynare_simul
|
||||
|
||||
install-exec-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/dynare++
|
||||
cp -r dynare_simul/* $(DESTDIR)$(pkglibdir)/dynare++
|
||||
|
||||
uninstall-local:
|
||||
rm -rf $(DESTDIR)$(pkglibdir)/dynare++
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
EXTRA_DIST = \
|
||||
dynare++-ramsey.tex \
|
||||
dynare++-tutorial.tex \
|
||||
sylvester.tex \
|
||||
tl.tex \
|
||||
changelog-old.html \
|
||||
changelog-sylv-old.html
|
||||
|
||||
if ENABLE_DOC
|
||||
pdf-local: dynare++-ramsey.pdf dynare++-tutorial.pdf sylvester.pdf tl.pdf
|
||||
endif
|
||||
|
||||
%.pdf: %.tex
|
||||
$(PDFLATEX) $<
|
||||
$(PDFLATEX) $<
|
||||
$(PDFLATEX) $<
|
||||
|
||||
CLEANFILES = *.pdf *.log *.aux *.out *.toc
|
||||
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
<HTML>
|
||||
<TITLE>
|
||||
Dynare++ Change Log
|
||||
</TITLE>
|
||||
<!-- $Header$ -->
|
||||
<BODY>
|
||||
<TABLE CELLSPACING=2 ALIGN="CENTER" BORDER=1>
|
||||
<TR>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="85"> <b>Revision</b> </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="85"> <b>Version</b></TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="80"> <b>Date</b> </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="600"> <b>Description of changes</b></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD>
|
||||
<TD>1.3.7
|
||||
<TD>2008/01/15
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a serious bug in centralizing a
|
||||
decision rule. This bug implies that all results based on simulations
|
||||
of the decision rule were wrong. However results based on stochastic
|
||||
fix points were correct. Thanks to Wouter J. den Haan and Joris de Wind!
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added options --centralize and --no-centralize.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected an error of a wrong
|
||||
variance-covariance matrix in real-time simulations (thanks to Pawel
|
||||
Zabzcyk).
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug of integer overflow in refined
|
||||
faa Di Bruno formula if one of refinements is empty. This bug appeared
|
||||
when solving models without forward looking variables.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug in the Sylvester equation
|
||||
formerly working only for models with forward looking variables.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug in global check printout.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added generating a dump file.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Fixed a bug of forgetting repeated assignments
|
||||
(for example in parameter settings and initval).
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added a diff operator to the parser.
|
||||
|
||||
<TR>
|
||||
<TD>1539
|
||||
<TD>1.3.6
|
||||
<TD>2008/01/03
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug of segmentation faults for long
|
||||
names and path names.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Changed a way how random numbers are
|
||||
generated. Dynare++ uses a separate instance of Mersenne twister for
|
||||
each simulation, this corrects a flaw of additional randomness caused
|
||||
by operating system scheduler. This also corrects a strange behaviour
|
||||
of random generator on Windows, where each simulation was getting the
|
||||
same sequence of random numbers.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added calculation of conditional distributions
|
||||
controlled by --condper and --condsim.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Dropped creating unfoled version of decision
|
||||
rule at the end. This might consume a lot of memory. However,
|
||||
simulations might be slower for some models.
|
||||
|
||||
<TR>
|
||||
<TD>1368
|
||||
<TD>1.3.5
|
||||
<TD>2007/07/11
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug of useless storing all derivative
|
||||
indices in a parser. This consumed a lot of memory for large models.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added an option <tt>--ss-tol</tt> controlling a
|
||||
tolerance used for convergence of a non-linear solver.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected buggy interaction of optimal policy
|
||||
and forward looking variables with more than one period.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Variance matrices can be positive
|
||||
semidefinite. This corrects a bug of throwing an error if estimating
|
||||
approximation errors on ellipse of the state space with a
|
||||
deterministic variable.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Implemented simulations with statistics
|
||||
calculated in real-time. Options <tt>--rtsim</tt> and <tt>--rtper</tt>.
|
||||
|
||||
<TR>
|
||||
<TD>1282
|
||||
<TD>1.3.4
|
||||
<TD>2007/05/15
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of wrong representation of NaN in generated M-files.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of occassionaly wrong evaluation of higher order derivatives of integer powers.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Implemented automatic handling of terms involving multiple leads.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug in the numerical integration, i.e. checking of the precision of the solution.
|
||||
|
||||
<TR>
|
||||
<TD>1090
|
||||
<TD>1.3.3
|
||||
<TD>2006/11/20
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of non-registering an auxiliary variable in initval assignments.
|
||||
|
||||
<TR>
|
||||
<TD>988
|
||||
<TD>1.3.2
|
||||
<TD>2006/10/11
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a few not-serious bugs: segfault on
|
||||
some exception, error in parsing large files, error in parsing
|
||||
matrices with comments, a bug in dynare_simul.m
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added posibility to specify a list of shocks for
|
||||
which IRFs are calculated
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added --order command line switch
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added writing two MATLAB files for steady state
|
||||
calcs
|
||||
|
||||
<TR><TD><TD><TD> <TD>Implemented optimal policy using keyword
|
||||
planner_objective and planner_discount
|
||||
|
||||
<TR><TD><TD><TD> <TD>Implemented an R interface to Dynare++ algorithms
|
||||
(Tamas Papp)
|
||||
|
||||
<TR><TD><TD><TD> <TD>Highlevel code reengineered to allow for
|
||||
different model inputs
|
||||
|
||||
<TR>
|
||||
<TD>799
|
||||
<TD>1.3.1
|
||||
<TD>2006/06/13
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected few bugs: in error functions, in linear algebra module.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Updated dynare_simul.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Updated the tutorial.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected an error in summing up tensors where
|
||||
setting up the decision rule derivatives. Thanks to Michel
|
||||
Juillard. The previous version was making deterministic effects of
|
||||
future volatility smaller than they should be.
|
||||
|
||||
<TR>
|
||||
<TD>766
|
||||
<TD>1.3.0
|
||||
<TD>2006/05/22
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>The non-linear solver replaced with a new one.
|
||||
|
||||
<TR><TD><TD><TD> <TD>The parser and derivator replaced with a new
|
||||
code. Now it is possible to put expressions in parameters and initval
|
||||
sections.
|
||||
|
||||
<TR>
|
||||
<TD>752
|
||||
<TD>1.2.2
|
||||
<TD>2006/05/22
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added an option triggering/suppressing IRF calcs..
|
||||
|
||||
<TR><TD><TD><TD> <TD>Newton algortihm is now used for fix-point calculations.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Vertical narrowing of tensors in Faa Di Bruno
|
||||
formula to avoid multiplication with zeros..
|
||||
|
||||
<TR>
|
||||
<TD>436
|
||||
<TD>1.2.1
|
||||
<TD>2005/08/17
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Faa Di Bruno for sparse matrices optimized. The
|
||||
implementation now accommodates vertical refinement of function stack
|
||||
in order to fit a corresponding slice to available memory. In
|
||||
addition, zero slices are identified. For some problems, this implies
|
||||
significant speedup.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Analytic derivator speedup.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug in the threading code. The bug
|
||||
stayed concealed in Linux 2.4.* kernels, and exhibited in Linux 2.6.*,
|
||||
which has a different scheduling. This correction also allows using
|
||||
detached threads on Windows.
|
||||
|
||||
<TR>
|
||||
<TD>410
|
||||
<TD>1.2
|
||||
<TD>2005/07/29
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added Dynare++ tutorial.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Changed and enriched contents of MAT-4 output
|
||||
file.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of wrong variable indexation
|
||||
resulting in an exception. The error occurred if a variable appeared
|
||||
at time t-1 or t+1 and not at t.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added MATLAB interface, which allows simulation
|
||||
of a decision rule in MATLAB.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Got rid of Matrix Template Library.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added checking of model residuals by the
|
||||
numerical integration. Three methods: checking along simulation path,
|
||||
checking along shocks, and on ellipse of states.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug in calculation of higher moments
|
||||
of Normal dist.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of wrong drawing from Normal dist
|
||||
with non-zero covariances.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Added numerical integration module. Product and Smolyak
|
||||
quadratures over Gauss-Hermite and Gauss-Legendre, and quasi Monte
|
||||
Carlo.
|
||||
|
||||
<TR>
|
||||
<TD>152
|
||||
<TD>1.1
|
||||
<TD>2005/04/22
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Added a calculation of approximation at a stochastic steady state
|
||||
(still experimental).
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Corrected a bug in Cholesky decomposition of variance-covariance
|
||||
matrix with off-diagonal elements.
|
||||
|
||||
<TR>
|
||||
<TD>89
|
||||
<TD>1.01
|
||||
<TD>2005/02/23
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Added version printout.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Corrected the bug of multithreading support for P4 HT processors running on Win32.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Enhanced Kronecker product code resulting in approx. 20% speedup.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Implemented vertical stack container refinement, and another
|
||||
method for sparse folded Faa Di Bruno (both not used yet).
|
||||
|
||||
<TR>
|
||||
<TD>5
|
||||
<TD>1.0
|
||||
<TD>2005/02/23
|
||||
<TD>The first released version.
|
||||
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,140 @@
|
|||
<HTML>
|
||||
<!-- $Header: /var/lib/cvs/dynare_cpp/sylv/change_log.html,v 1.1.1.1 2004/06/04 13:00:05 kamenik Exp $ -->
|
||||
<!-- Tag $Name: $ -->
|
||||
<TITLE>
|
||||
Sylvester Solver Change Log
|
||||
</TITLE>
|
||||
<BODY>
|
||||
<TABLE CELLSPACING=2 ALIGN="CENTER" BORDER=1>
|
||||
<TR>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="85"> Tag </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="80"> Date </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="600"> Description/Changes</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD>2003/09/10</TD>
|
||||
<TD>Initial version solving triangular system put to repository</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented solution of general case.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented a memory pool (Paris).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented MEX interface to the routine (Paris).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented QuasiTriangularZero (Paris) (not fully used yet).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-1</TD>
|
||||
<TD>2003/10-02</TD>
|
||||
<TD>Version sent to Michel.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Inheritance streamlined, QuasiTriangular inherits from GeneralMatrix.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented block diagonalization algorithm.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Solution routines rewritten so that the output rewrites input,
|
||||
considerable memory improvement.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>MEX interface now links with LAPACK library from MATLAB.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Added a hack to MEX library loading in order to avoid MATLAB crash in Wins.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-2</TD>
|
||||
<TD>2003/10/15</TD>
|
||||
<TD>Version sent to Michel.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>KronUtils now rewrite input by output using less memory.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Added iterative solution algorithm (doubling).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Introduced abstraction for set of parameters (SylvParams).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Algorithm enabled to solve problems with singular C.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented a class chooser chossing between QuasiTriangularZero,
|
||||
and QuasiTriangular (padded with zero) depending on size of the
|
||||
problem. Full use of QuasiTriangularZero.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Reimplemented QuasiTriangular::solve, offdiagonal elements are
|
||||
eleiminated by gauss with partial pivoting, not by transformation of
|
||||
complex eigenvalues. More stable for ill conditioned eigenvalues.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Reimplemented calculation of eliminating vectors, much more
|
||||
numerically stable now.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented algorithm for ordering of eigenvalues (not used now,
|
||||
no numerical improvements).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-3</TD>
|
||||
<TD>2003/12/4</TD>
|
||||
<TD>Version sent to Michel.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>GeneralMatrix separated for use outside, in sylv module we use
|
||||
its subclass SylvMatrix. Implemented ConstGeneralMatrix (useful outside).
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-4</TD>
|
||||
<TD>2004/6/4</TD>
|
||||
<TD>Version, which was moved to pythie.cepremap.cnrs.fr repository.</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,157 @@
|
|||
\documentclass[10pt]{article}
|
||||
\usepackage{array,natbib,times}
|
||||
\usepackage{amsmath, amsthm, amssymb}
|
||||
|
||||
%\usepackage[pdftex,colorlinks]{hyperref}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\title{Implementation of Ramsey Optimal Policy in Dynare++, Timeless Perspective}
|
||||
|
||||
\author{Ondra Kamen\'\i k}
|
||||
|
||||
\date{June 2006}
|
||||
\maketitle
|
||||
|
||||
\textbf{Abstract:} This document provides a derivation of Ramsey
|
||||
optimal policy from timeless perspective and describes its
|
||||
implementation in Dynare++.
|
||||
|
||||
\section{Derivation of the First Order Conditions}
|
||||
|
||||
Let us start with an economy populated by agents who take a number of
|
||||
variables exogenously, or given. These may include taxes or interest
|
||||
rates for example. These variables can be understood as decision (or control)
|
||||
variables of the timeless Ramsey policy (or social planner). The agent's
|
||||
information set at time $t$ includes mass-point distributions of these
|
||||
variables for all times after $t$. If $i_t$ denotes an interest rate
|
||||
for example, then the information set $I_t$ includes
|
||||
$i_{t|t},i_{t+1|t},\ldots,i_{t+k|t},\ldots$ as numbers. In addition
|
||||
the information set includes all realizations of past exogenous
|
||||
innovations $u_\tau$ for $\tau=t,t-1,\ldots$ and distibutions
|
||||
$u_\tau\sim N(0,\Sigma)$ for $\tau=t+1,\ldots$. These information sets will be denoted $I_t$.
|
||||
|
||||
An information set including only the information on past realizations
|
||||
of $u_\tau$ and future distributions of $u_\tau\sim N(0\sigma)$ will
|
||||
be denoted $J_t$. We will use the following notation for expectations
|
||||
through these sets:
|
||||
\begin{eqnarray*}
|
||||
E^I_t[X] &=& E(X|I_t)\\
|
||||
E^J_t[X] &=& E(X|J_t)
|
||||
\end{eqnarray*}
|
||||
|
||||
The agents optimize taking the decision variables of the social
|
||||
planner at $t$ and future as given. This means that all expectations
|
||||
they form are conditioned on the set $I_t$. Let $y_t$ denote a vector
|
||||
of all endogenous variables including the planer's decision
|
||||
variables. Let the number of endogenous variables be $n$. The economy
|
||||
can be described by $m$ equations including the first order conditions
|
||||
and transition equations:
|
||||
\begin{equation}\label{constr}
|
||||
E_t^I\left[f(y_{t-1},y_t,y_{t+1},u_t)\right] = 0.
|
||||
\end{equation}
|
||||
This lefts $n-m$
|
||||
the planner's control variables. The solution of this problem is a
|
||||
decision rule of the form:
|
||||
\begin{equation}\label{agent_dr}
|
||||
y_t=g(y_{t-1},u_t,c_{t|t},c_{t+1|t},\ldots,c_{t+k|t},\ldots),
|
||||
\end{equation}
|
||||
where $c$ is a vector of planner's control variables.
|
||||
|
||||
Each period the social planner chooses the vector $c_t$ to maximize
|
||||
his objective such that \eqref{agent_dr} holds for all times following
|
||||
$t$. This would lead to $n-m$ first order conditions with respect to
|
||||
$c_t$. These first order conditions would contain unknown derivatives
|
||||
of endogenous variables with respect to $c$, which would have to be
|
||||
retrieved from the implicit constraints \eqref{constr} since the
|
||||
explicit form \eqref{agent_dr} is not known.
|
||||
|
||||
The other way to proceed is to assume that the planner is so dumb that
|
||||
he is not sure what are his control variables. So he optimizes with
|
||||
respect to all $y_t$ given the constraints \eqref{constr}. If the
|
||||
planner's objective is $b(y_{t-1},y_t,y_{t+1},u_t)$ with a discount rate
|
||||
$\beta$, then the optimization problem looks as follows:
|
||||
\begin{align}
|
||||
\max_{\left\{y_\tau\right\}^\infty_t}&E_t^J
|
||||
\left[\sum_{\tau=t}^\infty\beta^{\tau-t}b(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right]\notag\\
|
||||
&\rm{s.t.}\label{planner_optim}\\
|
||||
&\hskip1cm E^I_\tau\left[f(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right]=0\quad\rm{for\ }
|
||||
\tau=\ldots,t-1,t,t+1,\ldots\notag
|
||||
\end{align}
|
||||
Note two things: First, each constraint \eqref{constr} in
|
||||
\eqref{planner_optim} is conditioned on $I_\tau$ not $I_t$. This is
|
||||
very important, since the behaviour of agents at period $\tau=t+k$ is
|
||||
governed by the constraint using expectations conditioned on $t+k$,
|
||||
not $t$. The social planner knows that at $t+k$ the agents will use
|
||||
all information available at $t+k$. Second, the constraints for the
|
||||
planner's decision made at $t$ include also constraints for agent's
|
||||
behaviour prior to $t$. This is because the agent's decision rules are
|
||||
given in the implicit form \eqref{constr} and not in the explicit form
|
||||
\eqref{agent_dr}.
|
||||
|
||||
Using Lagrange multipliers, this can be rewritten as
|
||||
\begin{align}
|
||||
\max_{y_t}E_t^J&\left[\sum_{\tau=t}^\infty\beta^{\tau-t}b(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right.\notag\\
|
||||
&\left.+\sum_{\tau=-\infty}^{\infty}\beta^{\tau-t}\lambda^T_\tau E_\tau^I\left[f(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right]\right],
|
||||
\label{planner_optim_l}
|
||||
\end{align}
|
||||
where $\lambda_t$ is a vector of Lagrange multipliers corresponding to
|
||||
constraints \eqref{constr}. Note that the multipliers are multiplied
|
||||
by powers of $\beta$ in order to make them stationary. Taking a
|
||||
derivative wrt $y_t$ and putting it to zero yields the first order
|
||||
conditions of the planner's problem:
|
||||
\begin{align}
|
||||
E^J_t\left[\vphantom{\frac{\int^(_)}{\int^(\_)}}\right.&\frac{\partial}{\partial y_t}b(y_{t-1},y_t,y_{t+1},u_t)+
|
||||
\beta L^{+1}\frac{\partial}{\partial y_{t-1}}b(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\beta^{-1}\lambda_{t-1}^TE^I_{t-1}\left[L^{-1}\frac{\partial}{\partial y_{t+1}}f(y_{t-1},y_t,y_{t+1},u_t)\right]\notag\\
|
||||
&+\lambda_t^TE^I_t\left[\frac{\partial}{\partial y_{t}}f(y_{t-1},y_t,y_{t+1},u_t)\right]\notag\\
|
||||
&+\beta\lambda_{t+1}^TE^I_{t+1}\left[L^{+1}\frac{\partial}{\partial y_{t-1}}f(y_{t-1},y_t,y_{t+1},u_t)\right]
|
||||
\left.\vphantom{\frac{\int^(_)}{\int^(\_)}}\right]
|
||||
= 0,\label{planner_optim_foc}
|
||||
\end{align}
|
||||
where $L^{+1}$ and $L^{-1}$ are one period lead and lag operators respectively.
|
||||
|
||||
Now we have to make a few assertions concerning expectations
|
||||
conditioned on the different information sets to simplify
|
||||
\eqref{planner_optim_foc}. Recall the formula for integration through
|
||||
information on which another expectation is conditioned, this is:
|
||||
$$E\left[E\left[u|v\right]\right] = E[u],$$
|
||||
where the outer expectation integrates through $v$. Since $J_t\subset
|
||||
I_t$, by easy application of the above formula we obtain
|
||||
\begin{eqnarray}
|
||||
E^J_t\left[E^I_t\left[X\right]\right] &=& E^J_t\left[X\right]\quad\rm{and}\notag\\
|
||||
E^J_t\left[E^I_{t-1}\left[X\right]\right] &=& E^J_t\left[X\right]\label{e_iden}\\
|
||||
E^J_t\left[E^I_{t+1}\left[X\right]\right] &=& E^J_{t+1}\left[X\right]\notag
|
||||
\end{eqnarray}
|
||||
Now, the last term of \eqref{planner_optim_foc} needs a special
|
||||
attention. It is equal to
|
||||
$E^J_t\left[\beta\lambda^T_{t+1}E^I_{t+1}[X]\right]$. If we assume
|
||||
that the problem \eqref{planner_optim} has a solution, then there is a
|
||||
deterministic function from $J_{t+1}$ to $\lambda_{t+1}$ and so
|
||||
$\lambda_{t+1}\in J_{t+1}\subset I_{t+1}$. And the last term is equal
|
||||
to $E^J_{t}\left[E^I_{t+1}[\beta\lambda^T_{t+1}X]\right]$, which is
|
||||
$E^J_{t+1}\left[\beta\lambda^T_{t+1}X\right]$. This term can be
|
||||
equivalently written as
|
||||
$E^J_{t}\left[\beta\lambda^T_{t+1}E^J_{t+1}[X]\right]$. The reason why
|
||||
we write the term in this way will be clear later. All in all, we have
|
||||
\begin{align}
|
||||
E^J_t\left[\vphantom{\frac{\int^(_)}{\int^(\_)}}\right.&\frac{\partial}{\partial y_t}b(y_{t-1},y_t,y_{t+1},u_t)+
|
||||
\beta L^{+1}\frac{\partial}{\partial y_{t-1}}b(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\beta^{-1}\lambda_{t-1}^TL^{-1}\frac{\partial}{\partial y_{t+1}}f(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\lambda_t^T\frac{\partial}{\partial y_{t}}f(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\beta\lambda_{t+1}^TE^J_{t+1}\left[L^{+1}\frac{\partial}{\partial y_{t-1}}f(y_{t-1},y_t,y_{t+1},u_t)\right]
|
||||
\left.\vphantom{\frac{\int^(_)}{\int^(\_)}}\right]
|
||||
= 0.\label{planner_optim_foc2}
|
||||
\end{align}
|
||||
Note that we have not proved that \eqref{planner_optim_foc} and
|
||||
\eqref{planner_optim_foc2} are equivalent. We proved only that if
|
||||
\eqref{planner_optim_foc} has a solution, then
|
||||
\eqref{planner_optim_foc2} is equivalent (and has the same solution).
|
||||
|
||||
%%- \section{Implementation}
|
||||
%%-
|
||||
%%- The user inputs $b(y_{t-1},y_t,y_{t+1},u_t)$, $\beta$, and agent's
|
||||
%%- first order conditions \eqref{constr}. The algorithm has to produce
|
||||
%%- \eqref{planner_optim_foc2}.
|
||||
%%-
|
||||
\end{document}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,176 @@
|
|||
%
|
||||
% SYNOPSIS
|
||||
%
|
||||
% r = dynare_simul(name, shocks)
|
||||
% r = dynare_simul(name, prefix, shocks)
|
||||
% r = dynare_simul(name, shocks, start)
|
||||
% r = dynare_simul(name, prefix, shocks, start)
|
||||
%
|
||||
% name name of MAT-file produced by dynare++
|
||||
% prefix prefix of variables in the MAT-file
|
||||
% shocks matrix of shocks
|
||||
% start zero period value
|
||||
%
|
||||
% Note that this file requires the dynare_simul_ DLL to be in the path.
|
||||
% This DLL is distributed with Dynare, under the mex/matlab or mex/octave
|
||||
% subdirectory.
|
||||
%
|
||||
% SEMANTICS
|
||||
%
|
||||
% The command reads a decision rule from the MAT-file having the given
|
||||
% prefix. Then it starts simulating the decision rule with zero time value
|
||||
% equal to the given start. It uses the given shocks for the simulation. If
|
||||
% the start is not given, the state about which the decision rule is
|
||||
% centralized is taken (called fix point, or stochastic steady state, take
|
||||
% your pick).
|
||||
%
|
||||
% prefix Use the prefix with which you called dynare++, the default
|
||||
% prefix in dynare++ is 'dyn'.
|
||||
% shocks Number of rows must be a number of exogenous shocks,
|
||||
% number of columns gives the number of simulated
|
||||
% periods. NaNs and Infs in the matrix are substitued by
|
||||
% draws from the normal distribution using the covariance
|
||||
% matrix given in the model file.
|
||||
% start Vector of endogenous variables in the ordering given by
|
||||
% <prefix>_vars.
|
||||
%
|
||||
% Seed for random generator is derived from calling rand(1,1). Therefore,
|
||||
% seeding can be controlled with rand('state') and rand('state',some_seed).
|
||||
%
|
||||
% EXAMPLES
|
||||
%
|
||||
% All examples suppose that the prefix is 'dyn' and that your_model.mat
|
||||
% has been loaded into Matlab.
|
||||
%
|
||||
% 1. response to permanent negative shock to the third exo var EPS3 for
|
||||
% 100 periods
|
||||
%
|
||||
% shocks = zeros(4,100); % 4 exogenous variables in the model
|
||||
% shocks(dyn_i_EPS3,:) = -0.1; % the permanent shock to EPS3
|
||||
% r = dynare_simul('your_model.mat',shocks);
|
||||
%
|
||||
% 2. one stochastic simulation for 100 periods
|
||||
%
|
||||
% shocks = zeros(4,100)./0; % put NaNs everywhere
|
||||
% r = dynare_simul('your_model.mat',shocks);
|
||||
%
|
||||
% 3. one stochastic simulation starting at 75% undercapitalized economy
|
||||
%
|
||||
% shocks = zeros(4,100)./0; % put NaNs everywhere
|
||||
% ystart = dyn_ss; % get copy of DR fix point
|
||||
% ystart(dyn_i_K) = 0.75*dyn_ss(dyn_i_K); % scale down the capital
|
||||
% r = dynare_simul('your_model.mat',shocks,ystart);
|
||||
%
|
||||
%
|
||||
% SEE ALSO
|
||||
%
|
||||
% "DSGE Models with Dynare++. A Tutorial.", Ondra Kamenik, 2005
|
||||
|
||||
% Copyright © 2005-2011, Ondra Kamenik
|
||||
% Copyright © 2020, Dynare Team
|
||||
|
||||
|
||||
function r = dynare_simul(varargin)
|
||||
|
||||
if ~exist('dynare_simul_','file')
|
||||
error('Can''t find dynare_simul_ DLL in the path. The simplest way to add it is to run Dynare once in this session.')
|
||||
end
|
||||
|
||||
% get the file name and load data
|
||||
fname = varargin{1};
|
||||
load(fname);
|
||||
|
||||
% set prefix, shocks, ystart
|
||||
if ischar(varargin{2})
|
||||
prefix = varargin{2};
|
||||
if length(varargin) == 3
|
||||
shocks = varargin{3};
|
||||
ystart = NaN;
|
||||
elseif length(varargin) == 4
|
||||
shocks = varargin{3};
|
||||
ystart = varargin{4};
|
||||
else
|
||||
error('Wrong number of parameters.');
|
||||
end
|
||||
else
|
||||
prefix = 'dyn';
|
||||
if length(varargin) == 2
|
||||
shocks = varargin{2};
|
||||
ystart = NaN;
|
||||
elseif length(varargin) == 3
|
||||
shocks = varargin{2};
|
||||
ystart = varargin{3};
|
||||
else
|
||||
error('Wrong number of parameters.');
|
||||
end
|
||||
end
|
||||
|
||||
% load all needed variables but prefix_g_*
|
||||
if exist([prefix '_nstat'],'var')
|
||||
nstat = eval([prefix '_nstat']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_nstat in workspace']);
|
||||
end
|
||||
if exist([prefix '_npred'],'var')
|
||||
npred = eval([prefix '_npred']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_npred in workspace']);
|
||||
end
|
||||
if exist([prefix '_nboth'],'var')
|
||||
nboth = eval([prefix '_nboth']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_nboth in workspace']);
|
||||
end
|
||||
if exist([prefix '_nforw'],'var')
|
||||
nforw = eval([prefix '_nforw']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_nforw in workspace']);
|
||||
end
|
||||
if exist([prefix '_ss'],'var')
|
||||
ss = eval([prefix '_ss']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_ss in workspace']);
|
||||
end
|
||||
if exist([prefix '_vcov_exo'],'var')
|
||||
vcov_exo = eval([prefix '_vcov_exo']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_vcov_exo in workspace']);
|
||||
end
|
||||
nexog = size(vcov_exo,1);
|
||||
|
||||
if isnan(ystart)
|
||||
ystart = ss;
|
||||
end
|
||||
|
||||
% newer version of dynare++ doesn't return prefix_g_0, we make it here if
|
||||
% it does not exist in workspace
|
||||
g_zero = [prefix '_g_0'];
|
||||
if ~exist(g_zero,'var')
|
||||
dr.g_0=zeros(nstat+npred+nboth+nforw,1);
|
||||
else
|
||||
dr.g_0=eval(g_zero);
|
||||
end
|
||||
|
||||
% make derstr a string of comma seperated existing prefix_g_*
|
||||
order = 1;
|
||||
cont = 1;
|
||||
while cont == 1
|
||||
g_ord = [prefix '_g_' num2str(order)];
|
||||
if exist(g_ord,'var')
|
||||
dr.(['g_' num2str(order)])=eval(g_ord);
|
||||
order = order + 1;
|
||||
else
|
||||
cont = 0;
|
||||
end
|
||||
end
|
||||
|
||||
% set seed
|
||||
seed = ceil(10000*rand(1,1));
|
||||
|
||||
% call dynare_simul_
|
||||
[err,r]=dynare_simul_(order-1,nstat,npred,nboth,nforw,...
|
||||
nexog,ystart,shocks,vcov_exo,seed,ss,dr);
|
||||
|
||||
if err
|
||||
error('Simulation failed')
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
SUBDIRS = cc src testing
|
|
@ -0,0 +1,16 @@
|
|||
noinst_LIBRARIES = libinteg.a
|
||||
|
||||
libinteg_a_SOURCES = \
|
||||
quadrature.cc \
|
||||
quadrature.hh \
|
||||
quasi_mcarlo.cc \
|
||||
quasi_mcarlo.hh \
|
||||
product.cc \
|
||||
product.hh \
|
||||
smolyak.cc \
|
||||
smolyak.hh \
|
||||
vector_function.cc \
|
||||
vector_function.hh \
|
||||
precalc_quadrature.hh
|
||||
libinteg_a_CPPFLAGS = -I../../sylv/cc -I../../utils/cc -I../../tl/cc -I$(top_srcdir)/mex/sources
|
||||
libinteg_a_CXXFLAGS = $(AM_CXXFLAGS) $(THREAD_CXXFLAGS)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "product.hh"
|
||||
#include "symmetry.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
/* This constructs a product iterator corresponding to index (j0,0,…,0). */
|
||||
|
||||
prodpit::prodpit(const ProductQuadrature &q, int j0, int l)
|
||||
: prodq(q), level(l), npoints(q.uquad.numPoints(l)),
|
||||
jseq(q.dimen(), 0),
|
||||
end_flag(false),
|
||||
sig{q.dimen()},
|
||||
p{q.dimen()}
|
||||
{
|
||||
if (j0 < npoints)
|
||||
{
|
||||
jseq[0] = j0;
|
||||
setPointAndWeight();
|
||||
}
|
||||
else
|
||||
end_flag = true;
|
||||
}
|
||||
|
||||
bool
|
||||
prodpit::operator==(const prodpit &ppit) const
|
||||
{
|
||||
return &prodq == &ppit.prodq && end_flag == ppit.end_flag && jseq == ppit.jseq;
|
||||
}
|
||||
|
||||
prodpit &
|
||||
prodpit::operator++()
|
||||
{
|
||||
int i = prodq.dimen()-1;
|
||||
jseq[i]++;
|
||||
while (i >= 0 && jseq[i] == npoints)
|
||||
{
|
||||
jseq[i] = 0;
|
||||
i--;
|
||||
if (i >= 0)
|
||||
jseq[i]++;
|
||||
}
|
||||
sig.signalAfter(std::max(i, 0));
|
||||
|
||||
if (i == -1)
|
||||
end_flag = true;
|
||||
|
||||
if (!end_flag)
|
||||
setPointAndWeight();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* This calculates the weight and sets point coordinates from the indices. */
|
||||
|
||||
void
|
||||
prodpit::setPointAndWeight()
|
||||
{
|
||||
w = 1.0;
|
||||
for (int i = 0; i < prodq.dimen(); i++)
|
||||
{
|
||||
p[i] = (prodq.uquad).point(level, jseq[i]);
|
||||
w *= (prodq.uquad).weight(level, jseq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
|
||||
void
|
||||
prodpit::print() const
|
||||
{
|
||||
auto ff = std::cout.flags();
|
||||
std::cout << "j=[";
|
||||
for (int i = 0; i < prodq.dimen(); i++)
|
||||
std::cout << std::setw(2) << jseq[i];
|
||||
std::cout << std::showpos << std::fixed << std::setprecision(3)
|
||||
<< "] " << std::setw(4) << w << "*(";
|
||||
for (int i = 0; i < prodq.dimen()-1; i++)
|
||||
std::cout << std::setw(4) << p[i] << ' ';
|
||||
std::cout << std::setw(4) << p[prodq.dimen()-1] << ')' << std::endl;
|
||||
std::cout.flags(ff);
|
||||
}
|
||||
|
||||
ProductQuadrature::ProductQuadrature(int d, const OneDQuadrature &uq)
|
||||
: QuadratureImpl<prodpit>(d), uquad(uq)
|
||||
{
|
||||
// TODO: check d≥1
|
||||
}
|
||||
|
||||
/* This calls prodpit constructor to return an iterator which points
|
||||
approximatelly at ‘ti’-th portion out of ‘tn’ portions. First we find
|
||||
out how many points are in the level, and then construct an interator
|
||||
(j0,0,…,0) where j0=ti·npoints/tn. */
|
||||
|
||||
prodpit
|
||||
ProductQuadrature::begin(int ti, int tn, int l) const
|
||||
{
|
||||
// TODO: raise if l<dimen()
|
||||
// TODO: check l ≤ uquad.numLevels()
|
||||
int npoints = uquad.numPoints(l);
|
||||
return prodpit(*this, ti*npoints/tn, l);
|
||||
}
|
||||
|
||||
/* This just starts at the first level and goes to a higher level as long as a
|
||||
number of evaluations (which is nₖᵈ for k being the level) is less than the
|
||||
given number of evaluations. */
|
||||
|
||||
void
|
||||
ProductQuadrature::designLevelForEvals(int max_evals, int &lev, int &evals) const
|
||||
{
|
||||
int last_evals;
|
||||
evals = 1;
|
||||
lev = 1;
|
||||
do
|
||||
{
|
||||
lev++;
|
||||
last_evals = evals;
|
||||
evals = numEvals(lev);
|
||||
}
|
||||
while (lev < uquad.numLevels()-2 && evals < max_evals);
|
||||
lev--;
|
||||
evals = last_evals;
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Product quadrature.
|
||||
|
||||
/* This file defines a product multidimensional quadrature. If Qₖ$ denotes the
|
||||
one dimensional quadrature, then the product quadrature Q of k level and
|
||||
dimension d takes the form:
|
||||
|
||||
nₖ nₖ
|
||||
Qf = ∑ … ∑ w_i₁·…·w_{i_d} f(x_i₁,…,x_{i_d})
|
||||
i₁=1 i_d=1
|
||||
|
||||
which can be written in terms of the one dimensional quadrature Qₖ as
|
||||
|
||||
Qf=(Qₖ⊗…⊗Qₖ)f
|
||||
|
||||
Here we define the product quadrature iterator prodpit and plug it into
|
||||
QuadratureImpl to obtains ProductQuadrature. */
|
||||
|
||||
#ifndef PRODUCT_H
|
||||
#define PRODUCT_H
|
||||
|
||||
#include "int_sequence.hh"
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
|
||||
/* This defines a product point iterator. We have to maintain the following: a
|
||||
pointer to product quadrature in order to know the dimension and the
|
||||
underlying one dimensional quadrature, then level, number of points in the
|
||||
level, integer sequence of indices, signal, the coordinates of the point and
|
||||
the weight.
|
||||
|
||||
The point indices, signal, and point coordinates are implmented as pointers
|
||||
in order to allow for empty constructor.
|
||||
|
||||
The constructor prodpit(const ProductQuadrature& q, int j0, int l)
|
||||
constructs an iterator pointing to (j0,0,…,0), which is used by begin()
|
||||
dictated by QuadratureImpl. */
|
||||
|
||||
class ProductQuadrature;
|
||||
|
||||
class prodpit
|
||||
{
|
||||
protected:
|
||||
const ProductQuadrature &prodq;
|
||||
int level{0};
|
||||
int npoints{0};
|
||||
IntSequence jseq;
|
||||
bool end_flag{true};
|
||||
ParameterSignal sig;
|
||||
Vector p;
|
||||
double w;
|
||||
public:
|
||||
prodpit() = default;
|
||||
prodpit(const ProductQuadrature &q, int j0, int l);
|
||||
prodpit(const prodpit &ppit) = default;
|
||||
~prodpit() = default;
|
||||
bool operator==(const prodpit &ppit) const;
|
||||
bool
|
||||
operator!=(const prodpit &ppit) const
|
||||
{
|
||||
return !operator==(ppit);
|
||||
}
|
||||
prodpit &operator=(const prodpit &spit) = delete;
|
||||
prodpit &operator++();
|
||||
const ParameterSignal &
|
||||
signal() const
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
double
|
||||
weight() const
|
||||
{
|
||||
return w;
|
||||
}
|
||||
void print() const;
|
||||
protected:
|
||||
void setPointAndWeight();
|
||||
};
|
||||
|
||||
/* The product quadrature is just QuadratureImpl with the product iterator
|
||||
plugged in. The object is constructed by just giving the underlying one
|
||||
dimensional quadrature, and the dimension. The only extra method is
|
||||
designLevelForEvals() which for the given maximum number of evaluations (and
|
||||
dimension and underlying quadrature from the object) returns a maximum level
|
||||
yeilding number of evaluations less than the given number. */
|
||||
|
||||
class ProductQuadrature : public QuadratureImpl<prodpit>
|
||||
{
|
||||
friend class prodpit;
|
||||
const OneDQuadrature &uquad;
|
||||
public:
|
||||
ProductQuadrature(int d, const OneDQuadrature &uq);
|
||||
~ProductQuadrature() override = default;
|
||||
int
|
||||
numEvals(int l) const override
|
||||
{
|
||||
int res = 1;
|
||||
for (int i = 0; i < dimen(); i++)
|
||||
res *= uquad.numPoints(l);
|
||||
return res;
|
||||
}
|
||||
void designLevelForEvals(int max_eval, int &lev, int &evals) const;
|
||||
protected:
|
||||
prodpit begin(int ti, int tn, int level) const override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "quadrature.hh"
|
||||
#include "precalc_quadrature.hh"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
void
|
||||
OneDPrecalcQuadrature::calcOffsets()
|
||||
{
|
||||
offsets[0] = 0;
|
||||
for (int i = 1; i < num_levels; i++)
|
||||
offsets[i] = offsets[i-1] + num_points[i-1];
|
||||
}
|
||||
|
||||
GaussHermite::GaussHermite()
|
||||
: OneDPrecalcQuadrature(gh_num_levels, gh_num_points, gh_weights, gh_points)
|
||||
{
|
||||
}
|
||||
|
||||
GaussLegendre::GaussLegendre()
|
||||
: OneDPrecalcQuadrature(gl_num_levels, gl_num_points, gl_weights, gl_points)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Quadrature.
|
||||
|
||||
/* This file defines an interface for one dimensional (non-nested) quadrature
|
||||
OneDQuadrature, and a parent for all multi-dimensional quadratures. This
|
||||
parent class Quadrature presents a general concept of quadrature, this is
|
||||
|
||||
N
|
||||
∫ f(x)dx ≃ ∑ wᵢxᵢ
|
||||
ⁱ⁼¹
|
||||
|
||||
The class Quadrature just declares this concept. The concept is implemented
|
||||
by class QuadratureImpl which paralelizes the summation. All implementations
|
||||
therefore wishing to use the parallel implementation should inherit from
|
||||
QuadratureImpl and integration is done.
|
||||
|
||||
The integration concept relies on a point iterator, which goes through all
|
||||
xᵢ and wᵢ for i=1,…,N. All the iterators must be able to go through only a
|
||||
portion of the set i=1,…,N. This enables us to implement paralelism, for two
|
||||
threads for example, one iterator goes from the beginning to the
|
||||
(approximately) half, and the other goes from the half to the end.
|
||||
|
||||
Besides this concept of the general quadrature, this file defines also one
|
||||
dimensional quadrature, which is basically a scheme of points and weights
|
||||
for different levels. The class OneDQuadrature is a parent of all such
|
||||
objects, the classes GaussHermite and GaussLegendre are specific
|
||||
implementations for Gauss-Hermite and Gauss-Legendre quadratures resp. */
|
||||
|
||||
#ifndef QUADRATURE_H
|
||||
#define QUADRATURE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "vector_function.hh"
|
||||
#include "int_sequence.hh"
|
||||
#include "sthread.hh"
|
||||
|
||||
/* This pure virtual class represents a concept of one-dimensional (non-nested)
|
||||
quadrature. So, one dimensional quadrature must return number of levels,
|
||||
number of points in a given level, and then a point and a weight in a given
|
||||
level and given order. */
|
||||
|
||||
class OneDQuadrature
|
||||
{
|
||||
public:
|
||||
virtual ~OneDQuadrature() = default;
|
||||
virtual int numLevels() const = 0;
|
||||
virtual int numPoints(int level) const = 0;
|
||||
virtual double point(int level, int i) const = 0;
|
||||
virtual double weight(int lelel, int i) const = 0;
|
||||
};
|
||||
|
||||
/* This is a general concept of multidimensional quadrature. at this general
|
||||
level, we maintain only a dimension, and declare virtual functions for
|
||||
integration. The function take two forms; first takes a constant
|
||||
VectorFunction as an argument, creates locally VectorFunctionSet and do
|
||||
calculation, second one takes as an argument VectorFunctionSet.
|
||||
|
||||
Part of the interface is a method returning a number of evaluations for a
|
||||
specific level. Note two things: this assumes that the number of evaluations
|
||||
is known apriori and thus it is not applicable for adaptive quadratures,
|
||||
second for Monte Carlo type of quadrature, the level is a number of
|
||||
evaluations. */
|
||||
|
||||
class Quadrature
|
||||
{
|
||||
protected:
|
||||
int dim;
|
||||
public:
|
||||
Quadrature(int d) : dim(d)
|
||||
{
|
||||
}
|
||||
virtual ~Quadrature() = default;
|
||||
int
|
||||
dimen() const
|
||||
{
|
||||
return dim;
|
||||
}
|
||||
virtual void integrate(const VectorFunction &func, int level,
|
||||
int tn, Vector &out) const = 0;
|
||||
virtual void integrate(VectorFunctionSet &fs, int level, Vector &out) const = 0;
|
||||
virtual int numEvals(int level) const = 0;
|
||||
};
|
||||
|
||||
/* This is just an integration worker, which works over a given QuadratureImpl.
|
||||
It also needs the function, level, a specification of the subgroup of
|
||||
points, and output vector.
|
||||
|
||||
See QuadratureImpl class declaration for details. */
|
||||
|
||||
template<typename _Tpit>
|
||||
class QuadratureImpl;
|
||||
|
||||
template<typename _Tpit>
|
||||
class IntegrationWorker : public sthread::detach_thread
|
||||
{
|
||||
const QuadratureImpl<_Tpit> &quad;
|
||||
VectorFunction &func;
|
||||
int level;
|
||||
int ti;
|
||||
int tn;
|
||||
Vector &outvec;
|
||||
public:
|
||||
IntegrationWorker(const QuadratureImpl<_Tpit> &q, VectorFunction &f, int l,
|
||||
int tii, int tnn, Vector &out)
|
||||
: quad(q), func(f), level(l), ti(tii), tn(tnn), outvec(out)
|
||||
{
|
||||
}
|
||||
|
||||
/* This integrates the given portion of the integral. We obtain first and
|
||||
last iterators for the portion (‘beg’ and ‘end’). Then we iterate through
|
||||
the portion. and finally we add the intermediate result to the result
|
||||
‘outvec’.
|
||||
|
||||
This method just everything up as it is coming. This might be imply large
|
||||
numerical errors, perhaps in future something smarter should be implemented. */
|
||||
|
||||
void
|
||||
operator()(std::mutex &mut) override
|
||||
{
|
||||
_Tpit beg = quad.begin(ti, tn, level);
|
||||
_Tpit end = quad.begin(ti+1, tn, level);
|
||||
Vector tmpall(outvec.length());
|
||||
tmpall.zeros();
|
||||
Vector tmp(outvec.length());
|
||||
|
||||
/* Note that since ‘beg’ came from begin(), it has empty signal and first
|
||||
evaluation gets no signal */
|
||||
for (_Tpit run = beg; run != end; ++run)
|
||||
{
|
||||
func.eval(run.point(), run.signal(), tmp);
|
||||
tmpall.add(run.weight(), tmp);
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
outvec.add(1.0, tmpall);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* This is the class which implements the integration. The class is templated
|
||||
by the iterator type. We declare a method begin() returning an iterator to
|
||||
the beginnning of the ‘ti’-th portion out of total ‘tn’ portions for a given
|
||||
level.
|
||||
|
||||
In addition, we define a method which saves all the points to a given file.
|
||||
Only for debugging purposes. */
|
||||
|
||||
template<typename _Tpit>
|
||||
class QuadratureImpl : public Quadrature
|
||||
{
|
||||
friend class IntegrationWorker<_Tpit>;
|
||||
public:
|
||||
QuadratureImpl(int d) : Quadrature(d)
|
||||
{
|
||||
}
|
||||
|
||||
/* Just fill a thread group with workes and run it. */
|
||||
void
|
||||
integrate(VectorFunctionSet &fs, int level, Vector &out) const override
|
||||
{
|
||||
// TODO: out.length()==func.outdim()
|
||||
// TODO: dim == func.indim()
|
||||
out.zeros();
|
||||
sthread::detach_thread_group gr;
|
||||
for (int ti = 0; ti < fs.getNum(); ti++)
|
||||
gr.insert(std::make_unique<IntegrationWorker<_Tpit>>(*this, fs.getFunc(ti),
|
||||
level, ti, fs.getNum(), out));
|
||||
gr.run();
|
||||
}
|
||||
void
|
||||
integrate(const VectorFunction &func,
|
||||
int level, int tn, Vector &out) const override
|
||||
{
|
||||
VectorFunctionSet fs(func, tn);
|
||||
integrate(fs, level, out);
|
||||
}
|
||||
|
||||
/* Just for debugging. */
|
||||
void
|
||||
savePoints(const std::string &fname, int level) const
|
||||
{
|
||||
std::ofstream fd{fname, std::ios::out | std::ios::trunc};
|
||||
if (fd.fail())
|
||||
{
|
||||
// TODO: raise
|
||||
std::cerr << "Cannot open file " << fname << " for writing." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
_Tpit beg = begin(0, 1, level);
|
||||
_Tpit end = begin(1, 1, level);
|
||||
fd << std::setprecision(12);
|
||||
for (_Tpit run = beg; run != end; ++run)
|
||||
{
|
||||
fd << std::setw(16) << run.weight();
|
||||
for (int i = 0; i < dimen(); i++)
|
||||
fd << '\t' << std::setw(16) << run.point()[i];
|
||||
fd << std::endl;
|
||||
}
|
||||
fd.close();
|
||||
}
|
||||
|
||||
_Tpit
|
||||
start(int level) const
|
||||
{
|
||||
return begin(0, 1, level);
|
||||
}
|
||||
_Tpit
|
||||
end(int level) const
|
||||
{
|
||||
return begin(1, 1, level);
|
||||
}
|
||||
protected:
|
||||
virtual _Tpit begin(int ti, int tn, int level) const = 0;
|
||||
};
|
||||
|
||||
/* This is only an interface to a precalculated data in file
|
||||
precalc_quadrature.hh which is basically C coded static data. It implements
|
||||
OneDQuadrature. The data file is supposed to define the following data:
|
||||
number of levels, array of number of points at each level, an array of
|
||||
weights and array of points. The both latter array store data level by
|
||||
level. An offset for a specific level is stored in ‘offsets’ integer
|
||||
sequence.
|
||||
|
||||
The implementing subclasses just fill the necessary data from the file, the
|
||||
rest is calculated here. */
|
||||
|
||||
class OneDPrecalcQuadrature : public OneDQuadrature
|
||||
{
|
||||
int num_levels;
|
||||
const int *num_points;
|
||||
const double *weights;
|
||||
const double *points;
|
||||
IntSequence offsets;
|
||||
public:
|
||||
OneDPrecalcQuadrature(int nlevels, const int *npoints,
|
||||
const double *wts, const double *pts)
|
||||
: num_levels(nlevels), num_points(npoints),
|
||||
weights(wts), points(pts), offsets(num_levels)
|
||||
{
|
||||
calcOffsets();
|
||||
}
|
||||
~OneDPrecalcQuadrature() override = default;
|
||||
int
|
||||
numLevels() const override
|
||||
{
|
||||
return num_levels;
|
||||
}
|
||||
int
|
||||
numPoints(int level) const override
|
||||
{
|
||||
return num_points[level-1];
|
||||
}
|
||||
double
|
||||
point(int level, int i) const override
|
||||
{
|
||||
return points[offsets[level-1]+i];
|
||||
}
|
||||
double
|
||||
weight(int level, int i) const override
|
||||
{
|
||||
return weights[offsets[level-1]+i];
|
||||
}
|
||||
protected:
|
||||
void calcOffsets();
|
||||
};
|
||||
|
||||
/* Just precalculated Gauss-Hermite quadrature. This quadrature integrates
|
||||
exactly integrals
|
||||
|
||||
+∞
|
||||
∫ xᵏe^{−x²}dx
|
||||
−∞
|
||||
|
||||
for level k.
|
||||
|
||||
Note that if pluging this one-dimensional quadrature to product or Smolyak
|
||||
rule in order to integrate a function f through normally distributed inputs,
|
||||
one has to wrap f to GaussConverterFunction and apply the product or Smolyak
|
||||
rule to the new function.
|
||||
|
||||
Check precalc_quadrature.hh for available levels. */
|
||||
|
||||
class GaussHermite : public OneDPrecalcQuadrature
|
||||
{
|
||||
public:
|
||||
GaussHermite();
|
||||
};
|
||||
|
||||
/* Just precalculated Gauss-Legendre quadrature. This quadrature integrates
|
||||
exactly integrals
|
||||
|
||||
₁
|
||||
∫ xᵏdx
|
||||
⁰
|
||||
|
||||
for level k.
|
||||
|
||||
Check precalc_quadrature.hh for available levels. */
|
||||
|
||||
class GaussLegendre : public OneDPrecalcQuadrature
|
||||
{
|
||||
public:
|
||||
GaussLegendre();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "quasi_mcarlo.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <array>
|
||||
|
||||
/* Here in the constructor, we have to calculate a maximum length of ‘coeff’
|
||||
array for a given ‘base’ and given maximum ‘maxn’. After allocation, we
|
||||
calculate the coefficients. */
|
||||
|
||||
RadicalInverse::RadicalInverse(int n, int b, int mxn)
|
||||
: num(n), base(b), maxn(mxn),
|
||||
coeff(static_cast<int>(floor(log(static_cast<double>(maxn))/log(static_cast<double>(b)))+2), 0)
|
||||
{
|
||||
int nr = num;
|
||||
j = -1;
|
||||
do
|
||||
{
|
||||
j++;
|
||||
coeff[j] = nr % base;
|
||||
nr = nr / base;
|
||||
}
|
||||
while (nr > 0);
|
||||
}
|
||||
|
||||
/* This evaluates the radical inverse. If there was no permutation, we have to
|
||||
calculate:
|
||||
|
||||
c₀ c₁ cⱼ
|
||||
── + ── + … + ────
|
||||
b b² bʲ⁺¹
|
||||
|
||||
which is evaluated as:
|
||||
|
||||
⎛ ⎛⎛cⱼ 1 cⱼ₋₁⎞ 1 cⱼ₋₂⎞ ⎞ 1 c₀
|
||||
⎢…⎢⎢──·─ + ────⎥·─ + ────⎥…⎥·─ + ──
|
||||
⎝ ⎝⎝ b b b ⎠ b b ⎠ ⎠ b b
|
||||
|
||||
|
||||
Now with permutation π, we have:
|
||||
|
||||
⎛ ⎛⎛π(cⱼ) 1 π(cⱼ₋₁)⎞ 1 π(cⱼ₋₂)⎞ ⎞ 1 π(c₀)
|
||||
⎢…⎢⎢─────·─ + ───────⎥·─ + ───────⎥…⎥·─ + ─────
|
||||
⎝ ⎝⎝ b b b ⎠ b b ⎠ ⎠ b b
|
||||
*/
|
||||
|
||||
double
|
||||
RadicalInverse::eval(const PermutationScheme &p) const
|
||||
{
|
||||
double res = 0;
|
||||
for (int i = j; i >= 0; i--)
|
||||
{
|
||||
int cper = p.permute(i, base, coeff[i]);
|
||||
res = (cper + res)/base;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* We just add 1 to the lowest coefficient and check for overflow with respect
|
||||
to the base. */
|
||||
void
|
||||
RadicalInverse::increase()
|
||||
{
|
||||
// TODO: raise if num+1 > maxn
|
||||
num++;
|
||||
int i = 0;
|
||||
coeff[i]++;
|
||||
while (coeff[i] == base)
|
||||
{
|
||||
coeff[i] = 0;
|
||||
coeff[++i]++;
|
||||
}
|
||||
if (i > j)
|
||||
j = i;
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
void
|
||||
RadicalInverse::print() const
|
||||
{
|
||||
std::cout << "n=" << num << " b=" << base << " c=";
|
||||
coeff.print();
|
||||
}
|
||||
|
||||
/* Here we have the first 170 primes. This means that we are not able to
|
||||
integrate dimensions greater than 170. */
|
||||
|
||||
std::array<int, 170> HaltonSequence::primes =
|
||||
{
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
|
||||
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
|
||||
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
|
||||
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
|
||||
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
|
||||
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
|
||||
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
|
||||
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
|
||||
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
|
||||
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
|
||||
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
|
||||
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
|
||||
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
|
||||
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
|
||||
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
|
||||
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
|
||||
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013
|
||||
};
|
||||
|
||||
/* This takes first ‘dim’ primes and constructs ‘dim’ radical inverses and
|
||||
calls eval(). */
|
||||
|
||||
HaltonSequence::HaltonSequence(int n, int mxn, int dim, const PermutationScheme &p)
|
||||
: num(n), maxn(mxn), per(p), pt(dim)
|
||||
{
|
||||
// TODO: raise if dim > num_primes
|
||||
// TODO: raise if n > mxn
|
||||
for (int i = 0; i < dim; i++)
|
||||
ri.emplace_back(num, primes[i], maxn);
|
||||
eval();
|
||||
}
|
||||
|
||||
/* This calls RadicalInverse::increase() for all radical inverses and calls
|
||||
eval(). */
|
||||
|
||||
void
|
||||
HaltonSequence::increase()
|
||||
{
|
||||
for (auto &i : ri)
|
||||
i.increase();
|
||||
num++;
|
||||
if (num <= maxn)
|
||||
eval();
|
||||
}
|
||||
|
||||
/* This sets point ‘pt’ to radical inverse evaluations in each dimension. */
|
||||
void
|
||||
HaltonSequence::eval()
|
||||
{
|
||||
for (unsigned int i = 0; i < ri.size(); i++)
|
||||
pt[i] = ri[i].eval(per);
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
void
|
||||
HaltonSequence::print() const
|
||||
{
|
||||
auto ff = std::cout.flags();
|
||||
for (const auto &i : ri)
|
||||
i.print();
|
||||
std::cout << "point=[ "
|
||||
<< std::fixed << std::setprecision(6);
|
||||
for (unsigned int i = 0; i < ri.size(); i++)
|
||||
std::cout << std::setw(7) << pt[i] << ' ';
|
||||
std::cout << ']' << std::endl;
|
||||
std::cout.flags(ff);
|
||||
}
|
||||
|
||||
qmcpit::qmcpit(const QMCSpecification &s, int n)
|
||||
: spec(s), halton{n, s.level(), s.dimen(), s.getPerScheme()},
|
||||
sig{s.dimen()}
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
qmcpit::operator==(const qmcpit &qpit) const
|
||||
{
|
||||
return &spec == &qpit.spec && halton.getNum() == qpit.halton.getNum();
|
||||
}
|
||||
|
||||
qmcpit &
|
||||
qmcpit::operator++()
|
||||
{
|
||||
halton.increase();
|
||||
return *this;
|
||||
}
|
||||
|
||||
double
|
||||
qmcpit::weight() const
|
||||
{
|
||||
return 1.0/spec.level();
|
||||
}
|
||||
|
||||
int
|
||||
WarnockPerScheme::permute(int i, int base, int c) const
|
||||
{
|
||||
return (c+i) % base;
|
||||
}
|
||||
|
||||
int
|
||||
ReversePerScheme::permute(int i, int base, int c) const
|
||||
{
|
||||
return (base-c) % base;
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2022 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/>.
|
||||
*/
|
||||
|
||||
// Quasi Monte Carlo quadrature.
|
||||
|
||||
/* This defines quasi Monte Carlo quadratures for cube and for a function
|
||||
multiplied by normal density. The quadrature for a cube is named
|
||||
QMCarloCubeQuadrature and integrates:
|
||||
|
||||
∫ f(x)dx
|
||||
[0,1]ⁿ
|
||||
|
||||
The quadrature for a function of normally distributed parameters is named
|
||||
QMCarloNormalQuadrature and integrates:
|
||||
|
||||
1
|
||||
──────── ∫ f(x)e^{−½xᵀx}dx
|
||||
√{(2π)ⁿ} [−∞,+∞]ⁿ
|
||||
|
||||
For a cube we define qmcpit as iterator of QMCarloCubeQuadrature, and for
|
||||
the normal density multiplied function we define qmcnpit as iterator of
|
||||
QMCarloNormalQuadrature.
|
||||
|
||||
The quasi Monte Carlo method generates low discrepancy points with equal
|
||||
weights. The one dimensional low discrepancy sequences are generated by
|
||||
RadicalInverse class, the sequences are combined for higher dimensions by
|
||||
HaltonSequence class. The Halton sequence can use a permutation scheme;
|
||||
PermutattionScheme is an abstract class for all permutaton schemes. We have
|
||||
three implementations: WarnockPerScheme, ReversePerScheme, and
|
||||
IdentityPerScheme. */
|
||||
|
||||
#ifndef QUASI_MCARLO_H
|
||||
#define QUASI_MCARLO_H
|
||||
|
||||
#include "int_sequence.hh"
|
||||
#include "quadrature.hh"
|
||||
|
||||
#include "Vector.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
/* This abstract class declares permute() method which permutes coefficient ‘c’
|
||||
having index of ‘i’ fro the base ‘base’ and returns the permuted coefficient
|
||||
which must be in 0,…,base−1. */
|
||||
|
||||
class PermutationScheme
|
||||
{
|
||||
public:
|
||||
PermutationScheme() = default;
|
||||
virtual ~PermutationScheme() = default;
|
||||
virtual int permute(int i, int base, int c) const = 0;
|
||||
};
|
||||
|
||||
/* This class represents an integer number ‘num’ as c₀+c₁b+c₂b²+…+cⱼbʲ, where b
|
||||
is ‘base’ and c₀,…,cⱼ is stored in ‘coeff’. The size of IntSequence coeff
|
||||
does not grow with growing ‘num’, but is fixed from the very beginning and
|
||||
is set according to supplied maximum ‘maxn’.
|
||||
|
||||
The basic method is eval() which evaluates the RadicalInverse with a given
|
||||
permutation scheme and returns the point, and increase() which increases
|
||||
‘num’ and recalculates the coefficients. */
|
||||
|
||||
class RadicalInverse
|
||||
{
|
||||
int num;
|
||||
int base;
|
||||
int maxn;
|
||||
int j;
|
||||
IntSequence coeff;
|
||||
public:
|
||||
RadicalInverse(int n, int b, int mxn);
|
||||
RadicalInverse(const RadicalInverse &ri) = default;
|
||||
RadicalInverse &operator=(const RadicalInverse &radi) = default;
|
||||
double eval(const PermutationScheme &p) const;
|
||||
void increase();
|
||||
void print() const;
|
||||
};
|
||||
|
||||
/* This is a vector of RadicalInverses, each RadicalInverse has a different
|
||||
prime as its base. The static members ‘primes’ and ‘num_primes’ define a
|
||||
precalculated array of primes. The increase() method of the class increases
|
||||
indices in all RadicalInverse’s and sets point ‘pt’ to contain the points in
|
||||
each dimension. */
|
||||
|
||||
class HaltonSequence
|
||||
{
|
||||
private:
|
||||
static std::array<int, 170> primes;
|
||||
protected:
|
||||
int num;
|
||||
int maxn;
|
||||
std::vector<RadicalInverse> ri;
|
||||
const PermutationScheme &per;
|
||||
Vector pt;
|
||||
public:
|
||||
HaltonSequence(int n, int mxn, int dim, const PermutationScheme &p);
|
||||
HaltonSequence(const HaltonSequence &hs) = default;
|
||||
HaltonSequence &operator=(const HaltonSequence &hs) = delete;
|
||||
void increase();
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return pt;
|
||||
}
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return num;
|
||||
}
|
||||
void print() const;
|
||||
protected:
|
||||
void eval();
|
||||
};
|
||||
|
||||
/* This is a specification of quasi Monte Carlo quadrature. It consists of
|
||||
dimension ‘dim’, number of points (or level) ‘lev’, and the permutation
|
||||
scheme. This class is common to all quasi Monte Carlo classes. */
|
||||
|
||||
class QMCSpecification
|
||||
{
|
||||
protected:
|
||||
int dim;
|
||||
int lev;
|
||||
const PermutationScheme &per_scheme;
|
||||
public:
|
||||
QMCSpecification(int d, int l, const PermutationScheme &p)
|
||||
: dim(d), lev(l), per_scheme(p)
|
||||
{
|
||||
}
|
||||
virtual ~QMCSpecification() = default;
|
||||
int
|
||||
dimen() const
|
||||
{
|
||||
return dim;
|
||||
}
|
||||
int
|
||||
level() const
|
||||
{
|
||||
return lev;
|
||||
}
|
||||
const PermutationScheme &
|
||||
getPerScheme() const
|
||||
{
|
||||
return per_scheme;
|
||||
}
|
||||
};
|
||||
|
||||
/* This is an iterator for quasi Monte Carlo over a cube QMCarloCubeQuadrature.
|
||||
The iterator maintains HaltonSequence of the same dimension as given by the
|
||||
specification. An iterator can be constructed from a given number ‘n’, or by
|
||||
a copy constructor. */
|
||||
|
||||
class qmcpit
|
||||
{
|
||||
protected:
|
||||
const QMCSpecification &spec;
|
||||
HaltonSequence halton;
|
||||
ParameterSignal sig;
|
||||
public:
|
||||
qmcpit(const QMCSpecification &s, int n);
|
||||
qmcpit(const qmcpit &qpit) = default;
|
||||
virtual ~qmcpit() = default;
|
||||
bool operator==(const qmcpit &qpit) const;
|
||||
bool
|
||||
operator!=(const qmcpit &qpit) const
|
||||
{
|
||||
return !operator==(qpit);
|
||||
}
|
||||
qmcpit &operator=(const qmcpit &qpit) = delete;
|
||||
qmcpit &operator++();
|
||||
const ParameterSignal &
|
||||
signal() const
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return halton.point();
|
||||
}
|
||||
double weight() const;
|
||||
void
|
||||
print() const
|
||||
{
|
||||
halton.print();
|
||||
}
|
||||
};
|
||||
|
||||
/* This is an easy declaration of quasi Monte Carlo quadrature for a cube.
|
||||
Everything important has been done in its iterator qmcpit, so we only
|
||||
inherit from general Quadrature and reimplement begin() and numEvals(). */
|
||||
|
||||
class QMCarloCubeQuadrature : public QuadratureImpl<qmcpit>, public QMCSpecification
|
||||
{
|
||||
public:
|
||||
QMCarloCubeQuadrature(int d, int l, const PermutationScheme &p)
|
||||
: QuadratureImpl<qmcpit>(d), QMCSpecification(d, l, p)
|
||||
{
|
||||
}
|
||||
~QMCarloCubeQuadrature() override = default;
|
||||
int
|
||||
numEvals(int l) const override
|
||||
{
|
||||
return l;
|
||||
}
|
||||
protected:
|
||||
qmcpit
|
||||
begin(int ti, int tn, int lev) const override
|
||||
{
|
||||
return qmcpit(*this, ti*level()/tn + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/* Declares Warnock permutation scheme. */
|
||||
class WarnockPerScheme : public PermutationScheme
|
||||
{
|
||||
public:
|
||||
int permute(int i, int base, int c) const override;
|
||||
};
|
||||
|
||||
/* Declares reverse permutation scheme. */
|
||||
class ReversePerScheme : public PermutationScheme
|
||||
{
|
||||
public:
|
||||
int permute(int i, int base, int c) const override;
|
||||
};
|
||||
|
||||
/* Declares no permutation (identity) scheme. */
|
||||
class IdentityPerScheme : public PermutationScheme
|
||||
{
|
||||
public:
|
||||
int
|
||||
permute(int i, int base, int c) const override
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "smolyak.hh"
|
||||
#include "symmetry.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
/* This constructs a beginning of ‘isum’ summand in ‘smolq’. We must be careful
|
||||
here, since ‘isum’ can be past-the-end, so no reference to vectors in
|
||||
‘smolq’ by ‘isum’ must be done in this case. */
|
||||
|
||||
smolpit::smolpit(const SmolyakQuadrature &q, unsigned int isum)
|
||||
: smolq(q), isummand(isum),
|
||||
jseq(q.dimen(), 0),
|
||||
sig{q.dimen()},
|
||||
p{q.dimen()}
|
||||
{
|
||||
if (isummand < q.numSummands())
|
||||
setPointAndWeight();
|
||||
}
|
||||
|
||||
bool
|
||||
smolpit::operator==(const smolpit &spit) const
|
||||
{
|
||||
return &smolq == &spit.smolq && isummand == spit.isummand && jseq == spit.jseq;
|
||||
}
|
||||
|
||||
/* We first try to increase index within the current summand. If we are at
|
||||
maximum, we go to a subsequent summand. Note that in this case all indices
|
||||
in ‘jseq’ will be zero, so no change is needed. */
|
||||
|
||||
smolpit &
|
||||
smolpit::operator++()
|
||||
{
|
||||
const IntSequence &levpts = smolq.levpoints[isummand];
|
||||
int i = smolq.dimen()-1;
|
||||
jseq[i]++;
|
||||
while (i >= 0 && jseq[i] == levpts[i])
|
||||
{
|
||||
jseq[i] = 0;
|
||||
i--;
|
||||
if (i >= 0)
|
||||
jseq[i]++;
|
||||
}
|
||||
sig.signalAfter(std::max(i, 0));
|
||||
|
||||
if (i < 0)
|
||||
isummand++;
|
||||
|
||||
if (isummand < smolq.numSummands())
|
||||
setPointAndWeight();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Here we set the point coordinates according to ‘jseq’ and
|
||||
‘isummand’. Also the weight is set here. */
|
||||
|
||||
void
|
||||
smolpit::setPointAndWeight()
|
||||
{
|
||||
// todo: raise if isummand ≥ smolq.numSummands()
|
||||
int l = smolq.level;
|
||||
int d = smolq.dimen();
|
||||
int sumk = (smolq.levels[isummand]).sum();
|
||||
int m1exp = l + d - sumk - 1;
|
||||
w = (2*(m1exp/2) == m1exp) ? 1.0 : -1.0;
|
||||
w *= PascalTriangle::noverk(d-1, sumk-l);
|
||||
for (int i = 0; i < d; i++)
|
||||
{
|
||||
int ki = (smolq.levels[isummand])[i];
|
||||
p[i] = (smolq.uquad).point(ki, jseq[i]);
|
||||
w *= (smolq.uquad).weight(ki, jseq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
void
|
||||
smolpit::print() const
|
||||
{
|
||||
auto ff = std::cout.flags();
|
||||
std::cout << "isum=" << std::left << std::setw(3) << isummand << std::right << ": [";
|
||||
for (int i = 0; i < smolq.dimen(); i++)
|
||||
std::cout << std::setw(2) << (smolq.levels[isummand])[i] << ' ';
|
||||
std::cout << "] j=[";
|
||||
for (int i = 0; i < smolq.dimen(); i++)
|
||||
std::cout << std::setw(2) << jseq[i] << ' ';
|
||||
std::cout << std::showpos << std::fixed << std::setprecision(3)
|
||||
<< "] " << std::setw(4) << w << "*(";
|
||||
for (int i = 0; i < smolq.dimen()-1; i++)
|
||||
std::cout << std::setw(4) << p[i] << ' ';
|
||||
std::cout << std::setw(4) << p[smolq.dimen()-1] << ')' << std::endl;
|
||||
std::cout.flags(ff);
|
||||
}
|
||||
|
||||
/* Here is the constructor of SmolyakQuadrature. We have to setup ‘levels’,
|
||||
‘levpoints’ and ‘cumevals’. We have to go through all d-dimensional
|
||||
sequences k, such that l≤|k|≤l+d−1 and all kᵢ are positive integers. This is
|
||||
equivalent to going through all k such that l−d≤|k|≤l−1 and all kᵢ are
|
||||
non-negative integers. This is equivalent to going through d+1 dimensional
|
||||
sequences (k,x) such that |(k,x)|=l−1 and x=0,…,d−1. The resulting sequence
|
||||
of positive integers is obtained by adding 1 to all kᵢ. */
|
||||
|
||||
SmolyakQuadrature::SmolyakQuadrature(int d, int l, const OneDQuadrature &uq)
|
||||
: QuadratureImpl<smolpit>(d), level(l), uquad(uq)
|
||||
{
|
||||
// TODO: check l>1, l≥d
|
||||
// TODO: check l≥uquad.miLevel(), l≤uquad.maxLevel()
|
||||
int cum = 0;
|
||||
for (const auto &si : SymmetrySet(l-1, d+1))
|
||||
{
|
||||
if (si[d] <= d-1)
|
||||
{
|
||||
IntSequence lev(si, 0, d);
|
||||
lev.add(1);
|
||||
levels.push_back(lev);
|
||||
IntSequence levpts(d);
|
||||
for (int i = 0; i < d; i++)
|
||||
levpts[i] = uquad.numPoints(lev[i]);
|
||||
levpoints.push_back(levpts);
|
||||
cum += levpts.mult();
|
||||
cumevals.push_back(cum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we return a number of evalutions of the quadrature for the given level.
|
||||
If the given level is the current one, we simply return the maximum
|
||||
cumulative number of evaluations. Otherwise we call costly
|
||||
calcNumEvaluations() method. */
|
||||
|
||||
int
|
||||
SmolyakQuadrature::numEvals(int l) const
|
||||
{
|
||||
if (l != level)
|
||||
return calcNumEvaluations(l);
|
||||
else
|
||||
return cumevals[numSummands()-1];
|
||||
}
|
||||
|
||||
/* This divides all the evaluations to ‘tn’ approximately equal groups, and
|
||||
returns the beginning of the specified group ‘ti’. The granularity of
|
||||
divisions are summands as listed by ‘levels’. */
|
||||
|
||||
smolpit
|
||||
SmolyakQuadrature::begin(int ti, int tn, int l) const
|
||||
{
|
||||
// TODO: raise is level≠l
|
||||
if (ti == tn)
|
||||
return smolpit(*this, numSummands());
|
||||
|
||||
int totevals = cumevals[numSummands()-1];
|
||||
int evals = (totevals*ti)/tn;
|
||||
unsigned int isum = 0;
|
||||
while (isum+1 < numSummands() && cumevals[isum+1] < evals)
|
||||
isum++;
|
||||
return smolpit(*this, isum);
|
||||
}
|
||||
|
||||
/* This is the same in a structure as SmolyakQuadrature constructor. We have to
|
||||
go through all summands and calculate a number of evaluations in each
|
||||
summand. */
|
||||
|
||||
int
|
||||
SmolyakQuadrature::calcNumEvaluations(int lev) const
|
||||
{
|
||||
int cum = 0;
|
||||
for (const auto &si : SymmetrySet(lev-1, dim+1))
|
||||
{
|
||||
if (si[dim] <= dim-1)
|
||||
{
|
||||
IntSequence lev(si, 0, dim);
|
||||
lev.add(1);
|
||||
IntSequence levpts(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
levpts[i] = uquad.numPoints(lev[i]);
|
||||
cum += levpts.mult();
|
||||
}
|
||||
}
|
||||
return cum;
|
||||
}
|
||||
|
||||
/* This returns a maximum level such that the number of evaluations is less
|
||||
than the given number. */
|
||||
|
||||
void
|
||||
SmolyakQuadrature::designLevelForEvals(int max_evals, int &lev, int &evals) const
|
||||
{
|
||||
int last_evals;
|
||||
evals = 1;
|
||||
lev = 1;
|
||||
do
|
||||
{
|
||||
lev++;
|
||||
last_evals = evals;
|
||||
evals = calcNumEvaluations(lev);
|
||||
}
|
||||
while (lev < uquad.numLevels() && evals <= max_evals);
|
||||
lev--;
|
||||
evals = last_evals;
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Smolyak quadrature.
|
||||
|
||||
/* This file defines Smolyak (sparse grid) multidimensional quadrature for
|
||||
non-nested underlying one dimensional quadrature. Let Q¹ₗ denote the one
|
||||
dimensional quadrature of l level. Let nₗ denote a number of points in the l
|
||||
level. Than the Smolyak quadrature can be defined as
|
||||
|
||||
⎛ d−1 ⎞
|
||||
Qᵈf = ∑ (−1)^{l+d−|k|−1} ⎢ ⎥ (Q¹_k₁⊗…⊗Q¹_{k_d})f
|
||||
l≤|k|≤l+d−1 ⎝|k|−l⎠
|
||||
|
||||
where d is the dimension, k is d-dimensional sequence of integers, and |k|
|
||||
denotes the sum of the sequence.
|
||||
|
||||
Here we define smolpit as Smolyak iterator and SmolyakQuadrature. */
|
||||
|
||||
#ifndef SMOLYAK_H
|
||||
#define SMOLYAK_H
|
||||
|
||||
#include "int_sequence.hh"
|
||||
#include "tl_static.hh"
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
#include "pascal_triangle.hh"
|
||||
|
||||
/* Here we define the Smolyak point iterator. The Smolyak formula can be broken
|
||||
to a sum of product quadratures with various combinations of levels. The
|
||||
iterator follows this pattern. It maintains an index to a summand and then a
|
||||
point coordinates within the summand (product quadrature). The array of
|
||||
summands to which the ‘isummand’ points is maintained by the
|
||||
SmolyakQuadrature class to which the object knows the pointer ‘smolq’.
|
||||
|
||||
We provide a constructor which points to the beginning of the given summand.
|
||||
This constructor is used in SmolyakQuadrature::begin() method which
|
||||
approximately divideds all the iterators to subsets of equal size. */
|
||||
|
||||
class SmolyakQuadrature;
|
||||
|
||||
class smolpit
|
||||
{
|
||||
protected:
|
||||
const SmolyakQuadrature &smolq;
|
||||
unsigned int isummand{0};
|
||||
IntSequence jseq;
|
||||
ParameterSignal sig;
|
||||
Vector p;
|
||||
double w;
|
||||
public:
|
||||
smolpit(const SmolyakQuadrature &q, unsigned int isum);
|
||||
smolpit(const smolpit &spit) = default;
|
||||
~smolpit() = default;
|
||||
bool operator==(const smolpit &spit) const;
|
||||
bool
|
||||
operator!=(const smolpit &spit) const
|
||||
{
|
||||
return !operator==(spit);
|
||||
}
|
||||
smolpit &operator=(const smolpit &spit) = delete;
|
||||
smolpit &operator++();
|
||||
const ParameterSignal &
|
||||
signal() const
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
double
|
||||
weight() const
|
||||
{
|
||||
return w;
|
||||
}
|
||||
void print() const;
|
||||
protected:
|
||||
void setPointAndWeight();
|
||||
};
|
||||
|
||||
/* Here we define the class SmolyakQuadrature. It maintains an array of
|
||||
summands of the Smolyak quadrature formula:
|
||||
|
||||
⎛ d−1 ⎞
|
||||
∑ (−1)^{l+d−|k|−1} ⎢ ⎥ (Q¹_k₁⊗…⊗Q¹_{k_d})f
|
||||
l≤|k|≤l+d−1 ⎝|k|−l⎠
|
||||
|
||||
Each summand is fully specified by sequence k. The summands are here
|
||||
represented (besides k) also by sequence of number of points in each level
|
||||
selected by k, and also by a cummulative number of evaluations. The latter
|
||||
two are added only for conveniency.
|
||||
|
||||
The summands in the code are given by ‘levels’, which is a vector of
|
||||
k sequences, further by ‘levpoints’ which is a vector of sequences
|
||||
of nuber of points in each level, and by ‘cumevals’ which is the
|
||||
cumulative number of points, this is:
|
||||
|
||||
d
|
||||
∑ ∏ n_kᵢ
|
||||
ᵏ ⁱ⁼¹
|
||||
|
||||
where the sum is done through all k before the current.
|
||||
|
||||
The ‘levels’ and ‘levpoints’ vectors are used by smolpit. */
|
||||
|
||||
class SmolyakQuadrature : public QuadratureImpl<smolpit>
|
||||
{
|
||||
friend class smolpit;
|
||||
int level;
|
||||
const OneDQuadrature &uquad;
|
||||
std::vector<IntSequence> levels;
|
||||
std::vector<IntSequence> levpoints;
|
||||
std::vector<int> cumevals;
|
||||
public:
|
||||
SmolyakQuadrature(int d, int l, const OneDQuadrature &uq);
|
||||
~SmolyakQuadrature() override = default;
|
||||
int numEvals(int level) const override;
|
||||
void designLevelForEvals(int max_eval, int &lev, int &evals) const;
|
||||
protected:
|
||||
smolpit begin(int ti, int tn, int level) const override;
|
||||
unsigned int
|
||||
numSummands() const
|
||||
{
|
||||
return levels.size();
|
||||
}
|
||||
private:
|
||||
int calcNumEvaluations(int level) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vector_function.hh"
|
||||
|
||||
#include <dynlapack.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
/* Just an easy constructor of sequence of booleans defaulting to change
|
||||
everywhere. */
|
||||
|
||||
ParameterSignal::ParameterSignal(int n)
|
||||
: data(n, true)
|
||||
{
|
||||
}
|
||||
|
||||
/* This sets ‘false’ (no change) before a given parameter, and ‘true’ (change)
|
||||
after the given parameter (including). */
|
||||
|
||||
void
|
||||
ParameterSignal::signalAfter(int l)
|
||||
{
|
||||
for (size_t i = 0; i < std::min(static_cast<size_t>(l), data.size()); i++)
|
||||
data[i] = false;
|
||||
for (size_t i = l; i < data.size(); i++)
|
||||
data[i] = true;
|
||||
}
|
||||
|
||||
/* This constructs a function set hardcopying also the first. */
|
||||
VectorFunctionSet::VectorFunctionSet(const VectorFunction &f, int n)
|
||||
: funcs(n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
func_copies.push_back(f.clone());
|
||||
funcs[i] = func_copies.back().get();
|
||||
}
|
||||
}
|
||||
|
||||
/* This constructs a function set with shallow copy in the first and hard
|
||||
copies in others. */
|
||||
VectorFunctionSet::VectorFunctionSet(VectorFunction &f, int n)
|
||||
: funcs(n)
|
||||
{
|
||||
if (n > 0)
|
||||
funcs[0] = &f;
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
func_copies.push_back(f.clone());
|
||||
funcs[i] = func_copies.back().get();
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we construct the object from the given function f and given
|
||||
variance-covariance matrix Σ=vcov. The matrix A is calculated as lower
|
||||
triangular and yields Σ=AAᵀ. */
|
||||
|
||||
GaussConverterFunction::GaussConverterFunction(VectorFunction &f, const GeneralMatrix &vcov)
|
||||
: VectorFunction(f), func(&f), A(vcov.nrows(), vcov.nrows()),
|
||||
multiplier(calcMultiplier())
|
||||
{
|
||||
// TODO: raise if A.nrows() ≠ indim()
|
||||
calcCholeskyFactor(vcov);
|
||||
}
|
||||
|
||||
GaussConverterFunction::GaussConverterFunction(std::unique_ptr<VectorFunction> f, const GeneralMatrix &vcov)
|
||||
: VectorFunction(*f), func_storage{move(f)}, func{func_storage.get()}, A(vcov.nrows(), vcov.nrows()),
|
||||
multiplier(calcMultiplier())
|
||||
{
|
||||
// TODO: raise if A.nrows() ≠ indim()
|
||||
calcCholeskyFactor(vcov);
|
||||
}
|
||||
|
||||
GaussConverterFunction::GaussConverterFunction(const GaussConverterFunction &f)
|
||||
: VectorFunction(f), func_storage{f.func->clone()}, func{func_storage.get()}, A(f.A),
|
||||
multiplier(f.multiplier)
|
||||
{
|
||||
}
|
||||
|
||||
/* Here we evaluate the function
|
||||
|
||||
g(y) = 1/√(πⁿ) f(√2·Ay).
|
||||
|
||||
Since the matrix A is lower triangular, the change signal for the function f
|
||||
will look like (0,…,0,1,…,1) where the first 1 is in the same position as
|
||||
the first change in the given signal ‘sig’ of the input y=point. */
|
||||
|
||||
void
|
||||
GaussConverterFunction::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
ParameterSignal s(sig);
|
||||
int i = 0;
|
||||
while (i < indim() && !sig[i])
|
||||
i++;
|
||||
s.signalAfter(i);
|
||||
|
||||
Vector x(indim());
|
||||
x.zeros();
|
||||
A.multaVec(x, point);
|
||||
x.mult(sqrt(2.0));
|
||||
|
||||
func->eval(x, s, out);
|
||||
|
||||
out.mult(multiplier);
|
||||
}
|
||||
|
||||
/* This returns 1/√(πⁿ). */
|
||||
|
||||
double
|
||||
GaussConverterFunction::calcMultiplier() const
|
||||
{
|
||||
return sqrt(pow(M_PI, -1*indim()));
|
||||
}
|
||||
|
||||
void
|
||||
GaussConverterFunction::calcCholeskyFactor(const GeneralMatrix &vcov)
|
||||
{
|
||||
A = vcov;
|
||||
|
||||
lapack_int rows = A.nrows(), lda = A.getLD();
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = i+1; j < rows; j++)
|
||||
A.get(i, j) = 0.0;
|
||||
|
||||
lapack_int info;
|
||||
dpotrf("L", &rows, A.base(), &lda, &info);
|
||||
// TODO: raise if info≠1
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Vector function.
|
||||
|
||||
/* This file defines interface for functions taking a vector as an input and
|
||||
returning a vector (with a different size) as an output. We are also
|
||||
introducing a parameter signalling; it is a boolean vector which tracks
|
||||
parameters which were changed from the previous call. The VectorFunction
|
||||
implementation can exploit this information and evaluate the function more
|
||||
efficiently. The information can be completely ignored.
|
||||
|
||||
From the signalling reason, and from other reasons, the function evaluation
|
||||
is not const. */
|
||||
|
||||
#ifndef VECTOR_FUNCTION_H
|
||||
#define VECTOR_FUNCTION_H
|
||||
|
||||
#include "Vector.hh"
|
||||
#include "GeneralMatrix.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
/* This is a simple class representing a vector of booleans. The items night be
|
||||
retrieved or changed, or can be set ‘true’ after some point. This is useful
|
||||
when we multiply the vector with lower triangular matrix.
|
||||
|
||||
‘true’ means that a parameter was changed. */
|
||||
|
||||
class ParameterSignal
|
||||
{
|
||||
protected:
|
||||
std::vector<bool> data;
|
||||
public:
|
||||
ParameterSignal(int n);
|
||||
ParameterSignal(const ParameterSignal &sig) = default;
|
||||
~ParameterSignal() = default;
|
||||
void signalAfter(int l);
|
||||
bool
|
||||
operator[](int i) const
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
std::vector<bool>::reference
|
||||
operator[](int i)
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
};
|
||||
|
||||
/* This is the abstract class for vector function. At this level of abstraction
|
||||
we only need to know size of input vector and a size of output vector.
|
||||
|
||||
The important thing here is a clone method, we will need to make hard copies
|
||||
of vector functions since the evaluations are not const. The hardcopies
|
||||
apply for parallelization. */
|
||||
|
||||
class VectorFunction
|
||||
{
|
||||
protected:
|
||||
int in_dim;
|
||||
int out_dim;
|
||||
public:
|
||||
VectorFunction(int idim, int odim)
|
||||
: in_dim(idim), out_dim(odim)
|
||||
{
|
||||
}
|
||||
VectorFunction(const VectorFunction &func) = default;
|
||||
virtual ~VectorFunction() = default;
|
||||
virtual std::unique_ptr<VectorFunction> clone() const = 0;
|
||||
virtual void eval(const Vector &point, const ParameterSignal &sig, Vector &out) = 0;
|
||||
int
|
||||
indim() const
|
||||
{
|
||||
return in_dim;
|
||||
}
|
||||
int
|
||||
outdim() const
|
||||
{
|
||||
return out_dim;
|
||||
}
|
||||
};
|
||||
|
||||
/* This makes ‘n’ copies of VectorFunction. The first constructor make exactly
|
||||
‘n’ new copies, the second constructor copies only the pointer to the first
|
||||
and others are hard (real) copies.
|
||||
|
||||
The class is useful for making a given number of copies at once, and this
|
||||
set can be reused many times if we need mupliple copis of the function (for
|
||||
example for paralelizing the code). */
|
||||
|
||||
class VectorFunctionSet
|
||||
{
|
||||
private:
|
||||
// Stores the hard copies made by the class
|
||||
std::vector<std::unique_ptr<VectorFunction>> func_copies;
|
||||
protected:
|
||||
std::vector<VectorFunction *> funcs;
|
||||
public:
|
||||
VectorFunctionSet(const VectorFunction &f, int n);
|
||||
VectorFunctionSet(VectorFunction &f, int n);
|
||||
~VectorFunctionSet() = default;
|
||||
VectorFunction &
|
||||
getFunc(int i)
|
||||
{
|
||||
return *(funcs[i]);
|
||||
}
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return funcs.size();
|
||||
}
|
||||
};
|
||||
|
||||
/* This class wraps another VectorFunction to allow integration of a function
|
||||
through normally distributed inputs. Namely, if one wants to integrate
|
||||
|
||||
1
|
||||
─────────── ∫ f(x)e^{−½xᵀ|Σ|⁻¹x}dx
|
||||
√{(2π)ⁿ|Σ|}
|
||||
|
||||
then if we write Σ=AAᵀ and x=√2·Ay, we get integral
|
||||
|
||||
1 1
|
||||
─────────── ∫ f(√2·Ay)e^{−½yᵀy} √(2ⁿ)|A|dy = ───── ∫ f(√2·Ay)e^{−½yᵀy}dy
|
||||
√{(2π)ⁿ|Σ|} √(πⁿ)
|
||||
|
||||
which means that a given function f we have to wrap to yield a function
|
||||
|
||||
g(y) = 1/√(πⁿ) f(√2·Ay).
|
||||
|
||||
This is exactly what this class is doing. This transformation is useful
|
||||
since the Gauss-Hermite points and weights are defined for weighting
|
||||
function e^{−y²}, so this transformation allows using Gauss-Hermite
|
||||
quadratures seemlessly in a context of integration through normally
|
||||
distributed inputs.
|
||||
|
||||
The class maintains a pointer to the function f. When the object is
|
||||
constructed by the first constructor, the f is assumed to be owned by the
|
||||
caller. If the object of this class is copied, then f is copied and hence
|
||||
stored in a std::unique_ptr. The second constructor takes a smart pointer to
|
||||
the function and in that case the class takes ownership of f. */
|
||||
|
||||
class GaussConverterFunction : public VectorFunction
|
||||
{
|
||||
private:
|
||||
std::unique_ptr<VectorFunction> func_storage;
|
||||
protected:
|
||||
VectorFunction *func;
|
||||
GeneralMatrix A;
|
||||
double multiplier;
|
||||
public:
|
||||
GaussConverterFunction(VectorFunction &f, const GeneralMatrix &vcov);
|
||||
GaussConverterFunction(std::unique_ptr<VectorFunction> f, const GeneralMatrix &vcov);
|
||||
GaussConverterFunction(const GaussConverterFunction &f);
|
||||
~GaussConverterFunction() override = default;
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<GaussConverterFunction>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
private:
|
||||
double calcMultiplier() const;
|
||||
void calcCholeskyFactor(const GeneralMatrix &vcov);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
noinst_PROGRAMS = quadrature-points
|
||||
|
||||
quadrature_points_SOURCES = quadrature-points.cc
|
||||
quadrature_points_CPPFLAGS = -I../.. -I../../sylv/cc -I../../integ/cc -I../../tl/cc -I../../utils/cc
|
||||
quadrature_points_CXXFLAGS = $(AM_CXXFLAGS) $(THREAD_CXXFLAGS)
|
||||
quadrature_points_LDADD = ../cc/libinteg.a ../../tl/cc/libtl.a ../../parser/cc/libparser.a ../../sylv/cc/libsylv.a ../../utils/cc/libutils.a $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS)
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* Copyright © 2008-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parser/cc/matrix_parser.hh"
|
||||
#include "utils/cc/exception.hh"
|
||||
#include "sylv/cc/GeneralMatrix.hh"
|
||||
#include "sylv/cc/Vector.hh"
|
||||
#include "sylv/cc/SymSchurDecomp.hh"
|
||||
#include "sylv/cc/SylvException.hh"
|
||||
#include "integ/cc/quadrature.hh"
|
||||
#include "integ/cc/smolyak.hh"
|
||||
#include "integ/cc/product.hh"
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
struct QuadParams
|
||||
{
|
||||
std::string outname;
|
||||
std::string vcovname;
|
||||
int max_level{3};
|
||||
double discard_weight{0.0};
|
||||
QuadParams(int argc, char **argv);
|
||||
void check_consistency() const;
|
||||
private:
|
||||
enum class opt { max_level, discard_weight, vcov };
|
||||
};
|
||||
|
||||
QuadParams::QuadParams(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
// Print the help and exit
|
||||
std::cerr << "Usage: " << argv[0] << " [--max-level INTEGER] [--discard-weight FLOAT] [--vcov FILENAME] OUTPUT_FILENAME" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
outname = argv[argc-1];
|
||||
argc--;
|
||||
|
||||
struct option const opts[] = {
|
||||
{"max-level", required_argument, nullptr, static_cast<int>(opt::max_level)},
|
||||
{"discard-weight", required_argument, nullptr, static_cast<int>(opt::discard_weight)},
|
||||
{"vcov", required_argument, nullptr, static_cast<int>(opt::vcov)},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
int ret;
|
||||
int index;
|
||||
while (-1 != (ret = getopt_long(argc, argv, "", opts, &index)))
|
||||
{
|
||||
if (ret == '?')
|
||||
{
|
||||
std::cerr << "Unknown option, ignored\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (static_cast<opt>(ret))
|
||||
{
|
||||
case opt::max_level:
|
||||
try
|
||||
{
|
||||
max_level = std::stoi(optarg);
|
||||
}
|
||||
catch (const std::invalid_argument &e)
|
||||
{
|
||||
std::cerr << "Couldn't parse integer " << optarg << ", ignored" << std::endl;
|
||||
}
|
||||
break;
|
||||
case opt::discard_weight:
|
||||
try
|
||||
{
|
||||
discard_weight = std::stod(optarg);
|
||||
}
|
||||
catch (const std::invalid_argument &e)
|
||||
{
|
||||
std::cerr << "Couldn't parse float " << optarg << ", ignored" << std::endl;
|
||||
}
|
||||
break;
|
||||
case opt::vcov:
|
||||
vcovname = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
check_consistency();
|
||||
}
|
||||
|
||||
void
|
||||
QuadParams::check_consistency() const
|
||||
{
|
||||
if (outname.empty())
|
||||
{
|
||||
std::cerr << "Error: output name not set" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (vcovname.empty())
|
||||
{
|
||||
std::cerr << "Error: vcov file name not set" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
QuadParams params(argc, argv);
|
||||
|
||||
// Open output file for writing
|
||||
std::ofstream fout{params.outname, std::ios::out | std::ios::trunc};
|
||||
if (fout.fail())
|
||||
{
|
||||
std::cerr << "Could not open " << params.outname << " for writing" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::ifstream f{params.vcovname};
|
||||
std::ostringstream buffer;
|
||||
buffer << f.rdbuf();
|
||||
std::string contents{buffer.str()};
|
||||
|
||||
// Parse the vcov matrix
|
||||
ogp::MatrixParser mp;
|
||||
mp.parse(contents);
|
||||
if (mp.nrows() != mp.ncols())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"VCOV matrix not square");
|
||||
// And put to the GeneralMatrix
|
||||
GeneralMatrix vcov(mp.nrows(), mp.ncols());
|
||||
vcov.zeros();
|
||||
for (ogp::MPIterator it = mp.begin(); it != mp.end(); ++it)
|
||||
vcov.get(it.row(), it.col()) = *it;
|
||||
|
||||
// Calculate the factor A of vcov, so that A·Aᵀ=VCOV
|
||||
GeneralMatrix A(vcov.nrows(), vcov.nrows());
|
||||
SymSchurDecomp ssd(vcov);
|
||||
ssd.getFactor(A);
|
||||
|
||||
// Construct Gauss-Hermite quadrature
|
||||
GaussHermite ghq;
|
||||
// Construct Smolyak quadrature
|
||||
int level = params.max_level;
|
||||
SmolyakQuadrature sq(vcov.nrows(), level, ghq);
|
||||
|
||||
std::cout << "Dimension: " << vcov.nrows() << std::endl
|
||||
<< "Maximum level: " << level << std::endl
|
||||
<< "Total number of nodes: " << sq.numEvals(level) << std::endl;
|
||||
|
||||
// Put the points to the vector
|
||||
std::vector<std::unique_ptr<Vector>> points;
|
||||
for (smolpit qit = sq.start(level); qit != sq.end(level); ++qit)
|
||||
points.push_back(std::make_unique<Vector>(const_cast<const Vector &>(qit.point())));
|
||||
// Sort and uniq
|
||||
std::sort(points.begin(), points.end(), [](auto &a, auto &b) { return a.get() < b.get(); });
|
||||
auto new_end = std::unique(points.begin(), points.end());
|
||||
points.erase(new_end, points.end());
|
||||
|
||||
std::cout << "Duplicit nodes removed: " << static_cast<unsigned long>(sq.numEvals(level)-points.size())
|
||||
<< std::endl;
|
||||
|
||||
// Calculate weights and mass
|
||||
double mass = 0.0;
|
||||
std::vector<double> weights;
|
||||
for (auto &point : points)
|
||||
{
|
||||
weights.push_back(std::exp(-point->dot(*point)));
|
||||
mass += weights.back();
|
||||
}
|
||||
|
||||
// Calculate discarded mass
|
||||
double discard_mass = 0.0;
|
||||
for (double weight : weights)
|
||||
if (weight/mass < params.discard_weight)
|
||||
discard_mass += weight;
|
||||
|
||||
std::cout << "Total mass discarded: " << std::fixed << discard_mass/mass << std::endl;
|
||||
|
||||
// Dump the results
|
||||
int npoints = 0;
|
||||
double upscale_weight = 1/(mass-discard_mass);
|
||||
Vector x(vcov.nrows());
|
||||
fout << std::setprecision(16);
|
||||
for (int i = 0; i < static_cast<int>(weights.size()); i++)
|
||||
if (weights[i]/mass >= params.discard_weight)
|
||||
{
|
||||
// Print the upscaled weight
|
||||
fout << std::setw(20) << upscale_weight*weights[i];
|
||||
// Multiply point with the factor A and √2
|
||||
A.multVec(0.0, x, std::sqrt(2.), *(points[i]));
|
||||
// Print the coordinates
|
||||
for (int j = 0; j < x.length(); j++)
|
||||
fout << ' ' << std::setw(20) << x[j];
|
||||
fout << std::endl;
|
||||
npoints++;
|
||||
}
|
||||
|
||||
std::cout << "Final number of points: " << npoints << std::endl;
|
||||
|
||||
fout.close();
|
||||
}
|
||||
catch (const SylvException &e)
|
||||
{
|
||||
e.printMessage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
catch (const ogu::Exception &e)
|
||||
{
|
||||
e.print();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
check_PROGRAMS = tests
|
||||
|
||||
tests_SOURCES = tests.cc
|
||||
tests_CPPFLAGS = -I../cc -I../../tl/cc -I../../sylv/cc -I../../utils/cc -I$(top_srcdir)/mex/sources
|
||||
tests_CXXFLAGS = $(AM_CXXFLAGS) $(THREAD_CXXFLAGS)
|
||||
tests_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MATIO)
|
||||
tests_LDADD = ../../sylv/cc/libsylv.a ../cc/libinteg.a ../../tl/cc/libtl.a ../../utils/cc/libutils.a $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) $(LIBADD_MATIO)
|
||||
|
||||
check-local:
|
||||
./tests
|
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GeneralMatrix.hh"
|
||||
#include <dynlapack.h>
|
||||
#include "SylvException.hh"
|
||||
|
||||
#include "rfs_tensor.hh"
|
||||
#include "normal_moments.hh"
|
||||
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
#include "smolyak.hh"
|
||||
#include "product.hh"
|
||||
#include "quasi_mcarlo.hh"
|
||||
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
|
||||
/* Evaluates unfolded (Dx)ᵏ power, where x is a vector, D is a Cholesky factor
|
||||
(lower triangular) */
|
||||
class MomentFunction : public VectorFunction
|
||||
{
|
||||
GeneralMatrix D;
|
||||
int k;
|
||||
public:
|
||||
MomentFunction(const GeneralMatrix &inD, int kk)
|
||||
: VectorFunction(inD.nrows(), UFSTensor::calcMaxOffset(inD.nrows(), kk)),
|
||||
D(inD), k(kk)
|
||||
{
|
||||
}
|
||||
MomentFunction(const MomentFunction &func) = default;
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<MomentFunction>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
MomentFunction::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
if (point.length() != indim() || out.length() != outdim())
|
||||
{
|
||||
std::cerr << "Wrong length of vectors in MomentFunction::eval" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
Vector y(point);
|
||||
y.zeros();
|
||||
D.multaVec(y, point);
|
||||
URSingleTensor ypow(y, k);
|
||||
out.zeros();
|
||||
out.add(1.0, ypow.getData());
|
||||
}
|
||||
|
||||
class TensorPower : public VectorFunction
|
||||
{
|
||||
int k;
|
||||
public:
|
||||
TensorPower(int nvar, int kk)
|
||||
: VectorFunction(nvar, UFSTensor::calcMaxOffset(nvar, kk)), k(kk)
|
||||
{
|
||||
}
|
||||
TensorPower(const TensorPower &func) = default;
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<TensorPower>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
TensorPower::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
if (point.length() != indim() || out.length() != outdim())
|
||||
{
|
||||
std::cerr << "Wrong length of vectors in TensorPower::eval" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
URSingleTensor ypow(point, k);
|
||||
out.zeros();
|
||||
out.add(1.0, ypow.getData());
|
||||
}
|
||||
|
||||
/* Evaluates (1+1/d)ᵈ(x₁·…·x_d)^(1/d), its integral over [0,1]ᵈ
|
||||
is 1.0, and its variation grows exponentially */
|
||||
class Function1 : public VectorFunction
|
||||
{
|
||||
int dim;
|
||||
public:
|
||||
Function1(int d)
|
||||
: VectorFunction(d, 1), dim(d)
|
||||
{
|
||||
}
|
||||
Function1(const Function1 &f)
|
||||
: VectorFunction(f.indim(), f.outdim()), dim(f.dim)
|
||||
{
|
||||
}
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<Function1>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
Function1::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
if (point.length() != dim || out.length() != 1)
|
||||
{
|
||||
std::cerr << "Wrong length of vectors in Function1::eval" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
double r = 1;
|
||||
for (int i = 0; i < dim; i++)
|
||||
r *= point[i];
|
||||
r = pow(r, 1.0/dim);
|
||||
r *= pow(1.0 + 1.0/dim, static_cast<double>(dim));
|
||||
out[0] = r;
|
||||
}
|
||||
|
||||
// Evaluates Function1 but with transformation xᵢ=0.5(yᵢ+1)
|
||||
// This makes the new function integrate over [−1,1]ᵈ to 1.0
|
||||
class Function1Trans : public Function1
|
||||
{
|
||||
public:
|
||||
Function1Trans(int d)
|
||||
: Function1(d)
|
||||
{
|
||||
}
|
||||
Function1Trans(const Function1Trans &func) = default;
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<Function1Trans>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
Function1Trans::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
Vector p(point.length());
|
||||
for (int i = 0; i < p.length(); i++)
|
||||
p[i] = 0.5*(point[i]+1);
|
||||
Function1::eval(p, sig, out);
|
||||
out.mult(pow(0.5, indim()));
|
||||
}
|
||||
|
||||
/* WallTimer class. Constructor saves the wall time, destructor cancels the
|
||||
current time from the saved, and prints the message with time information */
|
||||
class WallTimer
|
||||
{
|
||||
std::string mes;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> start;
|
||||
bool new_line;
|
||||
public:
|
||||
WallTimer(std::string m, bool nl = true)
|
||||
: mes{m}, start{std::chrono::high_resolution_clock::now()}, new_line{nl}
|
||||
{
|
||||
}
|
||||
~WallTimer()
|
||||
{
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> duration = end - start;
|
||||
std::cout << mes << std::setw(8) << std::setprecision(4) << duration.count();
|
||||
if (new_line)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************/
|
||||
/* declaration of TestRunnable class */
|
||||
/****************************************************/
|
||||
class TestRunnable
|
||||
{
|
||||
public:
|
||||
const std::string name;
|
||||
int dim; // dimension of the solved problem
|
||||
int nvar; // number of variables of the solved problem
|
||||
TestRunnable(std::string name_arg, int d, int nv)
|
||||
: name{move(name_arg)}, dim(d), nvar(nv)
|
||||
{
|
||||
}
|
||||
virtual ~TestRunnable() = default;
|
||||
bool test() const;
|
||||
virtual bool run() const = 0;
|
||||
protected:
|
||||
static bool smolyak_normal_moments(const GeneralMatrix &m, int imom, int level);
|
||||
static bool product_normal_moments(const GeneralMatrix &m, int imom, int level);
|
||||
static bool qmc_normal_moments(const GeneralMatrix &m, int imom, int level);
|
||||
static bool smolyak_product_cube(const VectorFunction &func, const Vector &res,
|
||||
double tol, int level);
|
||||
static bool qmc_cube(const VectorFunction &func, double res, double tol, int level);
|
||||
};
|
||||
|
||||
bool
|
||||
TestRunnable::test() const
|
||||
{
|
||||
std::cout << "Running test <" << name << ">" << std::endl;
|
||||
bool passed;
|
||||
{
|
||||
WallTimer tim("Wall clock time ", false);
|
||||
passed = run();
|
||||
}
|
||||
if (passed)
|
||||
{
|
||||
std::cout << "............................ passed" << std::endl << std::endl;
|
||||
return passed;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "............................ FAILED" << std::endl << std::endl;
|
||||
return passed;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************/
|
||||
/* definition of TestRunnable static methods */
|
||||
/****************************************************/
|
||||
bool
|
||||
TestRunnable::smolyak_normal_moments(const GeneralMatrix &m, int imom, int level)
|
||||
{
|
||||
// First make m·mᵀ and then Cholesky factor
|
||||
GeneralMatrix msq(m * transpose(m));
|
||||
|
||||
// Make vector function
|
||||
int dim = m.nrows();
|
||||
TensorPower tp(dim, imom);
|
||||
GaussConverterFunction func(tp, msq);
|
||||
|
||||
// Smolyak quadrature
|
||||
Vector smol_out(UFSTensor::calcMaxOffset(dim, imom));
|
||||
{
|
||||
WallTimer tim("\tSmolyak quadrature time: ");
|
||||
GaussHermite gs;
|
||||
SmolyakQuadrature quad(dim, level, gs);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, smol_out);
|
||||
std::cout << "\tNumber of Smolyak evaluations: " << quad.numEvals(level) << std::endl;
|
||||
}
|
||||
|
||||
// Check against theoretical moments
|
||||
UNormalMoments moments(imom, msq);
|
||||
smol_out.add(-1.0, moments.get(Symmetry{imom}).getData());
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << smol_out.getMax() << std::endl;
|
||||
return smol_out.getMax() < 1.e-7;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRunnable::product_normal_moments(const GeneralMatrix &m, int imom, int level)
|
||||
{
|
||||
// First make m·mᵀ and then Cholesky factor
|
||||
GeneralMatrix msq(m * transpose(m));
|
||||
|
||||
// Make vector function
|
||||
int dim = m.nrows();
|
||||
TensorPower tp(dim, imom);
|
||||
GaussConverterFunction func(tp, msq);
|
||||
|
||||
// Product quadrature
|
||||
Vector prod_out(UFSTensor::calcMaxOffset(dim, imom));
|
||||
{
|
||||
WallTimer tim("\tProduct quadrature time: ");
|
||||
GaussHermite gs;
|
||||
ProductQuadrature quad(dim, gs);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, prod_out);
|
||||
std::cout << "\tNumber of product evaluations: " << quad.numEvals(level) << std::endl;
|
||||
}
|
||||
|
||||
// Check against theoretical moments
|
||||
UNormalMoments moments(imom, msq);
|
||||
prod_out.add(-1.0, moments.get(Symmetry{imom}).getData());
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << prod_out.getMax() << std::endl;
|
||||
return prod_out.getMax() < 1.e-7;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRunnable::smolyak_product_cube(const VectorFunction &func, const Vector &res,
|
||||
double tol, int level)
|
||||
{
|
||||
if (res.length() != func.outdim())
|
||||
{
|
||||
std::cerr << "Incompatible dimensions of check value and function." << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
GaussLegendre glq;
|
||||
Vector out(func.outdim());
|
||||
double smol_error;
|
||||
double prod_error;
|
||||
{
|
||||
WallTimer tim("\tSmolyak quadrature time: ");
|
||||
SmolyakQuadrature quad(func.indim(), level, glq);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, out);
|
||||
out.add(-1.0, res);
|
||||
smol_error = out.getMax();
|
||||
std::cout << "\tNumber of Smolyak evaluations: " << quad.numEvals(level) << std::endl;
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << smol_error << std::endl;
|
||||
}
|
||||
{
|
||||
WallTimer tim("\tProduct quadrature time: ");
|
||||
ProductQuadrature quad(func.indim(), glq);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, out);
|
||||
out.add(-1.0, res);
|
||||
prod_error = out.getMax();
|
||||
std::cout << "\tNumber of product evaluations: " << quad.numEvals(level) << std::endl;
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << prod_error << std::endl;
|
||||
}
|
||||
|
||||
return smol_error < tol && prod_error < tol;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRunnable::qmc_cube(const VectorFunction &func, double res, double tol, int level)
|
||||
{
|
||||
Vector r(1);
|
||||
double error1;
|
||||
{
|
||||
WallTimer tim("\tQuasi-Monte Carlo (Warnock scrambling) time: ");
|
||||
WarnockPerScheme wps;
|
||||
QMCarloCubeQuadrature qmc(func.indim(), level, wps);
|
||||
qmc.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, r);
|
||||
error1 = std::max(res - r[0], r[0] - res);
|
||||
std::cout << "\tQuasi-Monte Carlo (Warnock scrambling) error: " << std::setw(16) << std::setprecision(12) << error1 << std::endl;
|
||||
}
|
||||
double error2;
|
||||
{
|
||||
WallTimer tim("\tQuasi-Monte Carlo (reverse scrambling) time: ");
|
||||
ReversePerScheme rps;
|
||||
QMCarloCubeQuadrature qmc(func.indim(), level, rps);
|
||||
qmc.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, r);
|
||||
error2 = std::max(res - r[0], r[0] - res);
|
||||
std::cout << "\tQuasi-Monte Carlo (reverse scrambling) error: " << std::setw(16) << std::setprecision(12) << error2 << std::endl;
|
||||
}
|
||||
double error3;
|
||||
{
|
||||
WallTimer tim("\tQuasi-Monte Carlo (no scrambling) time: ");
|
||||
IdentityPerScheme ips;
|
||||
QMCarloCubeQuadrature qmc(func.indim(), level, ips);
|
||||
qmc.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, r);
|
||||
error3 = std::max(res - r[0], r[0] - res);
|
||||
std::cout << "\tQuasi-Monte Carlo (no scrambling) error: " << std::setw(16) << std::setprecision(12) << error3 << std::endl;
|
||||
}
|
||||
|
||||
return error1 < tol && error2 < tol && error3 < tol;
|
||||
}
|
||||
|
||||
/****************************************************/
|
||||
/* definition of TestRunnable subclasses */
|
||||
/****************************************************/
|
||||
class SmolyakNormalMom1 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
SmolyakNormalMom1()
|
||||
: TestRunnable("Smolyak normal moments (dim=2, level=4, order=4)", 4, 2)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(2, 2);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(1, 1) = 1;
|
||||
return smolyak_normal_moments(m, 4, 4);
|
||||
}
|
||||
};
|
||||
|
||||
class SmolyakNormalMom2 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
SmolyakNormalMom2()
|
||||
: TestRunnable("Smolyak normal moments (dim=3, level=8, order=8)", 8, 3)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(3, 3);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(0, 2) = 0.5;
|
||||
m.get(1, 1) = 1;
|
||||
m.get(1, 0) = 0.5;
|
||||
m.get(2, 2) = 2;
|
||||
m.get(2, 1) = 4;
|
||||
return smolyak_normal_moments(m, 8, 8);
|
||||
}
|
||||
};
|
||||
|
||||
class ProductNormalMom1 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
ProductNormalMom1()
|
||||
: TestRunnable("Product normal moments (dim=2, level=4, order=4)", 4, 2)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(2, 2);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(1, 1) = 1;
|
||||
return product_normal_moments(m, 4, 4);
|
||||
}
|
||||
};
|
||||
|
||||
class ProductNormalMom2 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
ProductNormalMom2()
|
||||
: TestRunnable("Product normal moments (dim=3, level=8, order=8)", 8, 3)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(3, 3);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(0, 2) = 0.5;
|
||||
m.get(1, 1) = 1;
|
||||
m.get(1, 0) = 0.5;
|
||||
m.get(2, 2) = 2;
|
||||
m.get(2, 1) = 4;
|
||||
return product_normal_moments(m, 8, 8);
|
||||
}
|
||||
};
|
||||
|
||||
// Note that here we pass 1,1 to tls since smolyak has its own PascalTriangle
|
||||
class F1GaussLegendre : public TestRunnable
|
||||
{
|
||||
public:
|
||||
F1GaussLegendre()
|
||||
: TestRunnable("Function1 Gauss-Legendre (dim=6, level=13", 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
Function1Trans f1(6);
|
||||
Vector res(1);
|
||||
res[0] = 1.0;
|
||||
return smolyak_product_cube(f1, res, 1e-2, 13);
|
||||
}
|
||||
};
|
||||
|
||||
class F1QuasiMCarlo : public TestRunnable
|
||||
{
|
||||
public:
|
||||
F1QuasiMCarlo()
|
||||
: TestRunnable("Function1 Quasi-Monte Carlo (dim=6, level=1000000)", 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
Function1 f1(6);
|
||||
return qmc_cube(f1, 1.0, 1.e-4, 1000000);
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::vector<std::unique_ptr<TestRunnable>> all_tests;
|
||||
// Fill in vector of all tests
|
||||
all_tests.push_back(std::make_unique<SmolyakNormalMom1>());
|
||||
all_tests.push_back(std::make_unique<SmolyakNormalMom2>());
|
||||
all_tests.push_back(std::make_unique<ProductNormalMom1>());
|
||||
all_tests.push_back(std::make_unique<ProductNormalMom2>());
|
||||
all_tests.push_back(std::make_unique<F1GaussLegendre>());
|
||||
all_tests.push_back(std::make_unique<F1QuasiMCarlo>());
|
||||
|
||||
// Find maximum dimension and maximum nvar
|
||||
int dmax = 0;
|
||||
int nvmax = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
dmax = std::max(dmax, test->dim);
|
||||
nvmax = std::max(nvmax, test->nvar);
|
||||
}
|
||||
TLStatic::init(dmax, nvmax); // initialize library
|
||||
|
||||
// Launch the tests
|
||||
int success = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (test->test())
|
||||
success++;
|
||||
}
|
||||
catch (const TLException &e)
|
||||
{
|
||||
std::cout << "Caught TL exception in <" << test->name << ">:" << std::endl;
|
||||
e.print();
|
||||
}
|
||||
catch (SylvException &e)
|
||||
{
|
||||
std::cout << "Caught Sylv exception in <" << test->name << ">:" << std::endl;
|
||||
e.printMessage();
|
||||
}
|
||||
}
|
||||
|
||||
int nfailed = all_tests.size() - success;
|
||||
std::cout << "There were " << nfailed << " tests that failed out of "
|
||||
<< all_tests.size() << " tests run." << std::endl;
|
||||
|
||||
if (nfailed)
|
||||
return EXIT_FAILURE;
|
||||
else
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
noinst_LIBRARIES = libkord.a
|
||||
|
||||
libkord_a_SOURCES = \
|
||||
approximation.cc \
|
||||
approximation.hh \
|
||||
decision_rule.cc \
|
||||
decision_rule.hh \
|
||||
dynamic_model.cc \
|
||||
dynamic_model.hh \
|
||||
faa_di_bruno.cc \
|
||||
faa_di_bruno.hh \
|
||||
first_order.cc \
|
||||
first_order.hh \
|
||||
global_check.cc \
|
||||
global_check.hh \
|
||||
kord_exception.hh \
|
||||
korder.cc \
|
||||
korder.hh \
|
||||
korder_stoch.cc \
|
||||
korder_stoch.hh \
|
||||
journal.cc \
|
||||
journal.hh \
|
||||
normal_conjugate.cc \
|
||||
normal_conjugate.hh \
|
||||
seed_generator.cc \
|
||||
seed_generator.hh
|
||||
|
||||
libkord_a_CPPFLAGS = -I../sylv/cc -I../tl/cc -I../integ/cc -I../utils/cc -I$(top_srcdir)/mex/sources $(CPPFLAGS_MATIO) -DDYNVERSION=\"$(PACKAGE_VERSION)\"
|
||||
libkord_a_CXXFLAGS = $(AM_CXXFLAGS) $(THREAD_CXXFLAGS)
|
||||
|
||||
check_PROGRAMS = tests
|
||||
|
||||
tests_SOURCES = tests.cc
|
||||
tests_CPPFLAGS = -I../sylv/cc -I../tl/cc -I../integ/cc -I../utils/cc -I$(top_srcdir)/mex/sources
|
||||
tests_CXXFLAGS = $(AM_CXXFLAGS) $(THREAD_CXXFLAGS)
|
||||
tests_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MATIO)
|
||||
tests_LDADD = libkord.a ../tl/cc/libtl.a ../sylv/cc/libsylv.a ../utils/cc/libutils.a $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) $(LIBADD_MATIO)
|
||||
|
||||
check-local:
|
||||
./tests
|
||||
|
||||
CLEANFILES = out.txt
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2021 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -20,15 +20,15 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
#include "kord_exception.hh"
|
||||
#include "approximation.hh"
|
||||
#include "first_order.hh"
|
||||
#include "kord_exception.hh"
|
||||
#include "korder_stoch.hh"
|
||||
|
||||
ZAuxContainer::ZAuxContainer(const _Ctype* gss, int ngss, int ng, int ny, int nu) :
|
||||
StackContainer<FGSTensor>(4, 1)
|
||||
ZAuxContainer::ZAuxContainer(const _Ctype *gss, int ngss, int ng, int ny, int nu)
|
||||
: StackContainer<FGSTensor>(4, 1)
|
||||
{
|
||||
stack_sizes = {ngss, ng, ny, nu};
|
||||
stack_sizes = { ngss, ng, ny, nu };
|
||||
conts[0] = gss;
|
||||
calculateOffsets();
|
||||
}
|
||||
|
@ -37,36 +37,29 @@ ZAuxContainer::ZAuxContainer(const _Ctype* gss, int ngss, int ng, int ny, int nu
|
|||
argument we return ‘matrix’, for other three we return ‘zero’. */
|
||||
|
||||
ZAuxContainer::itype
|
||||
ZAuxContainer::getType(int i, const Symmetry& s) const
|
||||
ZAuxContainer::getType(int i, const Symmetry &s) const
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
}
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
return itype::zero;
|
||||
}
|
||||
|
||||
Approximation::Approximation(DynamicModel& m, Journal& j, int ns, bool dr_centr, bool pruned_dr,
|
||||
double qz_crit) :
|
||||
model(m),
|
||||
journal(j),
|
||||
Approximation::Approximation(DynamicModel &m, Journal &j, int ns, bool dr_centr, double qz_crit)
|
||||
: model(m), journal(j),
|
||||
ypart(model.nstat(), model.npred(), model.nboth(), model.nforw()),
|
||||
mom(UNormalMoments(model.order(), model.getVcov())),
|
||||
nvs {ypart.nys(), model.nexog(), model.nexog(), 1},
|
||||
nvs{ypart.nys(), model.nexog(), model.nexog(), 1},
|
||||
steps(ns),
|
||||
dr_centralize(dr_centr),
|
||||
pruning(pruned_dr),
|
||||
qz_criterium(qz_crit),
|
||||
ss(ypart.ny(), steps + 1)
|
||||
dr_centralize(dr_centr), qz_criterium(qz_crit), ss(ypart.ny(), steps+1)
|
||||
{
|
||||
ss.nans();
|
||||
}
|
||||
|
||||
/* This just returns ‘fdr’ with a check that it is created. */
|
||||
const FoldDecisionRule&
|
||||
const FoldDecisionRule &
|
||||
Approximation::getFoldDecisionRule() const
|
||||
{
|
||||
KORD_RAISE_IF(!fdr,
|
||||
|
@ -74,22 +67,12 @@ Approximation::getFoldDecisionRule() const
|
|||
return *fdr;
|
||||
}
|
||||
|
||||
/* This just returns ‘fdr_pruning’ with a check that it is created. */
|
||||
const UnfoldDecisionRule&
|
||||
Approximation::getUnfoldDecisionRulePruning() const
|
||||
{
|
||||
KORD_RAISE_IF(
|
||||
!udr_pruning,
|
||||
"Unfolded decision rule has not been created in Approximation::getUnfoldDecisionRule");
|
||||
return *udr_pruning;
|
||||
}
|
||||
|
||||
/* This just returns ‘udr’ with a check that it is created. */
|
||||
const UnfoldDecisionRule&
|
||||
const UnfoldDecisionRule &
|
||||
Approximation::getUnfoldDecisionRule() const
|
||||
{
|
||||
KORD_RAISE_IF(
|
||||
!udr, "Unfolded decision rule has not been created in Approximation::getUnfoldDecisionRule");
|
||||
KORD_RAISE_IF(!udr,
|
||||
"Unfolded decision rule has not been created in Approximation::getUnfoldDecisionRule");
|
||||
return *udr;
|
||||
}
|
||||
|
||||
|
@ -101,13 +84,15 @@ void
|
|||
Approximation::approxAtSteady()
|
||||
{
|
||||
model.calcDerivativesAtSteady();
|
||||
FirstOrder fo(model.nstat(), model.npred(), model.nboth(), model.nforw(), model.nexog(),
|
||||
model.getModelDerivatives().get(Symmetry {1}), journal, qz_criterium);
|
||||
FirstOrder fo(model.nstat(), model.npred(), model.nboth(), model.nforw(),
|
||||
model.nexog(), model.getModelDerivatives().get(Symmetry{1}),
|
||||
journal, qz_criterium);
|
||||
|
||||
if (model.order() >= 2)
|
||||
{
|
||||
KOrder korder(model.nstat(), model.npred(), model.nboth(), model.nforw(),
|
||||
model.getModelDerivatives(), fo.getGy(), fo.getGu(), model.getVcov(), journal);
|
||||
model.getModelDerivatives(), fo.getGy(), fo.getGu(),
|
||||
model.getVcov(), journal);
|
||||
korder.switchToFolded();
|
||||
for (int k = 2; k <= model.order(); k++)
|
||||
korder.performStep<Storage::fold>(k);
|
||||
|
@ -159,28 +144,27 @@ Approximation::walkStochSteady()
|
|||
to ‘ss’. */
|
||||
model.solveDeterministicSteady();
|
||||
approxAtSteady();
|
||||
Vector steady0 {ss.getCol(0)};
|
||||
Vector steady0{ss.getCol(0)};
|
||||
steady0 = model.getSteady();
|
||||
|
||||
double sigma_so_far = 0.0;
|
||||
double dsigma = (steps == 0) ? 0.0 : 1.0 / steps;
|
||||
double dsigma = (steps == 0) ? 0.0 : 1.0/steps;
|
||||
for (int i = 1; i <= steps; i++)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Approximation about stochastic steady for sigma=" << sigma_so_far + dsigma << endrec;
|
||||
pa << "Approximation about stochastic steady for sigma=" << sigma_so_far+dsigma << endrec;
|
||||
|
||||
Vector last_steady(const_cast<const Vector&>(model.getSteady()));
|
||||
Vector last_steady(const_cast<const Vector &>(model.getSteady()));
|
||||
|
||||
// calculate fix-point of the last rule for ‘dsigma’
|
||||
/* We form the DRFixPoint object from the last rule with σ=dsigma. Then
|
||||
we save the steady state to ‘ss’. The new steady is also put to
|
||||
model.getSteady(). */
|
||||
DRFixPoint<Storage::fold> fp(*rule_ders, ypart, model.getSteady(), dsigma);
|
||||
bool converged = fp.calcFixPoint(model.getSteady());
|
||||
bool converged = fp.calcFixPoint(DecisionRule::emethod::horner, model.getSteady());
|
||||
JournalRecord rec(journal);
|
||||
rec << "Fix point calcs: iter=" << fp.getNumIter()
|
||||
<< ", newton_iter=" << fp.getNewtonTotalIter()
|
||||
<< ", last_newton_iter=" << fp.getNewtonLastIter() << ".";
|
||||
rec << "Fix point calcs: iter=" << fp.getNumIter() << ", newton_iter="
|
||||
<< fp.getNewtonTotalIter() << ", last_newton_iter=" << fp.getNewtonLastIter() << ".";
|
||||
if (converged)
|
||||
rec << " Converged." << endrec;
|
||||
else
|
||||
|
@ -188,7 +172,7 @@ Approximation::walkStochSteady()
|
|||
rec << " Not converged!!" << endrec;
|
||||
KORD_RAISE_X("Fix point calculation not converged", KORD_FP_NOT_CONV);
|
||||
}
|
||||
Vector steadyi {ss.getCol(i)};
|
||||
Vector steadyi{ss.getCol(i)};
|
||||
steadyi = model.getSteady();
|
||||
|
||||
// calculate ‘hh’ as expectations of the last g**
|
||||
|
@ -196,11 +180,11 @@ Approximation::walkStochSteady()
|
|||
minus the old steady state. Then we create StochForwardDerivs object,
|
||||
which calculates the derivatives of g** expectations at new sigma and
|
||||
new steady. */
|
||||
Vector dy(const_cast<const Vector&>(model.getSteady()));
|
||||
Vector dy(const_cast<const Vector &>(model.getSteady()));
|
||||
dy.add(-1.0, last_steady);
|
||||
|
||||
StochForwardDerivs<Storage::fold> hh(ypart, model.nexog(), *rule_ders_ss, mom, dy, dsigma,
|
||||
sigma_so_far);
|
||||
StochForwardDerivs<Storage::fold> hh(ypart, model.nexog(), *rule_ders_ss, mom, dy,
|
||||
dsigma, sigma_so_far);
|
||||
JournalRecord rec1(journal);
|
||||
rec1 << "Calculation of g** expectations done" << endrec;
|
||||
|
||||
|
@ -208,35 +192,29 @@ Approximation::walkStochSteady()
|
|||
/* We calculate derivatives of the model at the new steady, form
|
||||
KOrderStoch object and solve, and save the rule. */
|
||||
model.calcDerivativesAtSteady();
|
||||
KOrderStoch korder_stoch(ypart, model.nexog(), model.getModelDerivatives(), hh, journal);
|
||||
KOrderStoch korder_stoch(ypart, model.nexog(), model.getModelDerivatives(),
|
||||
hh, journal);
|
||||
for (int d = 1; d <= model.order(); d++)
|
||||
korder_stoch.performStep<Storage::fold>(d);
|
||||
|
||||
saveRuleDerivs(korder_stoch.getFoldDers());
|
||||
|
||||
check(sigma_so_far + dsigma);
|
||||
check(sigma_so_far+dsigma);
|
||||
sigma_so_far += dsigma;
|
||||
}
|
||||
|
||||
// construct the resulting decision rules
|
||||
udr.reset();
|
||||
fdr = std::make_unique<FoldDecisionRule>(*rule_ders, ypart, model.nexog(), model.getSteady(),
|
||||
1.0 - sigma_so_far);
|
||||
if (pruning)
|
||||
{
|
||||
fdr_pruning = std::make_unique<FoldDecisionRule>(
|
||||
*rule_ders, ypart, model.nexog(), model.getSteady(), 1.0 - sigma_so_far, pruning);
|
||||
udr_pruning = std::make_unique<UnfoldDecisionRule>(*fdr_pruning);
|
||||
}
|
||||
fdr = std::make_unique<FoldDecisionRule>(*rule_ders, ypart, model.nexog(),
|
||||
model.getSteady(), 1.0-sigma_so_far);
|
||||
if (steps == 0 && dr_centralize)
|
||||
{
|
||||
// centralize decision rule for zero steps
|
||||
DRFixPoint<Storage::fold> fp(*rule_ders, ypart, model.getSteady(), 1.0);
|
||||
bool converged = fp.calcFixPoint(model.getSteady());
|
||||
bool converged = fp.calcFixPoint(DecisionRule::emethod::horner, model.getSteady());
|
||||
JournalRecord rec(journal);
|
||||
rec << "Fix point calcs: iter=" << fp.getNumIter()
|
||||
<< ", newton_iter=" << fp.getNewtonTotalIter()
|
||||
<< ", last_newton_iter=" << fp.getNewtonLastIter() << ".";
|
||||
rec << "Fix point calcs: iter=" << fp.getNumIter() << ", newton_iter="
|
||||
<< fp.getNewtonTotalIter() << ", last_newton_iter=" << fp.getNewtonLastIter() << ".";
|
||||
if (converged)
|
||||
rec << " Converged." << endrec;
|
||||
else
|
||||
|
@ -259,17 +237,16 @@ Approximation::walkStochSteady()
|
|||
from a temporary object and will be destroyed. */
|
||||
|
||||
void
|
||||
Approximation::saveRuleDerivs(const FGSContainer& g)
|
||||
Approximation::saveRuleDerivs(const FGSContainer &g)
|
||||
{
|
||||
rule_ders = std::make_unique<FGSContainer>(g);
|
||||
rule_ders_s = std::make_unique<FGSContainer>(4);
|
||||
rule_ders_ss = std::make_unique<FGSContainer>(4);
|
||||
for (auto& run : *rule_ders)
|
||||
for (auto &run : *rule_ders)
|
||||
{
|
||||
auto ten_s = std::make_unique<FGSTensor>(ypart.nstat, ypart.nys(), *(run.second));
|
||||
rule_ders_s->insert(std::move(ten_s));
|
||||
auto ten_ss
|
||||
= std::make_unique<FGSTensor>(ypart.nstat + ypart.npred, ypart.nyss(), *(run.second));
|
||||
auto ten_ss = std::make_unique<FGSTensor>(ypart.nstat+ypart.npred, ypart.nyss(), *(run.second));
|
||||
rule_ders_ss->insert(std::move(ten_ss));
|
||||
}
|
||||
}
|
||||
|
@ -290,37 +267,39 @@ Approximation::saveRuleDerivs(const FGSContainer& g)
|
|||
add the σᵈ/d! multiple to the result. */
|
||||
|
||||
void
|
||||
Approximation::calcStochShift(Vector& out, double at_sigma) const
|
||||
Approximation::calcStochShift(Vector &out, double at_sigma) const
|
||||
{
|
||||
KORD_RAISE_IF(out.length() != ypart.ny(),
|
||||
"Wrong length of output vector for Approximation::calcStochShift");
|
||||
out.zeros();
|
||||
|
||||
ZAuxContainer zaux(rule_ders_ss.get(), ypart.nyss(), ypart.ny(), ypart.nys(), model.nexog());
|
||||
ZAuxContainer zaux(rule_ders_ss.get(), ypart.nyss(), ypart.ny(),
|
||||
ypart.nys(), model.nexog());
|
||||
|
||||
int dfac = 1;
|
||||
for (int d = 1; d <= rule_ders->getMaxDim(); d++, dfac *= d)
|
||||
if (KOrder::is_even(d))
|
||||
{
|
||||
Symmetry sym {0, d, 0, 0};
|
||||
{
|
||||
if (KOrder::is_even(d))
|
||||
{
|
||||
Symmetry sym{0, d, 0, 0};
|
||||
|
||||
// calculate F_u′ᵈ via ZAuxContainer
|
||||
auto ten = std::make_unique<FGSTensor>(ypart.ny(), TensorDimens(sym, nvs));
|
||||
ten->zeros();
|
||||
for (int l = 1; l <= d; l++)
|
||||
{
|
||||
const FSSparseTensor& f = model.getModelDerivatives().get(Symmetry {l});
|
||||
zaux.multAndAdd(f, *ten);
|
||||
}
|
||||
// calculate F_u′ᵈ via ZAuxContainer
|
||||
auto ten = std::make_unique<FGSTensor>(ypart.ny(), TensorDimens(sym, nvs));
|
||||
ten->zeros();
|
||||
for (int l = 1; l <= d; l++)
|
||||
{
|
||||
const FSSparseTensor &f = model.getModelDerivatives().get(Symmetry{l});
|
||||
zaux.multAndAdd(f, *ten);
|
||||
}
|
||||
|
||||
// multiply with shocks and add to result
|
||||
auto tmp
|
||||
= std::make_unique<FGSTensor>(ypart.ny(), TensorDimens(Symmetry {0, 0, 0, 0}, nvs));
|
||||
tmp->zeros();
|
||||
ten->contractAndAdd(1, *tmp, mom.get(Symmetry {d}));
|
||||
// multiply with shocks and add to result
|
||||
auto tmp = std::make_unique<FGSTensor>(ypart.ny(), TensorDimens(Symmetry{0, 0, 0, 0}, nvs));
|
||||
tmp->zeros();
|
||||
ten->contractAndAdd(1, *tmp, mom.get(Symmetry{d}));
|
||||
|
||||
out.add(pow(at_sigma, d) / dfac, tmp->getData());
|
||||
}
|
||||
out.add(pow(at_sigma, d)/dfac, tmp->getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This method calculates and reports
|
||||
|
@ -344,8 +323,8 @@ Approximation::check(double at_sigma) const
|
|||
calcStochShift(stoch_shift, at_sigma);
|
||||
stoch_shift.add(1.0, system_resid);
|
||||
JournalRecord rec1(journal);
|
||||
rec1 << "Error of current approximation for shocks at sigma " << at_sigma << " is "
|
||||
<< stoch_shift.getMax() << endrec;
|
||||
rec1 << "Error of current approximation for shocks at sigma " << at_sigma
|
||||
<< " is " << stoch_shift.getMax() << endrec;
|
||||
calcStochShift(stoch_shift, 1.0);
|
||||
stoch_shift.add(1.0, system_resid);
|
||||
JournalRecord rec2(journal);
|
||||
|
@ -378,12 +357,12 @@ Approximation::check(double at_sigma) const
|
|||
TwoDMatrix
|
||||
Approximation::calcYCov() const
|
||||
{
|
||||
const TwoDMatrix& gy = rule_ders->get(Symmetry {1, 0, 0, 0});
|
||||
const TwoDMatrix& gu = rule_ders->get(Symmetry {0, 1, 0, 0});
|
||||
const TwoDMatrix &gy = rule_ders->get(Symmetry{1, 0, 0, 0});
|
||||
const TwoDMatrix &gu = rule_ders->get(Symmetry{0, 1, 0, 0});
|
||||
TwoDMatrix G(model.numeq(), model.numeq());
|
||||
G.zeros();
|
||||
G.place(gy, 0, model.nstat());
|
||||
TwoDMatrix B(const_cast<const TwoDMatrix&>(G));
|
||||
TwoDMatrix B(const_cast<const TwoDMatrix &>(G));
|
||||
B.mult(-1.0);
|
||||
TwoDMatrix C(transpose(G));
|
||||
TwoDMatrix A(model.numeq(), model.numeq());
|
||||
|
@ -393,8 +372,8 @@ Approximation::calcYCov() const
|
|||
|
||||
TwoDMatrix X((gu * model.getVcov()) * transpose(gu));
|
||||
|
||||
GeneralSylvester gs(1, model.numeq(), model.numeq(), 0, A.getData(), B.getData(), C.getData(),
|
||||
X.getData());
|
||||
GeneralSylvester gs(1, model.numeq(), model.numeq(), 0,
|
||||
A.getData(), B.getData(), C.getData(), X.getData());
|
||||
gs.solve();
|
||||
|
||||
return X;
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2021 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -61,13 +61,13 @@
|
|||
calculate also its unfolded versions, to be available for simulations
|
||||
and so on. */
|
||||
|
||||
#ifndef APPROXIMATION_HH
|
||||
#define APPROXIMATION_HH
|
||||
#ifndef APPROXIMATION_H
|
||||
#define APPROXIMATION_H
|
||||
|
||||
#include "decision_rule.hh"
|
||||
#include "dynamic_model.hh"
|
||||
#include "journal.hh"
|
||||
#include "decision_rule.hh"
|
||||
#include "korder.hh"
|
||||
#include "journal.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -87,8 +87,8 @@ class ZAuxContainer : public StackContainer<FGSTensor>, public FoldedStackContai
|
|||
public:
|
||||
using _Ctype = StackContainer<FGSTensor>::_Ctype;
|
||||
using itype = StackContainer<FGSTensor>::itype;
|
||||
ZAuxContainer(const _Ctype* gss, int ngss, int ng, int ny, int nu);
|
||||
[[nodiscard]] itype getType(int i, const Symmetry& s) const override;
|
||||
ZAuxContainer(const _Ctype *gss, int ngss, int ng, int ny, int nu);
|
||||
itype getType(int i, const Symmetry &s) const override;
|
||||
};
|
||||
|
||||
/* This class provides an interface to approximation algorithms. The core
|
||||
|
@ -119,63 +119,57 @@ public:
|
|||
|
||||
class Approximation
|
||||
{
|
||||
DynamicModel& model;
|
||||
Journal& journal;
|
||||
DynamicModel &model;
|
||||
Journal &journal;
|
||||
std::unique_ptr<FGSContainer> rule_ders;
|
||||
std::unique_ptr<FGSContainer> rule_ders_s;
|
||||
std::unique_ptr<FGSContainer> rule_ders_ss;
|
||||
std::unique_ptr<FoldDecisionRule> fdr;
|
||||
std::unique_ptr<FoldDecisionRule> fdr_pruning;
|
||||
std::unique_ptr<UnfoldDecisionRule> udr;
|
||||
std::unique_ptr<UnfoldDecisionRule> udr_pruning;
|
||||
const PartitionY ypart;
|
||||
const FNormalMoments mom;
|
||||
IntSequence nvs;
|
||||
int steps;
|
||||
bool dr_centralize;
|
||||
bool pruning;
|
||||
double qz_criterium;
|
||||
TwoDMatrix ss;
|
||||
|
||||
public:
|
||||
Approximation(DynamicModel& m, Journal& j, int ns, bool dr_centr, bool pruning, double qz_crit);
|
||||
Approximation(DynamicModel &m, Journal &j, int ns, bool dr_centr, double qz_crit);
|
||||
|
||||
[[nodiscard]] const FoldDecisionRule& getFoldDecisionRule() const;
|
||||
[[nodiscard]] const UnfoldDecisionRule& getUnfoldDecisionRulePruning() const;
|
||||
[[nodiscard]] const UnfoldDecisionRule& getUnfoldDecisionRule() const;
|
||||
[[nodiscard]] const TwoDMatrix&
|
||||
const FoldDecisionRule &getFoldDecisionRule() const;
|
||||
const UnfoldDecisionRule &getUnfoldDecisionRule() const;
|
||||
const TwoDMatrix &
|
||||
getSS() const
|
||||
{
|
||||
return ss;
|
||||
}
|
||||
[[nodiscard]] const DynamicModel&
|
||||
const DynamicModel &
|
||||
getModel() const
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
void walkStochSteady();
|
||||
[[nodiscard]] TwoDMatrix calcYCov() const;
|
||||
[[nodiscard]] const FGSContainer&
|
||||
TwoDMatrix calcYCov() const;
|
||||
const FGSContainer &
|
||||
get_rule_ders() const
|
||||
{
|
||||
return *rule_ders;
|
||||
}
|
||||
[[nodiscard]] const FGSContainer&
|
||||
const FGSContainer &
|
||||
get_rule_ders_s() const
|
||||
{
|
||||
return *rule_ders_s;
|
||||
}
|
||||
[[nodiscard]] const FGSContainer&
|
||||
const FGSContainer &
|
||||
get_rule_ders_ss() const
|
||||
{
|
||||
return *rule_ders_ss;
|
||||
}
|
||||
|
||||
protected:
|
||||
void approxAtSteady();
|
||||
void calcStochShift(Vector& out, double at_sigma) const;
|
||||
void saveRuleDerivs(const FGSContainer& g);
|
||||
void calcStochShift(Vector &out, double at_sigma) const;
|
||||
void saveRuleDerivs(const FGSContainer &g);
|
||||
void check(double at_sigma) const;
|
||||
};
|
||||
|
|
@ -0,0 +1,586 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kord_exception.hh"
|
||||
#include "decision_rule.hh"
|
||||
#include "dynamic_model.hh"
|
||||
#include "seed_generator.hh"
|
||||
|
||||
#include "SymSchurDecomp.hh"
|
||||
|
||||
#include <dynlapack.h>
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
// FoldDecisionRule conversion from UnfoldDecisionRule
|
||||
FoldDecisionRule::FoldDecisionRule(const UnfoldDecisionRule &udr)
|
||||
: DecisionRuleImpl<Storage::fold>(ctraits<Storage::fold>::Tpol(udr.nrows(), udr.nvars()),
|
||||
udr.ypart, udr.nu, udr.ysteady)
|
||||
{
|
||||
for (const auto &it : udr)
|
||||
insert(std::make_unique<ctraits<Storage::fold>::Ttensym>(*(it.second)));
|
||||
}
|
||||
|
||||
// UnfoldDecisionRule conversion from FoldDecisionRule
|
||||
UnfoldDecisionRule::UnfoldDecisionRule(const FoldDecisionRule &fdr)
|
||||
: DecisionRuleImpl<Storage::unfold>(ctraits<Storage::unfold>::Tpol(fdr.nrows(), fdr.nvars()),
|
||||
fdr.ypart, fdr.nu, fdr.ysteady)
|
||||
{
|
||||
for (const auto &it : fdr)
|
||||
insert(std::make_unique<ctraits<Storage::unfold>::Ttensym>(*(it.second)));
|
||||
}
|
||||
|
||||
/* This runs simulations with an output to journal file. Note that we
|
||||
report how many simulations had to be thrown out due to Nan or Inf. */
|
||||
|
||||
void
|
||||
SimResults::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &vcov, Journal &journal)
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Performing " << num_sim << " stochastic simulations for "
|
||||
<< num_per << " periods burning " << num_burn << " initial periods" << endrec;
|
||||
simulate(num_sim, dr, start, vcov);
|
||||
int thrown = num_sim - data.size();
|
||||
if (thrown > 0)
|
||||
{
|
||||
JournalRecord rec(journal);
|
||||
rec << "I had to throw " << thrown << " simulations away due to Nan or Inf" << endrec;
|
||||
}
|
||||
}
|
||||
|
||||
/* This runs a given number of simulations by creating
|
||||
SimulationWorker for each simulation and inserting them to the
|
||||
thread group. */
|
||||
|
||||
void
|
||||
SimResults::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &vcov)
|
||||
{
|
||||
std::vector<RandomShockRealization> rsrs;
|
||||
rsrs.reserve(num_sim);
|
||||
|
||||
sthread::detach_thread_group gr;
|
||||
for (int i = 0; i < num_sim; i++)
|
||||
{
|
||||
RandomShockRealization sr(vcov, seed_generator::get_new_seed());
|
||||
rsrs.push_back(sr);
|
||||
gr.insert(std::make_unique<SimulationWorker>(*this, dr, DecisionRule::emethod::horner,
|
||||
num_per+num_burn, start, rsrs.back()));
|
||||
}
|
||||
gr.run();
|
||||
}
|
||||
|
||||
/* This adds the data with the realized shocks. It takes only periods
|
||||
which are not to be burnt. If the data is not finite, the both data
|
||||
and shocks are thrown away. */
|
||||
|
||||
bool
|
||||
SimResults::addDataSet(const TwoDMatrix &d, const ExplicitShockRealization &sr, const ConstVector &st)
|
||||
{
|
||||
KORD_RAISE_IF(d.nrows() != num_y,
|
||||
"Incompatible number of rows for SimResults::addDataSets");
|
||||
KORD_RAISE_IF(d.ncols() != num_per+num_burn,
|
||||
"Incompatible number of cols for SimResults::addDataSets");
|
||||
bool ret = false;
|
||||
if (d.isFinite())
|
||||
{
|
||||
data.emplace_back(d, num_burn, num_per);
|
||||
shocks.emplace_back(ConstTwoDMatrix(sr.getShocks(), num_burn, num_per));
|
||||
if (num_burn == 0)
|
||||
start.emplace_back(st);
|
||||
else
|
||||
start.emplace_back(d.getCol(num_burn-1));
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
SimResults::writeMat(const std::string &base, const std::string &lname) const
|
||||
{
|
||||
std::string matfile_name = base + ".mat";
|
||||
mat_t *matfd = Mat_Create(matfile_name.c_str(), nullptr);
|
||||
if (matfd)
|
||||
{
|
||||
writeMat(matfd, lname);
|
||||
Mat_Close(matfd);
|
||||
}
|
||||
}
|
||||
|
||||
/* This save the results as matrices with given prefix and with index
|
||||
appended. If there is only one matrix, the index is not appended. */
|
||||
|
||||
void
|
||||
SimResults::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
for (int i = 0; i < getNumSets(); i++)
|
||||
{
|
||||
std::string tmp = lname + "_data";
|
||||
if (getNumSets() > 1)
|
||||
tmp += std::to_string(i+1);
|
||||
data[i].writeMat(fd, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsStats::simulate(int num_sim, const DecisionRule &dr,
|
||||
const Vector &start,
|
||||
const TwoDMatrix &vcov, Journal &journal)
|
||||
{
|
||||
SimResults::simulate(num_sim, dr, start, vcov, journal);
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating means from the simulations." << endrec;
|
||||
calcMean();
|
||||
}
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating covariances from the simulations." << endrec;
|
||||
calcVcov();
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we do not save the data itself, we save only mean and vcov. */
|
||||
void
|
||||
SimResultsStats::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
ConstTwoDMatrix(num_y, 1, mean).writeMat(fd, lname + "_mean");;
|
||||
vcov.writeMat(fd, lname + "_vcov");
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsStats::calcMean()
|
||||
{
|
||||
mean.zeros();
|
||||
if (data.size()*num_per > 0)
|
||||
{
|
||||
double mult = 1.0/data.size()/num_per;
|
||||
for (const auto &i : data)
|
||||
{
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
ConstVector col{i.getCol(j)};
|
||||
mean.add(mult, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsStats::calcVcov()
|
||||
{
|
||||
if (data.size()*num_per > 1)
|
||||
{
|
||||
vcov.zeros();
|
||||
double mult = 1.0/(data.size()*num_per - 1);
|
||||
for (const auto &d : data)
|
||||
for (int j = 0; j < num_per; j++)
|
||||
for (int m = 0; m < num_y; m++)
|
||||
for (int n = m; n < num_y; n++)
|
||||
{
|
||||
double s = (d.get(m, j)-mean[m])*(d.get(n, j)-mean[n]);
|
||||
vcov.get(m, n) += mult*s;
|
||||
if (m != n)
|
||||
vcov.get(n, m) += mult*s;
|
||||
}
|
||||
}
|
||||
else
|
||||
vcov.infs();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::simulate(int num_sim, const DecisionRule &dr,
|
||||
const Vector &start,
|
||||
const TwoDMatrix &vcov, Journal &journal)
|
||||
{
|
||||
SimResults::simulate(num_sim, dr, start, vcov, journal);
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating means of the conditional simulations." << endrec;
|
||||
calcMean();
|
||||
}
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating variances of the conditional simulations." << endrec;
|
||||
calcVariance();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
mean.writeMat(fd, lname + "_cond_mean");
|
||||
variance.writeMat(fd, lname + "_cond_variance");
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::calcMean()
|
||||
{
|
||||
mean.zeros();
|
||||
if (data.size() > 0)
|
||||
{
|
||||
double mult = 1.0/data.size();
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
Vector meanj{mean.getCol(j)};
|
||||
for (const auto &i : data)
|
||||
{
|
||||
ConstVector col{i.getCol(j)};
|
||||
meanj.add(mult, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::calcVariance()
|
||||
{
|
||||
if (data.size() > 1)
|
||||
{
|
||||
variance.zeros();
|
||||
double mult = 1.0/(data.size()-1);
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
ConstVector meanj{mean.getCol(j)};
|
||||
Vector varj{variance.getCol(j)};
|
||||
for (const auto &i : data)
|
||||
{
|
||||
Vector col{i.getCol(j)};
|
||||
col.add(-1.0, meanj);
|
||||
for (int k = 0; k < col.length(); k++)
|
||||
col[k] = col[k]*col[k];
|
||||
varj.add(mult, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
variance.infs();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::simulate(const DecisionRule &dr, Journal &journal)
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Performing " << control.getNumSets() << " IRF simulations for "
|
||||
<< num_per << " periods; shock=" << ishock << ", impulse=" << imp << endrec;
|
||||
simulate(dr);
|
||||
int thrown = control.getNumSets() - data.size();
|
||||
if (thrown > 0)
|
||||
{
|
||||
JournalRecord rec(journal);
|
||||
rec << "I had to throw " << thrown
|
||||
<< " simulations away due to Nan or Inf" << endrec;
|
||||
}
|
||||
calcMeans();
|
||||
calcVariances();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::simulate(const DecisionRule &dr)
|
||||
{
|
||||
sthread::detach_thread_group gr;
|
||||
for (int idata = 0; idata < control.getNumSets(); idata++)
|
||||
gr.insert(std::make_unique<SimulationIRFWorker>(*this, dr, DecisionRule::emethod::horner,
|
||||
num_per, idata, ishock, imp));
|
||||
gr.run();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::calcMeans()
|
||||
{
|
||||
means.zeros();
|
||||
if (data.size() > 0)
|
||||
{
|
||||
for (const auto &i : data)
|
||||
means.add(1.0, i);
|
||||
means.mult(1.0/data.size());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::calcVariances()
|
||||
{
|
||||
if (data.size() > 1)
|
||||
{
|
||||
variances.zeros();
|
||||
for (const auto &i : data)
|
||||
{
|
||||
TwoDMatrix d(i);
|
||||
d.add(-1.0, means);
|
||||
for (int j = 0; j < d.nrows(); j++)
|
||||
for (int k = 0; k < d.ncols(); k++)
|
||||
variances.get(j, k) += d.get(j, k)*d.get(j, k);
|
||||
d.mult(1.0/(data.size()-1));
|
||||
}
|
||||
}
|
||||
else
|
||||
variances.infs();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
means.writeMat(fd, lname + "_mean");
|
||||
variances.writeMat(fd, lname + "_var");
|
||||
}
|
||||
|
||||
void
|
||||
RTSimResultsStats::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &v, Journal &journal)
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Performing " << num_sim << " real-time stochastic simulations for "
|
||||
<< num_per << " periods" << endrec;
|
||||
simulate(num_sim, dr, start, v);
|
||||
mean = nc.getMean();
|
||||
mean.add(1.0, dr.getSteady());
|
||||
nc.getVariance(vcov);
|
||||
if (thrown_periods > 0)
|
||||
{
|
||||
JournalRecord rec(journal);
|
||||
rec << "I had to throw " << thrown_periods << " periods away due to Nan or Inf" << endrec;
|
||||
JournalRecord rec1(journal);
|
||||
rec1 << "This affected " << incomplete_simulations << " out of "
|
||||
<< num_sim << " simulations" << endrec;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTSimResultsStats::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &vcov)
|
||||
{
|
||||
std::vector<RandomShockRealization> rsrs;
|
||||
rsrs.reserve(num_sim);
|
||||
|
||||
sthread::detach_thread_group gr;
|
||||
for (int i = 0; i < num_sim; i++)
|
||||
{
|
||||
RandomShockRealization sr(vcov, seed_generator::get_new_seed());
|
||||
rsrs.push_back(sr);
|
||||
gr.insert(std::make_unique<RTSimulationWorker>(*this, dr, DecisionRule::emethod::horner,
|
||||
num_per, start, rsrs.back()));
|
||||
}
|
||||
gr.run();
|
||||
}
|
||||
|
||||
void
|
||||
RTSimResultsStats::writeMat(mat_t *fd, const std::string &lname)
|
||||
{
|
||||
ConstTwoDMatrix(nc.getDim(), 1, mean).writeMat(fd, lname + "_rt_mean");
|
||||
vcov.writeMat(fd, lname + "_rt_vcov");
|
||||
}
|
||||
|
||||
IRFResults::IRFResults(const DynamicModel &mod, const DecisionRule &dr,
|
||||
const SimResults &control, std::vector<int> ili,
|
||||
Journal &journal)
|
||||
: model(mod), irf_list_ind(std::move(ili))
|
||||
{
|
||||
int num_per = control.getNumPer();
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating IRFs against control for " << static_cast<int>(irf_list_ind.size()) << " shocks and for "
|
||||
<< num_per << " periods" << endrec;
|
||||
const TwoDMatrix &vcov = mod.getVcov();
|
||||
for (int ishock : irf_list_ind)
|
||||
{
|
||||
double stderror = sqrt(vcov.get(ishock, ishock));
|
||||
irf_res.emplace_back(control, model.numeq(), num_per,
|
||||
ishock, stderror);
|
||||
irf_res.emplace_back(control, model.numeq(), num_per,
|
||||
ishock, -stderror);
|
||||
}
|
||||
|
||||
for (unsigned int ii = 0; ii < irf_list_ind.size(); ii++)
|
||||
{
|
||||
irf_res[2*ii].simulate(dr, journal);
|
||||
irf_res[2*ii+1].simulate(dr, journal);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IRFResults::writeMat(mat_t *fd, const std::string &prefix) const
|
||||
{
|
||||
for (unsigned int i = 0; i < irf_list_ind.size(); i++)
|
||||
{
|
||||
int ishock = irf_list_ind[i];
|
||||
auto shockname = model.getExogNames().getName(ishock);
|
||||
irf_res[2*i].writeMat(fd, prefix + "_irfp_" + shockname);
|
||||
irf_res[2*i+1].writeMat(fd, prefix + "_irfm_" + shockname);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimulationWorker::operator()(std::mutex &mut)
|
||||
{
|
||||
ExplicitShockRealization esr(sr, np);
|
||||
TwoDMatrix m{dr.simulate(em, np, st, esr)};
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
res.addDataSet(m, esr, st);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we create a new instance of ExplicitShockRealization of the
|
||||
corresponding control, add the impulse, and simulate. */
|
||||
|
||||
void
|
||||
SimulationIRFWorker::operator()(std::mutex &mut)
|
||||
{
|
||||
ExplicitShockRealization esr(res.control.getShocks(idata));
|
||||
esr.addToShock(ishock, 0, imp);
|
||||
TwoDMatrix m{dr.simulate(em, np, res.control.getStart(idata), esr)};
|
||||
m.add(-1.0, res.control.getData(idata));
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
res.addDataSet(m, esr, res.control.getStart(idata));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTSimulationWorker::operator()(std::mutex &mut)
|
||||
{
|
||||
NormalConj nc(res.nc.getDim());
|
||||
const PartitionY &ypart = dr.getYPart();
|
||||
int nu = dr.nexog();
|
||||
const Vector &ysteady = dr.getSteady();
|
||||
|
||||
// initialize vectors and subvectors for simulation
|
||||
Vector dyu(ypart.nys()+nu);
|
||||
ConstVector ystart_pred(ystart, ypart.nstat, ypart.nys());
|
||||
ConstVector ysteady_pred(ysteady, ypart.nstat, ypart.nys());
|
||||
Vector dy(dyu, 0, ypart.nys());
|
||||
Vector u(dyu, ypart.nys(), nu);
|
||||
Vector y(nc.getDim());
|
||||
ConstVector ypred(y, ypart.nstat, ypart.nys());
|
||||
|
||||
// simulate the first real-time period
|
||||
int ip = 0;
|
||||
dy = ystart_pred;
|
||||
dy.add(-1.0, ysteady_pred);
|
||||
sr.get(ip, u);
|
||||
dr.eval(em, y, dyu);
|
||||
if (ip >= res.num_burn)
|
||||
nc.update(y);
|
||||
|
||||
// simulate other real-time periods
|
||||
while (y.isFinite() && ip < res.num_burn + res.num_per)
|
||||
{
|
||||
ip++;
|
||||
dy = ypred;
|
||||
sr.get(ip, u);
|
||||
dr.eval(em, y, dyu);
|
||||
if (ip >= res.num_burn)
|
||||
nc.update(y);
|
||||
}
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
res.nc.update(nc);
|
||||
if (res.num_per-ip > 0)
|
||||
{
|
||||
res.incomplete_simulations++;
|
||||
res.thrown_periods += res.num_per-ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This calculates factorization FFᵀ=V in the Cholesky way. It does
|
||||
not work for semidefinite matrices. */
|
||||
|
||||
void
|
||||
RandomShockRealization::choleskyFactor(const ConstTwoDMatrix &v)
|
||||
{
|
||||
factor = v;
|
||||
lapack_int rows = factor.nrows(), lda = factor.getLD();
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = i+1; j < rows; j++)
|
||||
factor.get(i, j) = 0.0;
|
||||
lapack_int info;
|
||||
|
||||
dpotrf("L", &rows, factor.base(), &lda, &info);
|
||||
KORD_RAISE_IF(info != 0,
|
||||
"Info!=0 in RandomShockRealization::choleskyFactor");
|
||||
}
|
||||
|
||||
/* This calculates FFᵀ=V factorization by symmetric Schur
|
||||
decomposition. It works for semidefinite matrices. */
|
||||
|
||||
void
|
||||
RandomShockRealization::schurFactor(const ConstTwoDMatrix &v)
|
||||
{
|
||||
SymSchurDecomp(v).getFactor(factor);
|
||||
}
|
||||
|
||||
void
|
||||
RandomShockRealization::get(int n, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(out.length() != numShocks(),
|
||||
"Wrong length of out vector in RandomShockRealization::get");
|
||||
Vector d(out.length());
|
||||
for (int i = 0; i < d.length(); i++)
|
||||
d[i] = dis(mtwister);
|
||||
out.zeros();
|
||||
factor.multaVec(out, ConstVector(d));
|
||||
}
|
||||
|
||||
ExplicitShockRealization::ExplicitShockRealization(ShockRealization &sr,
|
||||
int num_per)
|
||||
: shocks(sr.numShocks(), num_per)
|
||||
{
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
Vector jcol{shocks.getCol(j)};
|
||||
sr.get(j, jcol);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExplicitShockRealization::get(int n, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(out.length() != numShocks(),
|
||||
"Wrong length of out vector in ExplicitShockRealization::get");
|
||||
int i = n % shocks.ncols();
|
||||
ConstVector icol{shocks.getCol(i)};
|
||||
out = icol;
|
||||
}
|
||||
|
||||
void
|
||||
ExplicitShockRealization::addToShock(int ishock, int iper, double val)
|
||||
{
|
||||
KORD_RAISE_IF(ishock < 0 || ishock > numShocks(),
|
||||
"Wrong index of shock in ExplicitShockRealization::addToShock");
|
||||
int j = iper % shocks.ncols();
|
||||
shocks.get(ishock, j) += val;
|
||||
}
|
||||
|
||||
void
|
||||
GenShockRealization::get(int n, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(out.length() != numShocks(),
|
||||
"Wrong length of out vector in GenShockRealization::get");
|
||||
ExplicitShockRealization::get(n, out);
|
||||
Vector r(numShocks());
|
||||
RandomShockRealization::get(n, r);
|
||||
for (int j = 0; j < numShocks(); j++)
|
||||
if (!std::isfinite(out[j]))
|
||||
out[j] = r[j];
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dynamic_model.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
void
|
||||
NameList::print() const
|
||||
{
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
std::cout << getName(i) << '\n';
|
||||
}
|
||||
|
||||
void
|
||||
NameList::writeMat(mat_t *fd, const std::string &vname) const
|
||||
{
|
||||
int maxlen = 0;
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
maxlen = std::max(maxlen, static_cast<int>(getName(i).size()));
|
||||
|
||||
if (maxlen == 0)
|
||||
return;
|
||||
|
||||
auto m = std::make_unique<char[]>(getNum()*maxlen);
|
||||
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
for (int j = 0; j < maxlen; j++)
|
||||
if (j < static_cast<int>(getName(i).size()))
|
||||
m[j*getNum()+i] = getName(i)[j];
|
||||
else
|
||||
m[j*getNum()+i] = ' ';
|
||||
|
||||
size_t dims[2];
|
||||
dims[0] = getNum();
|
||||
dims[1] = maxlen;
|
||||
|
||||
matvar_t *v = Mat_VarCreate(vname.c_str(), MAT_C_CHAR, MAT_T_UINT8, 2, dims, m.get(), 0);
|
||||
|
||||
Mat_VarWrite(fd, v, MAT_COMPRESSION_NONE);
|
||||
|
||||
Mat_VarFree(v);
|
||||
}
|
||||
|
||||
void
|
||||
NameList::writeMatIndices(mat_t *fd, const std::string &prefix) const
|
||||
{
|
||||
TwoDMatrix aux(1, 1);
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
{
|
||||
aux.get(0, 0) = i+1;
|
||||
aux.writeMat(fd, prefix + "_i_" + getName(i));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -27,11 +27,11 @@
|
|||
|
||||
The interface is defined via pure virtual class DynamicModel. */
|
||||
|
||||
#ifndef DYNAMIC_MODEL_HH
|
||||
#define DYNAMIC_MODEL_HH
|
||||
#ifndef DYNAMIC_MODEL_H
|
||||
#define DYNAMIC_MODEL_H
|
||||
|
||||
#include "sparse_tensor.hh"
|
||||
#include "t_container.hh"
|
||||
#include "sparse_tensor.hh"
|
||||
|
||||
#include "Vector.hh"
|
||||
|
||||
|
@ -45,9 +45,11 @@ class NameList
|
|||
{
|
||||
public:
|
||||
virtual ~NameList() = default;
|
||||
[[nodiscard]] virtual int getNum() const = 0;
|
||||
[[nodiscard]] virtual const std::string& getName(int i) const = 0;
|
||||
virtual int getNum() const = 0;
|
||||
virtual const std::string &getName(int i) const = 0;
|
||||
void print() const;
|
||||
void writeMat(mat_t *fd, const std::string &vname) const;
|
||||
void writeMatIndices(mat_t *fd, const std::string &prefix) const;
|
||||
};
|
||||
|
||||
/* This is the interface to an information on a generic DSGE model. It is
|
||||
|
@ -109,34 +111,33 @@ public:
|
|||
class DynamicModel
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] virtual std::unique_ptr<DynamicModel> clone() const = 0;
|
||||
virtual std::unique_ptr<DynamicModel> clone() const = 0;
|
||||
virtual ~DynamicModel() = default;
|
||||
|
||||
[[nodiscard]] virtual int nstat() const = 0;
|
||||
[[nodiscard]] virtual int nboth() const = 0;
|
||||
[[nodiscard]] virtual int npred() const = 0;
|
||||
[[nodiscard]] virtual int nforw() const = 0;
|
||||
[[nodiscard]] virtual int nexog() const = 0;
|
||||
[[nodiscard]] virtual int order() const = 0;
|
||||
[[nodiscard]] int
|
||||
virtual int nstat() const = 0;
|
||||
virtual int nboth() const = 0;
|
||||
virtual int npred() const = 0;
|
||||
virtual int nforw() const = 0;
|
||||
virtual int nexog() const = 0;
|
||||
virtual int order() const = 0;
|
||||
int
|
||||
numeq() const
|
||||
{
|
||||
return nstat() + nboth() + npred() + nforw();
|
||||
return nstat()+nboth()+npred()+nforw();
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual const NameList& getAllEndoNames() const = 0;
|
||||
[[nodiscard]] virtual const NameList& getStateNames() const = 0;
|
||||
[[nodiscard]] virtual const NameList& getExogNames() const = 0;
|
||||
[[nodiscard]] virtual const TwoDMatrix& getVcov() const = 0;
|
||||
[[nodiscard]] virtual const TensorContainer<FSSparseTensor>& getModelDerivatives() const = 0;
|
||||
[[nodiscard]] virtual const Vector& getSteady() const = 0;
|
||||
virtual Vector& getSteady() = 0;
|
||||
virtual const NameList &getAllEndoNames() const = 0;
|
||||
virtual const NameList &getStateNames() const = 0;
|
||||
virtual const NameList &getExogNames() const = 0;
|
||||
virtual const TwoDMatrix &getVcov() const = 0;
|
||||
virtual const TensorContainer<FSSparseTensor> &getModelDerivatives() const = 0;
|
||||
virtual const Vector &getSteady() const = 0;
|
||||
virtual Vector &getSteady() = 0;
|
||||
|
||||
virtual void solveDeterministicSteady() = 0;
|
||||
virtual void evaluateSystem(Vector& out, const ConstVector& yy, const Vector& xx) = 0;
|
||||
virtual void evaluateSystem(Vector& out, const ConstVector& yym, const ConstVector& yy,
|
||||
const ConstVector& yyp, const Vector& xx)
|
||||
= 0;
|
||||
virtual void evaluateSystem(Vector &out, const ConstVector &yy, const Vector &xx) = 0;
|
||||
virtual void evaluateSystem(Vector &out, const ConstVector &yym, const ConstVector &yy,
|
||||
const ConstVector &yyp, const Vector &xx) = 0;
|
||||
virtual void calcDerivativesAtSteady() = 0;
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -27,8 +27,9 @@
|
|||
/* We take an opportunity to refine the stack container to avoid allocation of
|
||||
more memory than available. */
|
||||
void
|
||||
FaaDiBruno::calculate(const StackContainer<FGSTensor>& cont,
|
||||
const TensorContainer<FSSparseTensor>& f, FGSTensor& out)
|
||||
FaaDiBruno::calculate(const StackContainer<FGSTensor> &cont,
|
||||
const TensorContainer<FSSparseTensor> &f,
|
||||
FGSTensor &out)
|
||||
{
|
||||
out.zeros();
|
||||
for (int l = 1; l <= out.dimen(); l++)
|
||||
|
@ -46,7 +47,8 @@ FaaDiBruno::calculate(const StackContainer<FGSTensor>& cont,
|
|||
/* Here we just simply evaluate multAndAdd() for the dense container. There is
|
||||
no opportunity for tuning. */
|
||||
void
|
||||
FaaDiBruno::calculate(const FoldedStackContainer& cont, const FGSContainer& g, FGSTensor& out)
|
||||
FaaDiBruno::calculate(const FoldedStackContainer &cont, const FGSContainer &g,
|
||||
FGSTensor &out)
|
||||
{
|
||||
out.zeros();
|
||||
for (int l = 1; l <= out.dimen(); l++)
|
||||
|
@ -54,7 +56,7 @@ FaaDiBruno::calculate(const FoldedStackContainer& cont, const FGSContainer& g, F
|
|||
long int mem = SystemResources::availableMemory();
|
||||
cont.multAndAdd(l, g, out);
|
||||
JournalRecord rec(journal);
|
||||
int mem_mb = mem / 1024 / 1024;
|
||||
int mem_mb = mem/1024/1024;
|
||||
rec << "dim=" << l << " avmem=" << mem_mb << endrec;
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +65,9 @@ FaaDiBruno::calculate(const FoldedStackContainer& cont, const FGSContainer& g, F
|
|||
/* This is the same as FaaDiBruno::calculate() folded sparse code. The only
|
||||
difference is that we construct unfolded fine container. */
|
||||
void
|
||||
FaaDiBruno::calculate(const StackContainer<UGSTensor>& cont,
|
||||
const TensorContainer<FSSparseTensor>& f, UGSTensor& out)
|
||||
FaaDiBruno::calculate(const StackContainer<UGSTensor> &cont,
|
||||
const TensorContainer<FSSparseTensor> &f,
|
||||
UGSTensor &out)
|
||||
{
|
||||
out.zeros();
|
||||
for (int l = 1; l <= out.dimen(); l++)
|
||||
|
@ -81,7 +84,8 @@ FaaDiBruno::calculate(const StackContainer<UGSTensor>& cont,
|
|||
// FaaDiBruno::calculate() unfolded dense code
|
||||
/* Again, no tuning opportunity here. */
|
||||
void
|
||||
FaaDiBruno::calculate(const UnfoldedStackContainer& cont, const UGSContainer& g, UGSTensor& out)
|
||||
FaaDiBruno::calculate(const UnfoldedStackContainer &cont, const UGSContainer &g,
|
||||
UGSTensor &out)
|
||||
{
|
||||
out.zeros();
|
||||
for (int l = 1; l <= out.dimen(); l++)
|
||||
|
@ -89,7 +93,7 @@ FaaDiBruno::calculate(const UnfoldedStackContainer& cont, const UGSContainer& g,
|
|||
long int mem = SystemResources::availableMemory();
|
||||
cont.multAndAdd(l, g, out);
|
||||
JournalRecord rec(journal);
|
||||
int mem_mb = mem / 1024 / 1024;
|
||||
int mem_mb = mem/1024/1024;
|
||||
rec << "dim=" << l << " avmem=" << mem_mb << endrec;
|
||||
}
|
||||
}
|
||||
|
@ -125,21 +129,21 @@ FaaDiBruno::calculate(const UnfoldedStackContainer& cont, const UGSContainer& g,
|
|||
do something. */
|
||||
|
||||
std::tuple<int, int, int>
|
||||
FaaDiBruno::estimRefinement(const TensorDimens& tdims, int nr, int l)
|
||||
FaaDiBruno::estimRefinement(const TensorDimens &tdims, int nr, int l)
|
||||
{
|
||||
int nthreads = sthread::detach_thread_group::max_parallel_threads;
|
||||
long per_size1 = tdims.calcUnfoldMaxOffset();
|
||||
long per_size2 = static_cast<long>(std::pow(tdims.getNVS().getMax(), l));
|
||||
double lambda = 0.0;
|
||||
long per_size
|
||||
= sizeof(double) * nr * static_cast<long>(lambda * per_size1 + (1 - lambda) * per_size2);
|
||||
long per_size = sizeof(double)*nr
|
||||
*static_cast<long>(lambda*per_size1+(1-lambda)*per_size2);
|
||||
long mem = SystemResources::availableMemory();
|
||||
int max = 0;
|
||||
if (double num_cols {static_cast<double>(mem - magic_mult * nthreads * per_size) / nthreads
|
||||
/ sizeof(double) / nr};
|
||||
num_cols > 0)
|
||||
double num_cols = static_cast<double>(mem-magic_mult*nthreads*per_size)
|
||||
/nthreads/sizeof(double)/nr;
|
||||
if (num_cols > 0)
|
||||
{
|
||||
double maxd = std::pow(num_cols, 1.0 / l);
|
||||
double maxd = std::pow(num_cols, 1.0/l);
|
||||
max = static_cast<int>(std::floor(maxd));
|
||||
}
|
||||
if (max == 0)
|
||||
|
@ -151,7 +155,7 @@ FaaDiBruno::estimRefinement(const TensorDimens& tdims, int nr, int l)
|
|||
rec << " (decrease number of threads)";
|
||||
rec << endrec;
|
||||
}
|
||||
int avmem_mb = mem / 1024 / 1024;
|
||||
int tmpmem_mb = nthreads * per_size / 1024 / 1024;
|
||||
return {max, avmem_mb, tmpmem_mb};
|
||||
int avmem_mb = mem/1024/1024;
|
||||
int tmpmem_mb = nthreads*per_size/1024/1024;
|
||||
return { max, avmem_mb, tmpmem_mb };
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -29,34 +29,35 @@
|
|||
where sᵏ is a general symmetry of dimension k and z is a stack of
|
||||
functions. */
|
||||
|
||||
#ifndef FAA_DI_BRUNO_HH
|
||||
#define FAA_DI_BRUNO_HH
|
||||
#ifndef FAA_DI_BRUNO_H
|
||||
#define FAA_DI_BRUNO_H
|
||||
|
||||
#include "gs_tensor.hh"
|
||||
#include "journal.hh"
|
||||
#include "sparse_tensor.hh"
|
||||
#include "stack_container.hh"
|
||||
#include "t_container.hh"
|
||||
#include "sparse_tensor.hh"
|
||||
#include "gs_tensor.hh"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
class FaaDiBruno
|
||||
{
|
||||
Journal& journal;
|
||||
|
||||
Journal &journal;
|
||||
public:
|
||||
FaaDiBruno(Journal& jr) : journal(jr)
|
||||
FaaDiBruno(Journal &jr)
|
||||
: journal(jr)
|
||||
{
|
||||
}
|
||||
void calculate(const StackContainer<FGSTensor>& cont, const TensorContainer<FSSparseTensor>& f,
|
||||
FGSTensor& out);
|
||||
void calculate(const FoldedStackContainer& cont, const FGSContainer& g, FGSTensor& out);
|
||||
void calculate(const StackContainer<UGSTensor>& cont, const TensorContainer<FSSparseTensor>& f,
|
||||
UGSTensor& out);
|
||||
void calculate(const UnfoldedStackContainer& cont, const UGSContainer& g, UGSTensor& out);
|
||||
|
||||
void calculate(const StackContainer<FGSTensor> &cont, const TensorContainer<FSSparseTensor> &f,
|
||||
FGSTensor &out);
|
||||
void calculate(const FoldedStackContainer &cont, const FGSContainer &g,
|
||||
FGSTensor &out);
|
||||
void calculate(const StackContainer<UGSTensor> &cont, const TensorContainer<FSSparseTensor> &f,
|
||||
UGSTensor &out);
|
||||
void calculate(const UnfoldedStackContainer &cont, const UGSContainer &g,
|
||||
UGSTensor &out);
|
||||
protected:
|
||||
std::tuple<int, int, int> estimRefinement(const TensorDimens& tdims, int nr, int l);
|
||||
std::tuple<int, int, int> estimRefinement(const TensorDimens &tdims, int nr, int l);
|
||||
|
||||
// See FaaDiBruno::calculate() folded sparse code for why we have magic_mult
|
||||
constexpr static double magic_mult = 1.5;
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -18,10 +18,8 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "first_order.hh"
|
||||
#include "kord_exception.hh"
|
||||
#include "first_order.hh"
|
||||
|
||||
#include <dynlapack.h>
|
||||
|
||||
|
@ -33,10 +31,9 @@ std::mutex FirstOrder::mut;
|
|||
criterium). */
|
||||
|
||||
lapack_int
|
||||
FirstOrder::order_eigs(const double* alphar, const double* alphai, const double* beta)
|
||||
FirstOrder::order_eigs(const double *alphar, const double *alphai, const double *beta)
|
||||
{
|
||||
return (*alphar * *alphar + *alphai * *alphai
|
||||
< *beta * *beta * qz_criterium_global * qz_criterium_global);
|
||||
return (*alphar **alphar + *alphai **alphai < *beta **beta * qz_criterium_global * qz_criterium_global);
|
||||
}
|
||||
|
||||
/* Here we solve the linear approximation. The result are the matrices
|
||||
|
@ -52,7 +49,7 @@ FirstOrder::order_eigs(const double* alphar, const double* alphai, const double*
|
|||
and partitioning of the vector y (from object). */
|
||||
|
||||
void
|
||||
FirstOrder::solve(const TwoDMatrix& fd)
|
||||
FirstOrder::solve(const TwoDMatrix &fd)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Recovering first order derivatives " << endrec;
|
||||
|
@ -144,16 +141,17 @@ FirstOrder::solve(const TwoDMatrix& fd)
|
|||
ConstTwoDMatrix fymins(fd, off, ypart.nys());
|
||||
off += ypart.nys();
|
||||
ConstTwoDMatrix fuzero(fd, off, nu);
|
||||
off += nu;
|
||||
|
||||
// Form matrix D
|
||||
lapack_int n = ypart.ny() + ypart.nboth;
|
||||
lapack_int n = ypart.ny()+ypart.nboth;
|
||||
TwoDMatrix matD(n, n);
|
||||
matD.zeros();
|
||||
matD.place(fypzero, 0, 0);
|
||||
matD.place(fybzero, 0, ypart.npred);
|
||||
matD.place(fyplus, 0, ypart.nys() + ypart.nstat);
|
||||
matD.place(fyplus, 0, ypart.nys()+ypart.nstat);
|
||||
for (int i = 0; i < ypart.nboth; i++)
|
||||
matD.get(ypart.ny() + i, ypart.npred + i) = 1.0;
|
||||
matD.get(ypart.ny()+i, ypart.npred+i) = 1.0;
|
||||
lapack_int ldb = matD.getLD();
|
||||
|
||||
// Form matrix E
|
||||
|
@ -161,9 +159,9 @@ FirstOrder::solve(const TwoDMatrix& fd)
|
|||
matE.zeros();
|
||||
matE.place(fymins, 0, 0);
|
||||
matE.place(fyszero, 0, ypart.nys());
|
||||
matE.place(fyfzero, 0, ypart.nys() + ypart.nstat + ypart.nboth);
|
||||
matE.place(fyfzero, 0, ypart.nys()+ypart.nstat+ypart.nboth);
|
||||
for (int i = 0; i < ypart.nboth; i++)
|
||||
matE.get(ypart.ny() + i, ypart.nys() + ypart.nstat + i) = -1.0;
|
||||
matE.get(ypart.ny()+i, ypart.nys()+ypart.nstat+i) = -1.0;
|
||||
matE.mult(-1.0);
|
||||
lapack_int lda = matE.getLD();
|
||||
|
||||
|
@ -171,28 +169,30 @@ FirstOrder::solve(const TwoDMatrix& fd)
|
|||
TwoDMatrix vsl(n, n);
|
||||
TwoDMatrix vsr(n, n);
|
||||
lapack_int ldvsl = vsl.getLD(), ldvsr = vsr.getLD();
|
||||
lapack_int lwork = 100 * n + 16;
|
||||
lapack_int lwork = 100*n+16;
|
||||
Vector work(lwork);
|
||||
std::vector<lapack_int> bwork(n);
|
||||
auto bwork = std::make_unique<lapack_int[]>(n);
|
||||
lapack_int info;
|
||||
lapack_int sdim2 = sdim;
|
||||
{
|
||||
std::lock_guard<std::mutex> lk {mut};
|
||||
std::lock_guard<std::mutex> lk{mut};
|
||||
qz_criterium_global = qz_criterium;
|
||||
dgges("N", "V", "S", order_eigs, &n, matE.getData().base(), &lda, matD.getData().base(), &ldb,
|
||||
&sdim2, alphar.base(), alphai.base(), beta.base(), vsl.getData().base(), &ldvsl,
|
||||
vsr.getData().base(), &ldvsr, work.base(), &lwork, bwork.data(), &info);
|
||||
dgges("N", "V", "S", order_eigs, &n, matE.getData().base(), &lda,
|
||||
matD.getData().base(), &ldb, &sdim2, alphar.base(), alphai.base(),
|
||||
beta.base(), vsl.getData().base(), &ldvsl, vsr.getData().base(), &ldvsr,
|
||||
work.base(), &lwork, bwork.get(), &info);
|
||||
}
|
||||
if (info)
|
||||
throw KordException(__FILE__, __LINE__, "DGGES returns an error in FirstOrder::solve");
|
||||
throw KordException(__FILE__, __LINE__,
|
||||
"DGGES returns an error in FirstOrder::solve");
|
||||
sdim = sdim2;
|
||||
bk_cond = (sdim == ypart.nys());
|
||||
|
||||
// Setup submatrices of Z
|
||||
ConstGeneralMatrix z11(vsr, 0, 0, ypart.nys(), ypart.nys());
|
||||
ConstGeneralMatrix z12(vsr, 0, ypart.nys(), ypart.nys(), n - ypart.nys());
|
||||
ConstGeneralMatrix z21(vsr, ypart.nys(), 0, n - ypart.nys(), ypart.nys());
|
||||
ConstGeneralMatrix z22(vsr, ypart.nys(), ypart.nys(), n - ypart.nys(), n - ypart.nys());
|
||||
ConstGeneralMatrix z12(vsr, 0, ypart.nys(), ypart.nys(), n-ypart.nys());
|
||||
ConstGeneralMatrix z21(vsr, ypart.nys(), 0, n-ypart.nys(), ypart.nys());
|
||||
ConstGeneralMatrix z22(vsr, ypart.nys(), ypart.nys(), n-ypart.nys(), n-ypart.nys());
|
||||
|
||||
// Calculate derivatives of static and forward
|
||||
/* Here we calculate X=−Z₂₂⁻ᵀZ₁₂ᵀ, where X is ‘sfder’ in the code. */
|
||||
|
@ -214,12 +214,11 @@ FirstOrder::solve(const TwoDMatrix& fd)
|
|||
gy.place(preder, ypart.nstat, 0);
|
||||
GeneralMatrix sder(sfder, 0, 0, ypart.nstat, ypart.nys());
|
||||
gy.place(sder, 0, 0);
|
||||
GeneralMatrix fder(sfder, ypart.nstat + ypart.nboth, 0, ypart.nforw, ypart.nys());
|
||||
gy.place(fder, ypart.nstat + ypart.nys(), 0);
|
||||
GeneralMatrix fder(sfder, ypart.nstat+ypart.nboth, 0, ypart.nforw, ypart.nys());
|
||||
gy.place(fder, ypart.nstat+ypart.nys(), 0);
|
||||
|
||||
// Check difference for derivatives of both
|
||||
GeneralMatrix bder(const_cast<const GeneralMatrix&>(sfder), ypart.nstat, 0, ypart.nboth,
|
||||
ypart.nys());
|
||||
GeneralMatrix bder(const_cast<const GeneralMatrix &>(sfder), ypart.nstat, 0, ypart.nboth, ypart.nys());
|
||||
GeneralMatrix bder2(preder, ypart.npred, 0, ypart.nboth, ypart.nys());
|
||||
bder.add(-1, bder2);
|
||||
b_error = bder.getData().getMax();
|
||||
|
@ -238,7 +237,7 @@ FirstOrder::solve(const TwoDMatrix& fd)
|
|||
is ‘matA’ in the code. */
|
||||
GeneralMatrix matA(ypart.ny(), ypart.ny());
|
||||
matA.zeros();
|
||||
ConstGeneralMatrix gss(gy, ypart.nstat + ypart.npred, 0, ypart.nyss(), ypart.nys());
|
||||
ConstGeneralMatrix gss(gy, ypart.nstat+ypart.npred, 0, ypart.nyss(), ypart.nys());
|
||||
matA.place(fyplus * gss, 0, ypart.nstat);
|
||||
ConstGeneralMatrix fyzero(fd, 0, ypart.nyss(), ypart.ny(), ypart.ny());
|
||||
matA.add(1.0, fyzero);
|
||||
|
@ -248,7 +247,9 @@ FirstOrder::solve(const TwoDMatrix& fd)
|
|||
|
||||
journalEigs();
|
||||
|
||||
KORD_RAISE_IF_X(!bk_cond, "The model is not Blanchard-Kahn stable", KORD_MD_NOT_STABLE);
|
||||
KORD_RAISE_IF_X(!bk_cond,
|
||||
"The model is not Blanchard-Kahn stable",
|
||||
KORD_MD_NOT_STABLE);
|
||||
if (!gy.isFinite() || !gu.isFinite())
|
||||
throw KordException(__FILE__, __LINE__,
|
||||
"NaN or Inf asserted in first order derivatives in FirstOrder::solve()");
|
||||
|
@ -282,9 +283,9 @@ FirstOrder::journalEigs()
|
|||
jr << endrec;
|
||||
}
|
||||
JournalRecord jr(journal);
|
||||
double mod = std::sqrt(alphar[i] * alphar[i] + alphai[i] * alphai[i]);
|
||||
mod = mod / std::round(100000 * std::abs(beta[i])) * 100000;
|
||||
jr << i << "\t(" << alphar[i] << "," << alphai[i] << ") / " << beta[i] << " \t" << mod
|
||||
<< endrec;
|
||||
double mod = std::sqrt(alphar[i]*alphar[i]+alphai[i]*alphai[i]);
|
||||
mod = mod/std::round(100000*std::abs(beta[i]))*100000;
|
||||
jr << i << "\t(" << alphar[i] << "," << alphai[i] << ") / " << beta[i]
|
||||
<< " \t" << mod << endrec;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -20,8 +20,8 @@
|
|||
|
||||
// First order at deterministic steady state
|
||||
|
||||
#ifndef FIRST_ORDER_HH
|
||||
#define FIRST_ORDER_HH
|
||||
#ifndef FIRST_ORDER_H
|
||||
#define FIRST_ORDER_H
|
||||
|
||||
#include "korder.hh"
|
||||
|
||||
|
@ -44,10 +44,10 @@ class FirstOrder
|
|||
Vector alphai;
|
||||
Vector beta;
|
||||
double qz_criterium;
|
||||
Journal& journal;
|
||||
Journal &journal;
|
||||
|
||||
// Passed to LAPACK's DGGES
|
||||
static lapack_int order_eigs(const double* alphar, const double* alphai, const double* beta);
|
||||
static lapack_int order_eigs(const double *alphar, const double *alphai, const double *beta);
|
||||
|
||||
// The value of qz_criterium_global used by the order_eigs function
|
||||
/* NB: we have no choice but to use a global variable, since LAPACK won't
|
||||
|
@ -56,35 +56,33 @@ class FirstOrder
|
|||
|
||||
// Protects the static qz_criterium_global
|
||||
static std::mutex mut;
|
||||
|
||||
public:
|
||||
FirstOrder(int num_stat, int num_pred, int num_both, int num_forw, int num_u,
|
||||
const FSSparseTensor& f, Journal& jr, double qz_crit) :
|
||||
ypart(num_stat, num_pred, num_both, num_forw),
|
||||
FirstOrder(int num_stat, int num_pred, int num_both, int num_forw,
|
||||
int num_u, const FSSparseTensor &f, Journal &jr, double qz_crit)
|
||||
: ypart(num_stat, num_pred, num_both, num_forw),
|
||||
nu(num_u),
|
||||
gy(ypart.ny(), ypart.nys()),
|
||||
gu(ypart.ny(), nu),
|
||||
alphar(ypart.ny() + ypart.nboth),
|
||||
alphai(ypart.ny() + ypart.nboth),
|
||||
beta(ypart.ny() + ypart.nboth),
|
||||
alphar(ypart.ny()+ypart.nboth),
|
||||
alphai(ypart.ny()+ypart.nboth),
|
||||
beta(ypart.ny()+ypart.nboth),
|
||||
qz_criterium(qz_crit),
|
||||
journal(jr)
|
||||
{
|
||||
solve(FFSTensor(f));
|
||||
}
|
||||
[[nodiscard]] const TwoDMatrix&
|
||||
const TwoDMatrix &
|
||||
getGy() const
|
||||
{
|
||||
return gy;
|
||||
}
|
||||
[[nodiscard]] const TwoDMatrix&
|
||||
const TwoDMatrix &
|
||||
getGu() const
|
||||
{
|
||||
return gu;
|
||||
}
|
||||
|
||||
protected:
|
||||
void solve(const TwoDMatrix& f);
|
||||
void solve(const TwoDMatrix &f);
|
||||
void journalEigs();
|
||||
};
|
||||
|
||||
|
@ -95,16 +93,15 @@ template<Storage t>
|
|||
class FirstOrderDerivs : public ctraits<t>::Tg
|
||||
{
|
||||
public:
|
||||
FirstOrderDerivs(const FirstOrder& fo) : ctraits<t>::Tg(4)
|
||||
FirstOrderDerivs(const FirstOrder &fo)
|
||||
: ctraits<t>::Tg(4)
|
||||
{
|
||||
IntSequence nvs {fo.ypart.nys(), fo.nu, fo.nu, 1};
|
||||
auto ten = std::make_unique<typename ctraits<t>::Ttensor>(
|
||||
fo.ypart.ny(), TensorDimens(Symmetry {1, 0, 0, 0}, nvs));
|
||||
IntSequence nvs{fo.ypart.nys(), fo.nu, fo.nu, 1};
|
||||
auto ten = std::make_unique<typename ctraits<t>::Ttensor>(fo.ypart.ny(), TensorDimens(Symmetry{1, 0, 0, 0}, nvs));
|
||||
ten->zeros();
|
||||
ten->add(1.0, fo.gy);
|
||||
this->insert(std::move(ten));
|
||||
ten = std::make_unique<typename ctraits<t>::Ttensor>(fo.ypart.ny(),
|
||||
TensorDimens(Symmetry {0, 1, 0, 0}, nvs));
|
||||
ten = std::make_unique<typename ctraits<t>::Ttensor>(fo.ypart.ny(), TensorDimens(Symmetry{0, 1, 0, 0}, nvs));
|
||||
ten->zeros();
|
||||
ten->add(1.0, fo.gu);
|
||||
this->insert(std::move(ten));
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SymSchurDecomp.hh"
|
||||
|
||||
#include "global_check.hh"
|
||||
#include "seed_generator.hh"
|
||||
|
||||
#include "smolyak.hh"
|
||||
#include "product.hh"
|
||||
#include "quasi_mcarlo.hh"
|
||||
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
|
||||
/* Here we just set a reference to the approximation, and create a new
|
||||
DynamicModel. */
|
||||
|
||||
ResidFunction::ResidFunction(const Approximation &app)
|
||||
: VectorFunction(app.getModel().nexog(), app.getModel().numeq()), approx(app),
|
||||
model(app.getModel().clone())
|
||||
{
|
||||
}
|
||||
|
||||
ResidFunction::ResidFunction(const ResidFunction &rf)
|
||||
: VectorFunction(rf), approx(rf.approx), model(rf.model->clone())
|
||||
{
|
||||
if (rf.yplus)
|
||||
yplus = std::make_unique<Vector>(*(rf.yplus));
|
||||
if (rf.ystar)
|
||||
ystar = std::make_unique<Vector>(*(rf.ystar));
|
||||
if (rf.u)
|
||||
u = std::make_unique<Vector>(*(rf.u));
|
||||
if (rf.hss)
|
||||
hss = std::make_unique<FTensorPolynomial>(*(rf.hss));
|
||||
}
|
||||
|
||||
/* This sets y* and u. We have to create ‘ystar’, ‘u’, ‘yplus’ and ‘hss’. */
|
||||
|
||||
void
|
||||
ResidFunction::setYU(const ConstVector &ys, const ConstVector &xx)
|
||||
{
|
||||
ystar = std::make_unique<Vector>(ys);
|
||||
u = std::make_unique<Vector>(xx);
|
||||
yplus = std::make_unique<Vector>(model->numeq());
|
||||
approx.getFoldDecisionRule().evaluate(DecisionRule::emethod::horner,
|
||||
*yplus, *ystar, *u);
|
||||
|
||||
// make a tensor polynomial of in-place subtensors from decision rule
|
||||
/* Note that the non-const polynomial will be used for a construction of
|
||||
‘hss’ and will be used in a const context. So this const cast is safe.
|
||||
|
||||
Note, that there is always a folded decision rule in Approximation. */
|
||||
const FoldDecisionRule &dr = approx.getFoldDecisionRule();
|
||||
FTensorPolynomial dr_ss(model->nstat()+model->npred(), model->nboth()+model->nforw(),
|
||||
const_cast<FoldDecisionRule &>(dr));
|
||||
|
||||
// make ‘ytmp_star’ be a difference of ‘yplus’ from steady
|
||||
Vector ytmp_star(ConstVector(*yplus, model->nstat(), model->npred()+model->nboth()));
|
||||
ConstVector ysteady_star(dr.getSteady(), model->nstat(),
|
||||
model->npred()+model->nboth());
|
||||
ytmp_star.add(-1.0, ysteady_star);
|
||||
|
||||
// make ‘hss’ and add steady to it
|
||||
/* Here is the const context of ‘dr_ss’. */
|
||||
hss = std::make_unique<FTensorPolynomial>(dr_ss, ytmp_star);
|
||||
ConstVector ysteady_ss(dr.getSteady(), model->nstat()+model->npred(),
|
||||
model->nboth()+model->nforw());
|
||||
if (hss->check(Symmetry{0}))
|
||||
hss->get(Symmetry{0}).getData().add(1.0, ysteady_ss);
|
||||
else
|
||||
{
|
||||
auto ten = std::make_unique<FFSTensor>(hss->nrows(), hss->nvars(), 0);
|
||||
ten->getData() = ysteady_ss;
|
||||
hss->insert(std::move(ten));
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we evaluate the residual F(y*,u,u′). We have to evaluate ‘hss’ for
|
||||
u′=point and then we evaluate the system f. */
|
||||
|
||||
void
|
||||
ResidFunction::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(point.length() != hss->nvars(),
|
||||
"Wrong dimension of input vector in ResidFunction::eval");
|
||||
KORD_RAISE_IF(out.length() != model->numeq(),
|
||||
"Wrong dimension of output vector in ResidFunction::eval");
|
||||
Vector yss(hss->nrows());
|
||||
hss->evalHorner(yss, point);
|
||||
model->evaluateSystem(out, *ystar, *yplus, yss, *u);
|
||||
}
|
||||
|
||||
/* This checks the 𝔼[F(y*,u,u′)] for a given y* and u by integrating with a
|
||||
given quadrature. Note that the input ‘ys’ is y* not whole y. */
|
||||
|
||||
void
|
||||
GlobalChecker::check(const Quadrature &quad, int level,
|
||||
const ConstVector &ys, const ConstVector &x, Vector &out)
|
||||
{
|
||||
for (int ifunc = 0; ifunc < vfs.getNum(); ifunc++)
|
||||
dynamic_cast<GResidFunction &>(vfs.getFunc(ifunc)).setYU(ys, x);
|
||||
quad.integrate(vfs, level, out);
|
||||
}
|
||||
|
||||
/* This method is a bulk version of GlobalChecker::check() vector code. It
|
||||
decides between Smolyak and product quadrature according to ‘max_evals’
|
||||
constraint.
|
||||
|
||||
Note that ‘y’ can be either full (all endogenous variables including static
|
||||
and forward looking), or just y* (state variables). The method is able to
|
||||
recognize it. */
|
||||
|
||||
void
|
||||
GlobalChecker::check(int max_evals, const ConstTwoDMatrix &y,
|
||||
const ConstTwoDMatrix &x, TwoDMatrix &out)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Checking approximation error for " << y.ncols()
|
||||
<< " states with at most " << max_evals << " evaluations" << endrec;
|
||||
|
||||
// Decide about which type of quadrature
|
||||
GaussHermite gh;
|
||||
|
||||
SmolyakQuadrature dummy_sq(model.nexog(), 1, gh);
|
||||
int smol_evals;
|
||||
int smol_level;
|
||||
dummy_sq.designLevelForEvals(max_evals, smol_level, smol_evals);
|
||||
|
||||
ProductQuadrature dummy_pq(model.nexog(), gh);
|
||||
int prod_evals;
|
||||
int prod_level;
|
||||
dummy_pq.designLevelForEvals(max_evals, prod_level, prod_evals);
|
||||
|
||||
bool take_smolyak = (smol_evals < prod_evals) && (smol_level >= prod_level-1);
|
||||
|
||||
std::unique_ptr<Quadrature> quad;
|
||||
int lev;
|
||||
|
||||
// Create the quadrature and report the decision
|
||||
if (take_smolyak)
|
||||
{
|
||||
quad = std::make_unique<SmolyakQuadrature>(model.nexog(), smol_level, gh);
|
||||
lev = smol_level;
|
||||
JournalRecord rec(journal);
|
||||
rec << "Selected Smolyak (level,evals)=(" << smol_level << ","
|
||||
<< smol_evals << ") over product (" << prod_level << ","
|
||||
<< prod_evals << ")" << endrec;
|
||||
}
|
||||
else
|
||||
{
|
||||
quad = std::make_unique<ProductQuadrature>(model.nexog(), gh);
|
||||
lev = prod_level;
|
||||
JournalRecord rec(journal);
|
||||
rec << "Selected product (level,evals)=(" << prod_level << ","
|
||||
<< prod_evals << ") over Smolyak (" << smol_level << ","
|
||||
<< smol_evals << ")" << endrec;
|
||||
}
|
||||
|
||||
// Check all columns of ‘y’ and ‘x’
|
||||
int first_row = (y.nrows() == model.numeq()) ? model.nstat() : 0;
|
||||
ConstTwoDMatrix ysmat(y, first_row, 0, model.npred()+model.nboth(), y.ncols());
|
||||
for (int j = 0; j < y.ncols(); j++)
|
||||
{
|
||||
ConstVector yj{ysmat.getCol(j)};
|
||||
ConstVector xj{x.getCol(j)};
|
||||
Vector outj{out.getCol(j)};
|
||||
check(*quad, lev, yj, xj, outj);
|
||||
}
|
||||
}
|
||||
|
||||
/* This method checks an error of the approximation by evaluating residual
|
||||
𝔼[F(y*,u,u′) | y*,u] for y* equal to the steady state, and changing u. We go
|
||||
through all elements of u and vary them from −mult·σ to mult·σ in ‘m’
|
||||
steps. */
|
||||
|
||||
void
|
||||
GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating errors along shocks +/- "
|
||||
<< mult << " std errors, granularity " << m << endrec;
|
||||
|
||||
// Setup ‘y_mat’ of steady states for checking
|
||||
TwoDMatrix y_mat(model.numeq(), 2*m*model.nexog()+1);
|
||||
for (int j = 0; j < 2*m*model.nexog()+1; j++)
|
||||
{
|
||||
Vector yj{y_mat.getCol(j)};
|
||||
yj = model.getSteady();
|
||||
}
|
||||
|
||||
// Setup ‘exo_mat’ for checking
|
||||
TwoDMatrix exo_mat(model.nexog(), 2*m*model.nexog()+1);
|
||||
exo_mat.zeros();
|
||||
for (int ishock = 0; ishock < model.nexog(); ishock++)
|
||||
{
|
||||
double max_sigma = sqrt(model.getVcov().get(ishock, ishock));
|
||||
for (int j = 0; j < 2*m; j++)
|
||||
{
|
||||
int jmult = (j < m) ? j-m : j-m+1;
|
||||
exo_mat.get(ishock, 1+2*m*ishock+j) = mult*jmult*max_sigma/m;
|
||||
}
|
||||
}
|
||||
|
||||
TwoDMatrix errors(model.numeq(), 2*m*model.nexog()+1);
|
||||
check(max_evals, y_mat, exo_mat, errors);
|
||||
|
||||
// Report errors along shock and save them
|
||||
TwoDMatrix res(model.nexog(), 2*m+1);
|
||||
JournalRecord rec(journal);
|
||||
rec << "Shock value error" << endrec;
|
||||
ConstVector err0{errors.getCol(0)};
|
||||
for (int ishock = 0; ishock < model.nexog(); ishock++)
|
||||
{
|
||||
TwoDMatrix err_out(model.numeq(), 2*m+1);
|
||||
for (int j = 0; j < 2*m+1; j++)
|
||||
{
|
||||
int jj;
|
||||
Vector error{err_out.getCol(j)};
|
||||
if (j != m)
|
||||
{
|
||||
if (j < m)
|
||||
jj = 1 + 2*m*ishock+j;
|
||||
else
|
||||
jj = 1 + 2*m*ishock+j-1;
|
||||
ConstVector coljj{errors.getCol(jj)};
|
||||
error = coljj;
|
||||
}
|
||||
else
|
||||
{
|
||||
jj = 0;
|
||||
error = err0;
|
||||
}
|
||||
JournalRecord rec1(journal);
|
||||
std::string shockname{model.getExogNames().getName(ishock)};
|
||||
shockname.resize(8, ' ');
|
||||
rec1 << shockname << ' ' << exo_mat.get(ishock, jj)
|
||||
<< "\t" << error.getMax() << endrec;
|
||||
}
|
||||
err_out.writeMat(fd, prefix + "_shock_" + model.getExogNames().getName(ishock) + "_errors");
|
||||
}
|
||||
}
|
||||
|
||||
/* This method checks errors on ellipse of endogenous states (predetermined
|
||||
variables). The ellipse is shaped according to covariance matrix of
|
||||
endogenous variables based on the first order approximation and scaled by
|
||||
‘mult’. The points on the ellipse are chosen as polar images of the low
|
||||
discrepancy grid in a cube.
|
||||
|
||||
The method works as follows. First we calculate symmetric Schur factor of
|
||||
covariance matrix of the states. Second we generate low discrepancy points
|
||||
on the unit sphere. Third we transform the sphere with the
|
||||
variance-covariance matrix factor and multiplier ‘mult’ and initialize
|
||||
matrix of uₜ to zeros. Fourth we run the check() method and save the
|
||||
results. */
|
||||
|
||||
void
|
||||
GlobalChecker::checkOnEllipseAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating errors at " << m
|
||||
<< " ellipse points scaled by " << mult << endrec;
|
||||
|
||||
// Make factor of covariance of variables
|
||||
/* Here we set ‘ycovfac’ to the symmetric Schur decomposition factor of a
|
||||
submatrix of covariances of all endogenous variables. The submatrix
|
||||
corresponds to state variables (predetermined plus both). */
|
||||
TwoDMatrix ycov{approx.calcYCov()};
|
||||
TwoDMatrix ycovpred(const_cast<const TwoDMatrix &>(ycov), model.nstat(), model.nstat(),
|
||||
model.npred()+model.nboth(), model.npred()+model.nboth());
|
||||
SymSchurDecomp ssd(ycovpred);
|
||||
ssd.correctDefinitness(1.e-05);
|
||||
TwoDMatrix ycovfac(ycovpred.nrows(), ycovpred.ncols());
|
||||
KORD_RAISE_IF(!ssd.isPositiveSemidefinite(),
|
||||
"Covariance matrix of the states not positive \
|
||||
semidefinite in GlobalChecker::checkOnEllipseAndSave");
|
||||
ssd.getFactor(ycovfac);
|
||||
|
||||
// Put low discrepancy sphere points to ‘ymat’
|
||||
/* Here we first calculate dimension ‘d’ of the sphere, which is a number of
|
||||
state variables minus one. We go through the ‘d’-dimensional cube [0,1]ᵈ
|
||||
by QMCarloCubeQuadrature and make a polar transformation to the sphere.
|
||||
The polar transformation fⁱ can be written recursively w.r.t. the
|
||||
dimension i as:
|
||||
|
||||
f⁰() = [1]
|
||||
|
||||
⎡cos(2πxᵢ)·fⁱ⁻¹(x₁,…,xᵢ₋₁)⎤
|
||||
fⁱ(x₁,…,xᵢ) = ⎣ sin(2πxᵢ) ⎦
|
||||
*/
|
||||
int d = model.npred()+model.nboth()-1;
|
||||
TwoDMatrix ymat(model.npred()+model.nboth(), (d == 0) ? 2 : m);
|
||||
if (d == 0)
|
||||
{
|
||||
ymat.get(0, 0) = 1;
|
||||
ymat.get(0, 1) = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int icol = 0;
|
||||
ReversePerScheme ps;
|
||||
QMCarloCubeQuadrature qmc(d, m, ps);
|
||||
qmcpit beg = qmc.start(m);
|
||||
qmcpit end = qmc.end(m);
|
||||
for (qmcpit run = beg; run != end; ++run, icol++)
|
||||
{
|
||||
Vector ycol{ymat.getCol(icol)};
|
||||
Vector x(run.point());
|
||||
x.mult(2*M_PI);
|
||||
ycol[0] = 1;
|
||||
for (int i = 0; i < d; i++)
|
||||
{
|
||||
Vector subsphere(ycol, 0, i+1);
|
||||
subsphere.mult(cos(x[i]));
|
||||
ycol[i+1] = sin(x[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform sphere ‘ymat’ and prepare ‘umat’ for checking
|
||||
/* Here we multiply the sphere points in ‘ymat’ with the Cholesky factor to
|
||||
obtain the ellipse, scale the ellipse by the given ‘mult’, and initialize
|
||||
matrix of shocks ‘umat’ to zero. */
|
||||
TwoDMatrix umat(model.nexog(), ymat.ncols());
|
||||
umat.zeros();
|
||||
ymat.mult(mult);
|
||||
ymat.multLeft(ycovfac);
|
||||
ConstVector ys(model.getSteady(), model.nstat(),
|
||||
model.npred()+model.nboth());
|
||||
for (int icol = 0; icol < ymat.ncols(); icol++)
|
||||
{
|
||||
Vector ycol{ymat.getCol(icol)};
|
||||
ycol.add(1.0, ys);
|
||||
}
|
||||
|
||||
// Check on ellipse and save
|
||||
/* Here we check the points and save the results to MAT-4 file. */
|
||||
TwoDMatrix out(model.numeq(), ymat.ncols());
|
||||
check(max_evals, ymat, umat, out);
|
||||
|
||||
ymat.writeMat(fd, prefix + "_ellipse_points");
|
||||
out.writeMat(fd, prefix + "_ellipse_errors");
|
||||
}
|
||||
|
||||
/* Here we check the errors along a simulation. We simulate, then set ‘x’ to
|
||||
zeros, check and save results. */
|
||||
|
||||
void
|
||||
GlobalChecker::checkAlongSimulationAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, int max_evals)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating errors at " << m
|
||||
<< " simulated points" << endrec;
|
||||
RandomShockRealization sr(model.getVcov(), seed_generator::get_new_seed());
|
||||
TwoDMatrix y{approx.getFoldDecisionRule().simulate(DecisionRule::emethod::horner,
|
||||
m, model.getSteady(), sr)};
|
||||
TwoDMatrix x(model.nexog(), m);
|
||||
x.zeros();
|
||||
TwoDMatrix out(model.numeq(), m);
|
||||
check(max_evals, y, x, out);
|
||||
|
||||
y.writeMat(fd, prefix + "_simul_points");
|
||||
out.writeMat(fd, prefix + "_simul_errors");
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Global check
|
||||
|
||||
/* The purpose of this file is to provide classes for checking error of
|
||||
approximation. If yₜ=g(y*ₜ₋₁,u) is an approximate solution, then we check
|
||||
for the error of residuals of the system equations. Let
|
||||
F(y*,u,u′)=f(g**(g*(y*,u′),u),g(y*,u),y*,u), then we calculate the integral:
|
||||
|
||||
𝔼ₜ[F(y*,u,u′)]
|
||||
|
||||
which we want to be zero for all y* and u.
|
||||
|
||||
There are a few possibilities how and where the integral is evaluated.
|
||||
Currently we offer the following ones:
|
||||
|
||||
— Along shocks. The y* is set to the steady state, and u is set to zero but
|
||||
one element is going from minus through plus shocks in few steps. The user
|
||||
gives the scaling factor, for instance the interval [−3σ,3σ] (where σ is
|
||||
one standard error of the shock), and a number of steps. This is repeated
|
||||
for each shock (element of the u vector).
|
||||
|
||||
— Along simulation. Some random simulation is run, and for each realization
|
||||
of y* and u along the path we evaluate the residual.
|
||||
|
||||
— On ellipse. Let V=AAᵀ be a covariance matrix of the predetermined
|
||||
variables y* based on linear approximation, then we calculate integral for
|
||||
points on the ellipse { Ax | ‖x‖₂=1 }. The points are selected by means of
|
||||
low discrepancy method and polar transformation. The shock u are zeros.
|
||||
|
||||
— Unconditional distribution.
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_CHECK_H
|
||||
#define GLOBAL_CHECK_H
|
||||
|
||||
#include <matio.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
|
||||
#include "dynamic_model.hh"
|
||||
#include "journal.hh"
|
||||
#include "approximation.hh"
|
||||
|
||||
/* This is a class for implementing the VectorFunction interface evaluating the
|
||||
residual of equations, this is F(y*,u,u′)=f(g**(g*(y*,u),u′),y*,u) is
|
||||
written as a function of u′.
|
||||
|
||||
When the object is constructed, one has to specify (y*,u), this is done by
|
||||
the setYU() method. The object has basically two states. One is after
|
||||
construction and before the call to setYU(). The second is after the call to
|
||||
setYU(). We distinguish between the two states, an object in the second
|
||||
state contains ‘yplus’, ‘ystar’, ‘u’, and ‘hss’.
|
||||
|
||||
The vector ‘yplus’ is g*(y*,u). ‘ystar’ is y*, and polynomial ‘hss’ is
|
||||
partially evaluated g**(yplus, u).
|
||||
|
||||
The pointer to DynamicModel is important, since the DynamicModel evaluates
|
||||
the function f. When copying the object, we have to make also a copy of
|
||||
DynamicModel. */
|
||||
|
||||
class ResidFunction : public VectorFunction
|
||||
{
|
||||
protected:
|
||||
const Approximation ≈
|
||||
std::unique_ptr<DynamicModel> model;
|
||||
std::unique_ptr<Vector> yplus, ystar, u;
|
||||
std::unique_ptr<FTensorPolynomial> hss;
|
||||
public:
|
||||
ResidFunction(const Approximation &app);
|
||||
ResidFunction(const ResidFunction &rf);
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<ResidFunction>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
void setYU(const ConstVector &ys, const ConstVector &xx);
|
||||
};
|
||||
|
||||
/* This is a ResidFunction wrapped with GaussConverterFunction. */
|
||||
|
||||
class GResidFunction : public GaussConverterFunction
|
||||
{
|
||||
public:
|
||||
GResidFunction(const Approximation &app)
|
||||
: GaussConverterFunction(std::make_unique<ResidFunction>(app), app.getModel().getVcov())
|
||||
{
|
||||
}
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<GResidFunction>(*this);
|
||||
}
|
||||
void
|
||||
setYU(const ConstVector &ys, const ConstVector &xx)
|
||||
{
|
||||
dynamic_cast<ResidFunction *>(func)->setYU(ys, xx);
|
||||
}
|
||||
};
|
||||
|
||||
/* This is a class encapsulating checking algorithms. Its core routine is
|
||||
check(), which calculates integral 𝔼[F(y*,u,u′) | y*,u] for given
|
||||
realizations of y* and u. The both are given in matrices. The methods
|
||||
checking along shocks, on ellipse and anlong a simulation path, just fill
|
||||
the matrices and call the core check().
|
||||
|
||||
The method checkUnconditionalAndSave() evaluates unconditional 𝔼[F(y,u,u′)].
|
||||
|
||||
The object also maintains a set of GResidFunction functions ‘vfs’ in order
|
||||
to save (possibly expensive) copying of DynamicModel’s. */
|
||||
|
||||
class GlobalChecker
|
||||
{
|
||||
const Approximation ≈
|
||||
const DynamicModel &model;
|
||||
Journal &journal;
|
||||
GResidFunction rf;
|
||||
VectorFunctionSet vfs;
|
||||
public:
|
||||
GlobalChecker(const Approximation &app, int n, Journal &jr)
|
||||
: approx(app), model(approx.getModel()), journal(jr),
|
||||
rf(approx), vfs(rf, n)
|
||||
{
|
||||
}
|
||||
void check(int max_evals, const ConstTwoDMatrix &y,
|
||||
const ConstTwoDMatrix &x, TwoDMatrix &out);
|
||||
void checkAlongShocksAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals);
|
||||
void checkOnEllipseAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals);
|
||||
void checkAlongSimulationAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, int max_evals);
|
||||
void checkUnconditionalAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, int max_evals);
|
||||
protected:
|
||||
void check(const Quadrature &quad, int level,
|
||||
const ConstVector &y, const ConstVector &x, Vector &out);
|
||||
};
|
||||
|
||||
/* Signalled resid function. Not implemented yet. todo: */
|
||||
|
||||
class ResidFunctionSig : public ResidFunction
|
||||
{
|
||||
public:
|
||||
ResidFunctionSig(const Approximation &app, const Vector &ys, const Vector &xx);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004-2011 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -21,31 +21,30 @@
|
|||
#include "journal.hh"
|
||||
#include "kord_exception.hh"
|
||||
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <thread>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <cstdlib> // For getloadavg()
|
||||
# include <sys/resource.h> // For getrusage()
|
||||
# include <sys/time.h> // For getrusage()
|
||||
# include <sys/resource.h> // For getrusage()
|
||||
# include <sys/utsname.h> // For uname()
|
||||
# include <cstdlib> // For getloadavg()
|
||||
# include <unistd.h> // For sysconf()
|
||||
# ifdef __APPLE__
|
||||
# include <sys/sysctl.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# endif
|
||||
#else
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX // Do not define "min" and "max" macros
|
||||
# define NOMINMAX // Do not define "min" and "max" macros
|
||||
# endif
|
||||
# include <windows.h> // For GlobalMemoryStatus()
|
||||
# include <windows.h> // For GlobalMemoryStatus()
|
||||
#endif
|
||||
|
||||
const std::chrono::time_point<std::chrono::high_resolution_clock> SystemResources::start
|
||||
= std::chrono::high_resolution_clock::now();
|
||||
const std::chrono::time_point<std::chrono::high_resolution_clock> SystemResources::start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
#ifndef _WIN32
|
||||
long
|
||||
|
@ -59,11 +58,11 @@ long
|
|||
SystemResources::availableMemory()
|
||||
{
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
return sysconf(_SC_AVPHYS_PAGES) * pageSize();
|
||||
return sysconf(_SC_AVPHYS_PAGES)*pageSize();
|
||||
#elif defined(__APPLE__)
|
||||
unsigned long usermem = 0;
|
||||
size_t len = sizeof usermem;
|
||||
static int mib[2] = {CTL_HW, HW_USERMEM};
|
||||
static int mib[2] = { CTL_HW, HW_USERMEM };
|
||||
int retval = sysctl(mib, 2, &usermem, &len, NULL, 0);
|
||||
if (retval == 0)
|
||||
return static_cast<long>(usermem);
|
||||
|
@ -84,8 +83,8 @@ SystemResources::SystemResources()
|
|||
#ifndef _WIN32
|
||||
struct rusage rus;
|
||||
getrusage(RUSAGE_SELF, &rus);
|
||||
utime = rus.ru_utime.tv_sec + rus.ru_utime.tv_usec * 1.0e-6;
|
||||
stime = rus.ru_stime.tv_sec + rus.ru_stime.tv_usec * 1.0e-6;
|
||||
utime = rus.ru_utime.tv_sec+rus.ru_utime.tv_usec*1.0e-6;
|
||||
stime = rus.ru_stime.tv_sec+rus.ru_stime.tv_usec*1.0e-6;
|
||||
idrss = rus.ru_idrss;
|
||||
majflt = rus.ru_majflt * pageSize();
|
||||
#else
|
||||
|
@ -105,7 +104,7 @@ SystemResources::SystemResources()
|
|||
}
|
||||
|
||||
void
|
||||
SystemResources::diff(const SystemResources& pre)
|
||||
SystemResources::diff(const SystemResources &pre)
|
||||
{
|
||||
utime -= pre.utime;
|
||||
stime -= pre.stime;
|
||||
|
@ -115,14 +114,14 @@ SystemResources::diff(const SystemResources& pre)
|
|||
}
|
||||
|
||||
// JournalRecord::operator<<() symmetry code
|
||||
JournalRecord&
|
||||
JournalRecord::operator<<(const IntSequence& s)
|
||||
JournalRecord &
|
||||
JournalRecord::operator<<(const IntSequence &s)
|
||||
{
|
||||
operator<<('[');
|
||||
for (int i = 0; i < s.size(); i++)
|
||||
{
|
||||
operator<<(s[i]);
|
||||
if (i < s.size() - 1)
|
||||
if (i < s.size()-1)
|
||||
operator<<(',');
|
||||
}
|
||||
operator<<(']');
|
||||
|
@ -130,49 +129,49 @@ JournalRecord::operator<<(const IntSequence& s)
|
|||
}
|
||||
|
||||
void
|
||||
JournalRecord::writeFloatTabular(std::ostream& s, double d, int width)
|
||||
JournalRecord::writeFloatTabular(std::ostream &s, double d, int width)
|
||||
{
|
||||
// Number of digits of integer part
|
||||
int intdigits = std::max(static_cast<int>(std::floor(log10(d)) + 1), 1);
|
||||
int intdigits = std::max(static_cast<int>(std::floor(log10(d))+1), 1);
|
||||
|
||||
int prec = std::max(width - 1 - intdigits, 0);
|
||||
s << std::fixed << std::setw(width) << std::setprecision(prec) << d;
|
||||
}
|
||||
|
||||
void
|
||||
JournalRecord::writePrefix(const SystemResources& f)
|
||||
JournalRecord::writePrefix(const SystemResources &f)
|
||||
{
|
||||
constexpr double mb = 1024 * 1024;
|
||||
constexpr double mb = 1024*1024;
|
||||
std::ostringstream s;
|
||||
s << std::setfill('0');
|
||||
writeFloatTabular(s, f.elapsed, 7);
|
||||
s << "│" << recChar << std::setw(5) << ord << "│";
|
||||
writeFloatTabular(s, f.load_avg, 3);
|
||||
s << "│";
|
||||
writeFloatTabular(s, f.mem_avail / mb, 5);
|
||||
writeFloatTabular(s, f.mem_avail/mb, 5);
|
||||
s << "│ │ ";
|
||||
for (int i = 0; i < 2 * journal.getDepth(); i++)
|
||||
for (int i = 0; i < 2*journal.getDepth(); i++)
|
||||
s << ' ';
|
||||
prefix = s.str();
|
||||
}
|
||||
|
||||
void
|
||||
JournalRecordPair::writePrefixForEnd(const SystemResources& f)
|
||||
JournalRecordPair::writePrefixForEnd(const SystemResources &f)
|
||||
{
|
||||
constexpr double mb = 1024 * 1024;
|
||||
constexpr double mb = 1024*1024;
|
||||
SystemResources difnow;
|
||||
difnow.diff(f);
|
||||
std::ostringstream s;
|
||||
s << std::setfill('0');
|
||||
writeFloatTabular(s, f.elapsed + difnow.elapsed, 7);
|
||||
writeFloatTabular(s, f.elapsed+difnow.elapsed, 7);
|
||||
s << "│E" << std::setw(5) << ord << "│";
|
||||
writeFloatTabular(s, difnow.load_avg, 3);
|
||||
s << "│";
|
||||
writeFloatTabular(s, difnow.mem_avail / mb, 5);
|
||||
writeFloatTabular(s, difnow.mem_avail/mb, 5);
|
||||
s << "│";
|
||||
writeFloatTabular(s, difnow.majflt / mb, 6);
|
||||
writeFloatTabular(s, difnow.majflt/mb, 6);
|
||||
s << "│ ";
|
||||
for (int i = 0; i < 2 * journal.getDepth(); i++)
|
||||
for (int i = 0; i < 2*journal.getDepth(); i++)
|
||||
s << ' ';
|
||||
prefix_end = s.str();
|
||||
}
|
||||
|
@ -187,8 +186,8 @@ JournalRecordPair::~JournalRecordPair()
|
|||
journal.flush();
|
||||
}
|
||||
|
||||
JournalRecord&
|
||||
endrec(JournalRecord& rec)
|
||||
JournalRecord &
|
||||
endrec(JournalRecord &rec)
|
||||
{
|
||||
rec.journal << rec.prefix;
|
||||
rec.journal << rec.mes;
|
||||
|
@ -201,15 +200,24 @@ endrec(JournalRecord& rec)
|
|||
void
|
||||
Journal::printHeader()
|
||||
{
|
||||
*this << "Dynare, version " << PACKAGE_VERSION << '\n' << '\n' << "System info: ";
|
||||
*this << "Dynare++ v. " << VERSION << '\n'
|
||||
<< '\n'
|
||||
<< "Copyright © 2004-2011 Ondra Kamenik\n"
|
||||
<< "Copyright © 2019-2020 Dynare Team\n"
|
||||
<< "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under the GNU GPL,\n"
|
||||
<< "version 3 or later (see https://www.gnu.org/licenses/gpl.html)\n"
|
||||
<< "\n\n"
|
||||
<< "System info: ";
|
||||
#ifndef _WIN32
|
||||
utsname info;
|
||||
uname(&info);
|
||||
*this << info.sysname << " " << info.release << " " << info.version << " " << info.machine;
|
||||
*this << info.sysname << " " << info.release << " " << info.version << " "
|
||||
<< info.machine;
|
||||
#else
|
||||
*this << "Windows";
|
||||
#endif
|
||||
*this << ", processors online: " << std::thread::hardware_concurrency() << "\n\nStart time: ";
|
||||
*this << ", processors online: " << std::thread::hardware_concurrency()
|
||||
<< "\n\nStart time: ";
|
||||
std::time_t t = std::time(nullptr);
|
||||
// NB: in the date/time string, we avoid using locale-specific strings (#1751)
|
||||
*this << std::put_time(std::localtime(&t),
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2020 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -20,16 +20,16 @@
|
|||
|
||||
// Resource usage journal
|
||||
|
||||
#ifndef JOURNAL_HH
|
||||
#define JOURNAL_HH
|
||||
#ifndef JOURNAL_H
|
||||
#define JOURNAL_H
|
||||
|
||||
#include "int_sequence.hh"
|
||||
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
|
||||
/* Implement static methods for accessing some system resources. An instance of
|
||||
this class is a photograph of these resources at the time of instantiation. */
|
||||
|
@ -52,23 +52,23 @@ struct SystemResources
|
|||
long majflt;
|
||||
|
||||
SystemResources();
|
||||
void diff(const SystemResources& pre);
|
||||
void diff(const SystemResources &pre);
|
||||
};
|
||||
|
||||
class Journal : public std::ofstream
|
||||
{
|
||||
int ord {0};
|
||||
int depth {0};
|
||||
|
||||
int ord{0};
|
||||
int depth{0};
|
||||
public:
|
||||
explicit Journal(const std::string& fname) : std::ofstream(fname)
|
||||
explicit Journal(const std::string &fname)
|
||||
: std::ofstream(fname)
|
||||
{
|
||||
printHeader();
|
||||
}
|
||||
/* Constructor that does not initialize the std::ofstream. To be used when an
|
||||
on-disk journal is not wanted. */
|
||||
Journal() = default;
|
||||
Journal& operator=(Journal&&) = default;
|
||||
Journal &operator=(Journal &&) = default;
|
||||
~Journal() override
|
||||
{
|
||||
flush();
|
||||
|
@ -102,64 +102,63 @@ public:
|
|||
};
|
||||
|
||||
class JournalRecord;
|
||||
JournalRecord& endrec(JournalRecord&);
|
||||
JournalRecord &endrec(JournalRecord &);
|
||||
|
||||
class JournalRecord
|
||||
{
|
||||
protected:
|
||||
char recChar;
|
||||
int ord;
|
||||
|
||||
public:
|
||||
Journal& journal;
|
||||
Journal &journal;
|
||||
std::string prefix;
|
||||
std::string mes;
|
||||
SystemResources flash;
|
||||
using _Tfunc = JournalRecord& (*)(JournalRecord&);
|
||||
using _Tfunc = JournalRecord &(*)(JournalRecord &);
|
||||
|
||||
explicit JournalRecord(Journal& jr, char rc = 'M') : recChar(rc), ord(jr.getOrd()), journal(jr)
|
||||
explicit JournalRecord(Journal &jr, char rc = 'M')
|
||||
: recChar(rc), ord(jr.getOrd()), journal(jr)
|
||||
{
|
||||
writePrefix(flash);
|
||||
}
|
||||
virtual ~JournalRecord() = default;
|
||||
JournalRecord& operator<<(const IntSequence& s);
|
||||
JournalRecord&
|
||||
JournalRecord &operator<<(const IntSequence &s);
|
||||
JournalRecord &
|
||||
operator<<(_Tfunc f)
|
||||
{
|
||||
(*f)(*this);
|
||||
return *this;
|
||||
}
|
||||
JournalRecord&
|
||||
JournalRecord &
|
||||
operator<<(char c)
|
||||
{
|
||||
mes += c;
|
||||
return *this;
|
||||
}
|
||||
JournalRecord&
|
||||
operator<<(const std::string& s)
|
||||
JournalRecord &
|
||||
operator<<(const std::string &s)
|
||||
{
|
||||
mes += s;
|
||||
return *this;
|
||||
}
|
||||
JournalRecord&
|
||||
JournalRecord &
|
||||
operator<<(int i)
|
||||
{
|
||||
mes += std::to_string(i);
|
||||
return *this;
|
||||
}
|
||||
JournalRecord&
|
||||
JournalRecord &
|
||||
operator<<(double d)
|
||||
{
|
||||
mes += std::to_string(d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
void writePrefix(const SystemResources& f);
|
||||
void writePrefix(const SystemResources &f);
|
||||
/* Writes a floating point number as a field of exactly ‘width’ characters
|
||||
large. Note that the width will not be respected if the integer part is
|
||||
too large. */
|
||||
static void writeFloatTabular(std::ostream& s, double d, int width);
|
||||
static void writeFloatTabular(std::ostream &s, double d, int width);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -171,16 +170,15 @@ protected:
|
|||
class JournalRecordPair : public JournalRecord
|
||||
{
|
||||
std::string prefix_end;
|
||||
|
||||
public:
|
||||
explicit JournalRecordPair(Journal& jr) : JournalRecord(jr, 'S')
|
||||
explicit JournalRecordPair(Journal &jr)
|
||||
: JournalRecord(jr, 'S')
|
||||
{
|
||||
journal.incrementDepth();
|
||||
}
|
||||
~JournalRecordPair() override;
|
||||
|
||||
private:
|
||||
void writePrefixForEnd(const SystemResources& f);
|
||||
void writePrefixForEnd(const SystemResources &f);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -22,24 +22,24 @@
|
|||
|
||||
/* This is a simple code defining an exception and two convenience macros. */
|
||||
|
||||
#ifndef KORD_EXCEPTION_HH
|
||||
#define KORD_EXCEPTION_HH
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#define KORD_RAISE(mes) throw KordException(__FILE__, __LINE__, mes);
|
||||
#ifndef KORD_EXCEPTION_H
|
||||
# define KORD_EXCEPTION_H
|
||||
|
||||
#define KORD_RAISE_IF(expr, mes) \
|
||||
if (expr) \
|
||||
# define KORD_RAISE(mes) \
|
||||
throw KordException(__FILE__, __LINE__, mes);
|
||||
|
||||
#define KORD_RAISE_X(mes, c) throw KordException(__FILE__, __LINE__, mes, c);
|
||||
# define KORD_RAISE_IF(expr, mes) \
|
||||
if (expr) throw KordException(__FILE__, __LINE__, mes);
|
||||
|
||||
#define KORD_RAISE_IF_X(expr, mes, c) \
|
||||
if (expr) \
|
||||
# define KORD_RAISE_X(mes, c) \
|
||||
throw KordException(__FILE__, __LINE__, mes, c);
|
||||
|
||||
# define KORD_RAISE_IF_X(expr, mes, c) \
|
||||
if (expr) throw KordException(__FILE__, __LINE__, mes, c);
|
||||
|
||||
class KordException
|
||||
{
|
||||
protected:
|
||||
|
@ -47,10 +47,9 @@ protected:
|
|||
int lnum;
|
||||
std::string message;
|
||||
int cd;
|
||||
|
||||
public:
|
||||
KordException(std::string f, int l, std::string mes, int c = 255) :
|
||||
fname {std::move(f)}, lnum {l}, message {std::move(mes)}, cd {c}
|
||||
KordException(std::string f, int l, std::string mes, int c = 255)
|
||||
: fname{std::move(f)}, lnum{l}, message{std::move(mes)}, cd{c}
|
||||
{
|
||||
}
|
||||
virtual ~KordException() = default;
|
||||
|
@ -59,12 +58,12 @@ public:
|
|||
{
|
||||
std::cout << "At " << fname << ':' << lnum << ":(" << cd << "):" << message << '\n';
|
||||
}
|
||||
[[nodiscard]] virtual int
|
||||
virtual int
|
||||
code() const
|
||||
{
|
||||
return cd;
|
||||
}
|
||||
[[nodiscard]] const std::string&
|
||||
const std::string &
|
||||
get_message() const
|
||||
{
|
||||
return message;
|
|
@ -18,8 +18,8 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "korder.hh"
|
||||
#include "kord_exception.hh"
|
||||
#include "korder.hh"
|
||||
|
||||
/* Here we set ‘ipiv’ and ‘inv’ members of the PLUMatrix depending on its
|
||||
content. It is assumed that subclasses will call this method at the end of
|
||||
|
@ -30,23 +30,26 @@ PLUMatrix::calcPLU()
|
|||
{
|
||||
lapack_int info;
|
||||
lapack_int rows = nrows(), lda = ld;
|
||||
inv = const_cast<const Vector&>(getData());
|
||||
inv = const_cast<const Vector &>(getData());
|
||||
dgetrf(&rows, &rows, inv.base(), &lda, ipiv.data(), &info);
|
||||
}
|
||||
|
||||
/* Here we just call the LAPACK machinery to multiply by the inverse. */
|
||||
|
||||
void
|
||||
PLUMatrix::multInv(TwoDMatrix& m) const
|
||||
PLUMatrix::multInv(TwoDMatrix &m) const
|
||||
{
|
||||
KORD_RAISE_IF(m.nrows() != ncols(), "The matrix is not square in PLUMatrix::multInv");
|
||||
KORD_RAISE_IF(m.nrows() != ncols(),
|
||||
"The matrix is not square in PLUMatrix::multInv");
|
||||
lapack_int info;
|
||||
lapack_int lda = ld;
|
||||
lapack_int mcols = m.ncols();
|
||||
lapack_int mrows = m.nrows();
|
||||
lapack_int ldb = m.getLD();
|
||||
dgetrs("N", &mrows, &mcols, inv.base(), &lda, ipiv.data(), m.getData().base(), &ldb, &info);
|
||||
KORD_RAISE_IF(info != 0, "Info!=0 in PLUMatrix::multInv");
|
||||
dgetrs("N", &mrows, &mcols, inv.base(), &lda, ipiv.data(),
|
||||
m.getData().base(), &ldb, &info);
|
||||
KORD_RAISE_IF(info != 0,
|
||||
"Info!=0 in PLUMatrix::multInv");
|
||||
}
|
||||
|
||||
/* Here we construct the matrix A. Its dimension is ‘ny’, and it is
|
||||
|
@ -56,17 +59,17 @@ PLUMatrix::multInv(TwoDMatrix& m) const
|
|||
where the first zero spans ‘nstat’ columns, and last zero spans ‘nforw’
|
||||
columns. */
|
||||
|
||||
MatrixA::MatrixA(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatrix& gy,
|
||||
const PartitionY& ypart) :
|
||||
PLUMatrix(ypart.ny())
|
||||
MatrixA::MatrixA(const FSSparseTensor &f, const IntSequence &ss,
|
||||
const TwoDMatrix &gy, const PartitionY &ypart)
|
||||
: PLUMatrix(ypart.ny())
|
||||
{
|
||||
zeros();
|
||||
|
||||
IntSequence c {1};
|
||||
IntSequence c{1};
|
||||
FGSTensor f_y(f, ss, c, TensorDimens(ss, c));
|
||||
add(1.0, f_y);
|
||||
|
||||
ConstTwoDMatrix gss_ys(ypart.nstat + ypart.npred, ypart.nyss(), gy);
|
||||
ConstTwoDMatrix gss_ys(ypart.nstat+ypart.npred, ypart.nyss(), gy);
|
||||
c[0] = 0;
|
||||
FGSTensor f_yss(f, ss, c, TensorDimens(ss, c));
|
||||
TwoDMatrix sub(*this, ypart.nstat, ypart.nys());
|
||||
|
@ -82,23 +85,23 @@ MatrixA::MatrixA(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatri
|
|||
It is, in fact, the matrix A plus the third summand. The first zero in the
|
||||
summand spans ‘nstat’ columns, the second zero spans ‘npred’ columns. */
|
||||
|
||||
MatrixS::MatrixS(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatrix& gy,
|
||||
const PartitionY& ypart) :
|
||||
PLUMatrix(ypart.ny())
|
||||
MatrixS::MatrixS(const FSSparseTensor &f, const IntSequence &ss,
|
||||
const TwoDMatrix &gy, const PartitionY &ypart)
|
||||
: PLUMatrix(ypart.ny())
|
||||
{
|
||||
zeros();
|
||||
|
||||
IntSequence c {1};
|
||||
IntSequence c{1};
|
||||
FGSTensor f_y(f, ss, c, TensorDimens(ss, c));
|
||||
add(1.0, f_y);
|
||||
|
||||
ConstTwoDMatrix gss_ys(ypart.nstat + ypart.npred, ypart.nyss(), gy);
|
||||
ConstTwoDMatrix gss_ys(ypart.nstat+ypart.npred, ypart.nyss(), gy);
|
||||
c[0] = 0;
|
||||
FGSTensor f_yss(f, ss, c, TensorDimens(ss, c));
|
||||
TwoDMatrix sub(*this, ypart.nstat, ypart.nys());
|
||||
sub.multAndAdd(ConstTwoDMatrix(f_yss), gss_ys);
|
||||
|
||||
TwoDMatrix sub2(*this, ypart.nstat + ypart.npred, ypart.nyss());
|
||||
TwoDMatrix sub2(*this, ypart.nstat+ypart.npred, ypart.nyss());
|
||||
sub2.add(1.0, f_yss);
|
||||
|
||||
calcPLU();
|
||||
|
@ -109,169 +112,169 @@ MatrixS::MatrixS(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatri
|
|||
interesting here. */
|
||||
|
||||
template<>
|
||||
ctraits<Storage::unfold>::Tg&
|
||||
ctraits<Storage::unfold>::Tg &
|
||||
KOrder::g<Storage::unfold>()
|
||||
{
|
||||
return _ug;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::Tg&
|
||||
const ctraits<Storage::unfold>::Tg &
|
||||
KOrder::g<Storage::unfold>() const
|
||||
{
|
||||
return _ug;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::Tg&
|
||||
ctraits<Storage::fold>::Tg &
|
||||
KOrder::g<Storage::fold>()
|
||||
{
|
||||
return _fg;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::Tg&
|
||||
const ctraits<Storage::fold>::Tg &
|
||||
KOrder::g<Storage::fold>() const
|
||||
{
|
||||
return _fg;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::Tgs&
|
||||
ctraits<Storage::unfold>::Tgs &
|
||||
KOrder::gs<Storage::unfold>()
|
||||
{
|
||||
return _ugs;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::Tgs&
|
||||
const ctraits<Storage::unfold>::Tgs &
|
||||
KOrder::gs<Storage::unfold>() const
|
||||
{
|
||||
return _ugs;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::Tgs&
|
||||
ctraits<Storage::fold>::Tgs &
|
||||
KOrder::gs<Storage::fold>()
|
||||
{
|
||||
return _fgs;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::Tgs&
|
||||
const ctraits<Storage::fold>::Tgs &
|
||||
KOrder::gs<Storage::fold>() const
|
||||
{
|
||||
return _fgs;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::Tgss&
|
||||
ctraits<Storage::unfold>::Tgss &
|
||||
KOrder::gss<Storage::unfold>()
|
||||
{
|
||||
return _ugss;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::Tgss&
|
||||
const ctraits<Storage::unfold>::Tgss &
|
||||
KOrder::gss<Storage::unfold>() const
|
||||
{
|
||||
return _ugss;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::Tgss&
|
||||
ctraits<Storage::fold>::Tgss &
|
||||
KOrder::gss<Storage::fold>()
|
||||
{
|
||||
return _fgss;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::Tgss&
|
||||
const ctraits<Storage::fold>::Tgss &
|
||||
KOrder::gss<Storage::fold>() const
|
||||
{
|
||||
return _fgss;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::TG&
|
||||
ctraits<Storage::unfold>::TG &
|
||||
KOrder::G<Storage::unfold>()
|
||||
{
|
||||
return _uG;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::TG&
|
||||
const ctraits<Storage::unfold>::TG &
|
||||
KOrder::G<Storage::unfold>() const
|
||||
{
|
||||
return _uG;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::TG&
|
||||
ctraits<Storage::fold>::TG &
|
||||
KOrder::G<Storage::fold>()
|
||||
{
|
||||
return _fG;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::TG&
|
||||
const ctraits<Storage::fold>::TG &
|
||||
KOrder::G<Storage::fold>() const
|
||||
{
|
||||
return _fG;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::TZstack&
|
||||
ctraits<Storage::unfold>::TZstack &
|
||||
KOrder::Zstack<Storage::unfold>()
|
||||
{
|
||||
return _uZstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::TZstack&
|
||||
const ctraits<Storage::unfold>::TZstack &
|
||||
KOrder::Zstack<Storage::unfold>() const
|
||||
{
|
||||
return _uZstack;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::TZstack&
|
||||
ctraits<Storage::fold>::TZstack &
|
||||
KOrder::Zstack<Storage::fold>()
|
||||
{
|
||||
return _fZstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::TZstack&
|
||||
const ctraits<Storage::fold>::TZstack &
|
||||
KOrder::Zstack<Storage::fold>() const
|
||||
{
|
||||
return _fZstack;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::TGstack&
|
||||
ctraits<Storage::unfold>::TGstack &
|
||||
KOrder::Gstack<Storage::unfold>()
|
||||
{
|
||||
return _uGstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::TGstack&
|
||||
const ctraits<Storage::unfold>::TGstack &
|
||||
KOrder::Gstack<Storage::unfold>() const
|
||||
{
|
||||
return _uGstack;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::TGstack&
|
||||
ctraits<Storage::fold>::TGstack &
|
||||
KOrder::Gstack<Storage::fold>()
|
||||
{
|
||||
return _fGstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::TGstack&
|
||||
const ctraits<Storage::fold>::TGstack &
|
||||
KOrder::Gstack<Storage::fold>() const
|
||||
{
|
||||
return _fGstack;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::Tm&
|
||||
ctraits<Storage::unfold>::Tm &
|
||||
KOrder::m<Storage::unfold>()
|
||||
{
|
||||
return _um;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::Tm&
|
||||
const ctraits<Storage::unfold>::Tm &
|
||||
KOrder::m<Storage::unfold>() const
|
||||
{
|
||||
return _um;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::Tm&
|
||||
ctraits<Storage::fold>::Tm &
|
||||
KOrder::m<Storage::fold>()
|
||||
{
|
||||
return _fm;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::Tm&
|
||||
const ctraits<Storage::fold>::Tm &
|
||||
KOrder::m<Storage::fold>() const
|
||||
{
|
||||
return _fm;
|
||||
|
@ -290,58 +293,56 @@ KOrder::m<Storage::fold>() const
|
|||
to comply to preconditions of performStep(). */
|
||||
|
||||
KOrder::KOrder(int num_stat, int num_pred, int num_both, int num_forw,
|
||||
const TensorContainer<FSSparseTensor>& fcont, const TwoDMatrix& gy,
|
||||
const TwoDMatrix& gu, const TwoDMatrix& v, Journal& jr) :
|
||||
ypart(num_stat, num_pred, num_both, num_forw),
|
||||
ny(ypart.ny()),
|
||||
nu(gu.ncols()),
|
||||
maxk(fcont.getMaxDim()),
|
||||
nvs {ypart.nys(), nu, nu, 1},
|
||||
_ug(4),
|
||||
_fg(4),
|
||||
_ugs(4),
|
||||
_fgs(4),
|
||||
_ugss(4),
|
||||
_fgss(4),
|
||||
_uG(4),
|
||||
_fG(4),
|
||||
const TensorContainer<FSSparseTensor> &fcont,
|
||||
const TwoDMatrix &gy, const TwoDMatrix &gu, const TwoDMatrix &v,
|
||||
Journal &jr)
|
||||
: ypart(num_stat, num_pred, num_both, num_forw),
|
||||
ny(ypart.ny()), nu(gu.ncols()), maxk(fcont.getMaxDim()),
|
||||
nvs{ypart.nys(), nu, nu, 1},
|
||||
_ug(4), _fg(4), _ugs(4), _fgs(4), _ugss(4), _fgss(4),
|
||||
_uG(4), _fG(4),
|
||||
_uZstack(&_uG, ypart.nyss(), &_ug, ny, ypart.nys(), nu),
|
||||
_fZstack(&_fG, ypart.nyss(), &_fg, ny, ypart.nys(), nu),
|
||||
_uGstack(&_ugs, ypart.nys(), nu),
|
||||
_fGstack(&_fgs, ypart.nys(), nu),
|
||||
_um(maxk, v),
|
||||
_fm(_um),
|
||||
f(fcont),
|
||||
matA(f.get(Symmetry {1}), _uZstack.getStackSizes(), gy, ypart),
|
||||
matS(f.get(Symmetry {1}), _uZstack.getStackSizes(), gy, ypart),
|
||||
matB(f.get(Symmetry {1}), _uZstack.getStackSizes()),
|
||||
_um(maxk, v), _fm(_um), f(fcont),
|
||||
matA(f.get(Symmetry{1}), _uZstack.getStackSizes(), gy, ypart),
|
||||
matS(f.get(Symmetry{1}), _uZstack.getStackSizes(), gy, ypart),
|
||||
matB(f.get(Symmetry{1}), _uZstack.getStackSizes()),
|
||||
journal(jr)
|
||||
{
|
||||
KORD_RAISE_IF(gy.ncols() != ypart.nys(), "Wrong number of columns in gy in KOrder constructor");
|
||||
KORD_RAISE_IF(v.ncols() != nu, "Wrong number of columns of Vcov in KOrder constructor");
|
||||
KORD_RAISE_IF(nu != v.nrows(), "Wrong number of rows of Vcov in KOrder constructor");
|
||||
KORD_RAISE_IF(maxk < 2, "Order of approximation must be at least 2 in KOrder constructor");
|
||||
KORD_RAISE_IF(gy.nrows() != ypart.ny(), "Wrong number of rows in gy in KOrder constructor");
|
||||
KORD_RAISE_IF(gu.nrows() != ypart.ny(), "Wrong number of rows in gu in KOrder constructor");
|
||||
KORD_RAISE_IF(gu.ncols() != nu, "Wrong number of columns in gu in KOrder constructor");
|
||||
KORD_RAISE_IF(gy.ncols() != ypart.nys(),
|
||||
"Wrong number of columns in gy in KOrder constructor");
|
||||
KORD_RAISE_IF(v.ncols() != nu,
|
||||
"Wrong number of columns of Vcov in KOrder constructor");
|
||||
KORD_RAISE_IF(nu != v.nrows(),
|
||||
"Wrong number of rows of Vcov in KOrder constructor");
|
||||
KORD_RAISE_IF(maxk < 2,
|
||||
"Order of approximation must be at least 2 in KOrder constructor");
|
||||
KORD_RAISE_IF(gy.nrows() != ypart.ny(),
|
||||
"Wrong number of rows in gy in KOrder constructor");
|
||||
KORD_RAISE_IF(gu.nrows() != ypart.ny(),
|
||||
"Wrong number of rows in gu in KOrder constructor");
|
||||
KORD_RAISE_IF(gu.ncols() != nu,
|
||||
"Wrong number of columns in gu in KOrder constructor");
|
||||
|
||||
// Put g_y and gᵤ in the container
|
||||
/* Note that g_σ is zero by construction and we do not insert it to the
|
||||
container. We insert a new physical copies. */
|
||||
auto tgy = std::make_unique<UGSTensor>(ny, TensorDimens(Symmetry {1, 0, 0, 0}, nvs));
|
||||
auto tgy = std::make_unique<UGSTensor>(ny, TensorDimens(Symmetry{1, 0, 0, 0}, nvs));
|
||||
tgy->getData() = gy.getData();
|
||||
insertDerivative<Storage::unfold>(std::move(tgy));
|
||||
auto tgu = std::make_unique<UGSTensor>(ny, TensorDimens(Symmetry {0, 1, 0, 0}, nvs));
|
||||
auto tgu = std::make_unique<UGSTensor>(ny, TensorDimens(Symmetry{0, 1, 0, 0}, nvs));
|
||||
tgu->getData() = gu.getData();
|
||||
insertDerivative<Storage::unfold>(std::move(tgu));
|
||||
|
||||
// Put G_y, G_u and G_u′ in the container
|
||||
/* Also note that since g_σ is zero, so is G_σ. */
|
||||
auto tGy = faaDiBrunoG<Storage::unfold>(Symmetry {1, 0, 0, 0});
|
||||
auto tGy = faaDiBrunoG<Storage::unfold>(Symmetry{1, 0, 0, 0});
|
||||
G<Storage::unfold>().insert(std::move(tGy));
|
||||
auto tGu = faaDiBrunoG<Storage::unfold>(Symmetry {0, 1, 0, 0});
|
||||
auto tGu = faaDiBrunoG<Storage::unfold>(Symmetry{0, 1, 0, 0});
|
||||
G<Storage::unfold>().insert(std::move(tGu));
|
||||
auto tGup = faaDiBrunoG<Storage::unfold>(Symmetry {0, 0, 1, 0});
|
||||
auto tGup = faaDiBrunoG<Storage::unfold>(Symmetry{0, 0, 1, 0});
|
||||
G<Storage::unfold>().insert(std::move(tGup));
|
||||
}
|
||||
|
||||
|
@ -360,16 +361,19 @@ KOrder::KOrder(int num_stat, int num_pred, int num_both, int num_forw,
|
|||
|
||||
template<>
|
||||
void
|
||||
KOrder::sylvesterSolve<Storage::unfold>(ctraits<Storage::unfold>::Ttensor& der) const
|
||||
KOrder::sylvesterSolve<Storage::unfold>(ctraits<Storage::unfold>::Ttensor &der) const
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Sylvester equation for dimension = " << der.getSym()[0] << endrec;
|
||||
if (ypart.nys() > 0 && ypart.nyss() > 0)
|
||||
{
|
||||
KORD_RAISE_IF(!der.isFinite(), "RHS of Sylverster is not finite");
|
||||
TwoDMatrix gs_y(gs<Storage::unfold>().get(Symmetry {1, 0, 0, 0}));
|
||||
GeneralSylvester sylv(der.getSym()[0], ny, ypart.nys(), ypart.nstat + ypart.npred,
|
||||
matA.getData(), matB.getData(), gs_y.getData(), der.getData());
|
||||
KORD_RAISE_IF(!der.isFinite(),
|
||||
"RHS of Sylverster is not finite");
|
||||
TwoDMatrix gs_y(gs<Storage::unfold>().get(Symmetry{1, 0, 0, 0}));
|
||||
GeneralSylvester sylv(der.getSym()[0], ny, ypart.nys(),
|
||||
ypart.nstat+ypart.npred,
|
||||
matA.getData(), matB.getData(),
|
||||
gs_y.getData(), der.getData());
|
||||
sylv.solve();
|
||||
}
|
||||
else if (ypart.nys() > 0 && ypart.nyss() == 0)
|
||||
|
@ -383,12 +387,12 @@ KOrder::sylvesterSolve<Storage::unfold>(ctraits<Storage::unfold>::Ttensor& der)
|
|||
|
||||
template<>
|
||||
void
|
||||
KOrder::sylvesterSolve<Storage::fold>(ctraits<Storage::fold>::Ttensor& der) const
|
||||
KOrder::sylvesterSolve<Storage::fold>(ctraits<Storage::fold>::Ttensor &der) const
|
||||
{
|
||||
ctraits<Storage::unfold>::Ttensor tmp(der);
|
||||
sylvesterSolve<Storage::unfold>(tmp);
|
||||
ctraits<Storage::fold>::Ttensor ftmp(tmp);
|
||||
der.getData() = const_cast<const Vector&>(ftmp.getData());
|
||||
der.getData() = const_cast<const Vector &>(ftmp.getData());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -399,7 +403,7 @@ KOrder::switchToFolded()
|
|||
|
||||
int maxdim = g<Storage::unfold>().getMaxDim();
|
||||
for (int dim = 1; dim <= maxdim; dim++)
|
||||
for (auto& si : SymmetrySet(dim, 4))
|
||||
for (auto &si : SymmetrySet(dim, 4))
|
||||
{
|
||||
if (si[2] == 0 && g<Storage::unfold>().check(si))
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -38,22 +38,22 @@
|
|||
PartitionY, MatrixA, MatrixS and MatrixB.
|
||||
*/
|
||||
|
||||
#ifndef KORDER_HH
|
||||
#define KORDER_HH
|
||||
#ifndef KORDER_H
|
||||
#define KORDER_H
|
||||
|
||||
#include "faa_di_bruno.hh"
|
||||
#include "int_sequence.hh"
|
||||
#include "fs_tensor.hh"
|
||||
#include "gs_tensor.hh"
|
||||
#include "int_sequence.hh"
|
||||
#include "journal.hh"
|
||||
#include "normal_moments.hh"
|
||||
#include "pascal_triangle.hh"
|
||||
#include "stack_container.hh"
|
||||
#include "t_container.hh"
|
||||
#include "stack_container.hh"
|
||||
#include "normal_moments.hh"
|
||||
#include "t_polynomial.hh"
|
||||
#include "faa_di_bruno.hh"
|
||||
#include "journal.hh"
|
||||
#include "pascal_triangle.hh"
|
||||
|
||||
#include "GeneralSylvester.hh"
|
||||
#include "kord_exception.hh"
|
||||
#include "GeneralSylvester.hh"
|
||||
|
||||
#include <dynlapack.h>
|
||||
|
||||
|
@ -61,11 +61,7 @@
|
|||
#include <type_traits>
|
||||
|
||||
// The enum class passed as template parameter for many data structures
|
||||
enum class Storage
|
||||
{
|
||||
fold,
|
||||
unfold
|
||||
};
|
||||
enum class Storage { fold, unfold };
|
||||
|
||||
/* In ‘ctraits’ we define a number of types. We have a type for tensor Ttensor,
|
||||
and types for each pair of folded/unfolded containers used as a member in
|
||||
|
@ -94,10 +90,8 @@ public:
|
|||
using TGstack = std::conditional_t<type == Storage::fold, FoldedGContainer, UnfoldedGContainer>;
|
||||
using Tm = std::conditional_t<type == Storage::fold, FNormalMoments, UNormalMoments>;
|
||||
using Tpol = std::conditional_t<type == Storage::fold, FTensorPolynomial, UTensorPolynomial>;
|
||||
using TZXstack
|
||||
= std::conditional_t<type == Storage::fold, FoldedZXContainer, UnfoldedZXContainer>;
|
||||
using TGXstack
|
||||
= std::conditional_t<type == Storage::fold, FoldedGXContainer, UnfoldedGXContainer>;
|
||||
using TZXstack = std::conditional_t<type == Storage::fold, FoldedZXContainer, UnfoldedZXContainer>;
|
||||
using TGXstack = std::conditional_t<type == Storage::fold, FoldedGXContainer, UnfoldedGXContainer>;
|
||||
};
|
||||
|
||||
/* The PartitionY class defines the partitioning of state variables y. The
|
||||
|
@ -123,27 +117,27 @@ struct PartitionY
|
|||
const int npred;
|
||||
const int nboth;
|
||||
const int nforw;
|
||||
PartitionY() : PartitionY(0, 0, 0, 0)
|
||||
PartitionY() : PartitionY(0,0,0,0) {}
|
||||
PartitionY(int num_stat, int num_pred,
|
||||
int num_both, int num_forw)
|
||||
: nstat(num_stat), npred(num_pred),
|
||||
nboth(num_both), nforw(num_forw)
|
||||
{
|
||||
}
|
||||
PartitionY(int num_stat, int num_pred, int num_both, int num_forw) :
|
||||
nstat(num_stat), npred(num_pred), nboth(num_both), nforw(num_forw)
|
||||
{
|
||||
}
|
||||
[[nodiscard]] int
|
||||
int
|
||||
ny() const
|
||||
{
|
||||
return nstat + npred + nboth + nforw;
|
||||
return nstat+npred+nboth+nforw;
|
||||
}
|
||||
[[nodiscard]] int
|
||||
int
|
||||
nys() const
|
||||
{
|
||||
return npred + nboth;
|
||||
return npred+nboth;
|
||||
}
|
||||
[[nodiscard]] int
|
||||
int
|
||||
nyss() const
|
||||
{
|
||||
return nboth + nforw;
|
||||
return nboth+nforw;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -157,15 +151,16 @@ struct PartitionY
|
|||
class PLUMatrix : public TwoDMatrix
|
||||
{
|
||||
public:
|
||||
PLUMatrix(int n) : TwoDMatrix(n, n), inv(nrows() * ncols()), ipiv(nrows())
|
||||
PLUMatrix(int n)
|
||||
: TwoDMatrix(n, n),
|
||||
inv(nrows()*ncols()),
|
||||
ipiv(nrows())
|
||||
{
|
||||
}
|
||||
void multInv(TwoDMatrix& m) const;
|
||||
|
||||
void multInv(TwoDMatrix &m) const;
|
||||
private:
|
||||
Vector inv;
|
||||
std::vector<lapack_int> ipiv;
|
||||
|
||||
protected:
|
||||
void calcPLU();
|
||||
};
|
||||
|
@ -176,8 +171,8 @@ protected:
|
|||
class MatrixA : public PLUMatrix
|
||||
{
|
||||
public:
|
||||
MatrixA(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatrix& gy,
|
||||
const PartitionY& ypart);
|
||||
MatrixA(const FSSparseTensor &f, const IntSequence &ss,
|
||||
const TwoDMatrix &gy, const PartitionY &ypart);
|
||||
};
|
||||
|
||||
/* The class MatrixS slightly differs from MatrixA. It is used for
|
||||
|
@ -187,8 +182,8 @@ public:
|
|||
class MatrixS : public PLUMatrix
|
||||
{
|
||||
public:
|
||||
MatrixS(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatrix& gy,
|
||||
const PartitionY& ypart);
|
||||
MatrixS(const FSSparseTensor &f, const IntSequence &ss,
|
||||
const TwoDMatrix &gy, const PartitionY &ypart);
|
||||
};
|
||||
|
||||
/* The B matrix is equal to [f_y**₊]. We have just a constructor. */
|
||||
|
@ -196,8 +191,9 @@ public:
|
|||
class MatrixB : public TwoDMatrix
|
||||
{
|
||||
public:
|
||||
MatrixB(const FSSparseTensor& f, const IntSequence& ss) :
|
||||
TwoDMatrix(FGSTensor(f, ss, IntSequence(1, 0), TensorDimens(ss, IntSequence(1, 0))))
|
||||
MatrixB(const FSSparseTensor &f, const IntSequence &ss)
|
||||
: TwoDMatrix(FGSTensor(f, ss, IntSequence(1, 0),
|
||||
TensorDimens(ss, IntSequence(1, 0))))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -250,7 +246,7 @@ protected:
|
|||
|
||||
/* Dynamic model derivatives: just a reference to the container of sparse
|
||||
tensors of the system derivatives, lives outside the class */
|
||||
const TensorContainer<FSSparseTensor>& f;
|
||||
const TensorContainer<FSSparseTensor> &f;
|
||||
|
||||
/* Matrices: matrix A, matrix S, and matrix B, see MatrixA and MatrixB class
|
||||
declarations */
|
||||
|
@ -262,46 +258,46 @@ protected:
|
|||
containers. We declare template methods for accessing containers depending
|
||||
on ‘fold’ and ‘unfold’ flag, we implement their specializations*/
|
||||
template<Storage t>
|
||||
typename ctraits<t>::Tg& g();
|
||||
typename ctraits<t>::Tg &g();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::Tg& g() const;
|
||||
const typename ctraits<t>::Tg &g() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::Tgs& gs();
|
||||
typename ctraits<t>::Tgs &gs();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::Tgs& gs() const;
|
||||
const typename ctraits<t>::Tgs &gs() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::Tgss& gss();
|
||||
typename ctraits<t>::Tgss &gss();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::Tgss& gss() const;
|
||||
const typename ctraits<t>::Tgss &gss() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::TG& G();
|
||||
typename ctraits<t>::TG &G();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::TG& G() const;
|
||||
const typename ctraits<t>::TG &G() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::TZstack& Zstack();
|
||||
typename ctraits<t>::TZstack &Zstack();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::TZstack& Zstack() const;
|
||||
const typename ctraits<t>::TZstack &Zstack() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::TGstack& Gstack();
|
||||
typename ctraits<t>::TGstack &Gstack();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::TGstack& Gstack() const;
|
||||
const typename ctraits<t>::TGstack &Gstack() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::Tm& m();
|
||||
typename ctraits<t>::Tm &m();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::Tm& m() const;
|
||||
|
||||
Journal& journal;
|
||||
const typename ctraits<t>::Tm &m() const;
|
||||
|
||||
Journal &journal;
|
||||
public:
|
||||
KOrder(int num_stat, int num_pred, int num_both, int num_forw,
|
||||
const TensorContainer<FSSparseTensor>& fcont, const TwoDMatrix& gy, const TwoDMatrix& gu,
|
||||
const TwoDMatrix& v, Journal& jr);
|
||||
const TensorContainer<FSSparseTensor> &fcont,
|
||||
const TwoDMatrix &gy, const TwoDMatrix &gu, const TwoDMatrix &v,
|
||||
Journal &jr);
|
||||
|
||||
/* Performs k-order step provided that k=2 or the k−1-th step has been
|
||||
run, this is the core method */
|
||||
|
@ -311,27 +307,27 @@ public:
|
|||
/* Calculates residuals of all solved equations for k-order and reports their
|
||||
sizes, it is runnable after k-order performStep() has been run */
|
||||
template<Storage t>
|
||||
[[nodiscard]] double check(int dim) const;
|
||||
double check(int dim) const;
|
||||
|
||||
template<Storage t>
|
||||
[[nodiscard]] Vector calcStochShift(int order, double sigma) const;
|
||||
Vector calcStochShift(int order, double sigma) const;
|
||||
void switchToFolded();
|
||||
[[nodiscard]] const PartitionY&
|
||||
const PartitionY &
|
||||
getPartY() const
|
||||
{
|
||||
return ypart;
|
||||
}
|
||||
[[nodiscard]] const FGSContainer&
|
||||
const FGSContainer &
|
||||
getFoldDers() const
|
||||
{
|
||||
return _fg;
|
||||
}
|
||||
[[nodiscard]] const UGSContainer&
|
||||
const UGSContainer &
|
||||
getUnfoldDers() const
|
||||
{
|
||||
return _ug;
|
||||
}
|
||||
[[nodiscard]] const FGSContainer&
|
||||
const FGSContainer &
|
||||
getFoldDersS() const
|
||||
{
|
||||
return _fgs;
|
||||
|
@ -341,7 +337,6 @@ public:
|
|||
{
|
||||
return i % 2 == 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
/* Inserts a g derivative to the g container and also creates subtensors and
|
||||
insert them to g_y* and g_y** containers */
|
||||
|
@ -350,17 +345,17 @@ protected:
|
|||
|
||||
/* Solves the sylvester equation (templated fold, and unfold) */
|
||||
template<Storage t>
|
||||
void sylvesterSolve(typename ctraits<t>::Ttensor& der) const;
|
||||
void sylvesterSolve(typename ctraits<t>::Ttensor &der) const;
|
||||
|
||||
/* Calculates derivatives of F by Faà Di Bruno for the sparse container of
|
||||
system derivatives and Z stack container */
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoZ(const Symmetry& sym) const;
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoZ(const Symmetry &sym) const;
|
||||
|
||||
/* Calculates derivatives of G by Faà Di Bruno for the dense container g**
|
||||
and G stack */
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoG(const Symmetry& sym) const;
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoG(const Symmetry &sym) const;
|
||||
|
||||
// Recovers g_y*ⁱ
|
||||
template<Storage t>
|
||||
|
@ -407,9 +402,8 @@ KOrder::insertDerivative(std::unique_ptr<typename ctraits<t>::Ttensor> der)
|
|||
{
|
||||
auto der_ptr = der.get();
|
||||
g<t>().insert(std::move(der));
|
||||
gs<t>().insert(
|
||||
std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat, ypart.nys(), *der_ptr));
|
||||
gss<t>().insert(std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat + ypart.npred,
|
||||
gs<t>().insert(std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat, ypart.nys(), *der_ptr));
|
||||
gss<t>().insert(std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat+ypart.npred,
|
||||
ypart.nyss(), *der_ptr));
|
||||
}
|
||||
|
||||
|
@ -423,7 +417,7 @@ KOrder::insertDerivative(std::unique_ptr<typename ctraits<t>::Ttensor> der)
|
|||
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor>
|
||||
KOrder::faaDiBrunoZ(const Symmetry& sym) const
|
||||
KOrder::faaDiBrunoZ(const Symmetry &sym) const
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Faà Di Bruno Z container for " << sym << endrec;
|
||||
|
@ -437,7 +431,7 @@ KOrder::faaDiBrunoZ(const Symmetry& sym) const
|
|||
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor>
|
||||
KOrder::faaDiBrunoG(const Symmetry& sym) const
|
||||
KOrder::faaDiBrunoG(const Symmetry &sym) const
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Faà Di Bruno G container for " << sym << endrec;
|
||||
|
@ -462,7 +456,7 @@ template<Storage t>
|
|||
void
|
||||
KOrder::recover_y(int i)
|
||||
{
|
||||
Symmetry sym {i, 0, 0, 0};
|
||||
Symmetry sym{i, 0, 0, 0};
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Recovering symmetry " << sym << endrec;
|
||||
|
||||
|
@ -477,9 +471,9 @@ KOrder::recover_y(int i)
|
|||
|
||||
insertDerivative<t>(std::move(g_yi));
|
||||
|
||||
auto& gss_y = gss<t>().get(Symmetry {1, 0, 0, 0});
|
||||
auto &gss_y = gss<t>().get(Symmetry{1, 0, 0, 0});
|
||||
gs<t>().multAndAdd(gss_y, *G_yi_ptr);
|
||||
auto& gss_yi = gss<t>().get(sym);
|
||||
auto &gss_yi = gss<t>().get(sym);
|
||||
gs<t>().multAndAdd(gss_yi, *G_yi_ptr);
|
||||
}
|
||||
|
||||
|
@ -496,7 +490,7 @@ template<Storage t>
|
|||
void
|
||||
KOrder::recover_yu(int i, int j)
|
||||
{
|
||||
Symmetry sym {i, j, 0, 0};
|
||||
Symmetry sym{i, j, 0, 0};
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Recovering symmetry " << sym << endrec;
|
||||
|
||||
|
@ -509,7 +503,7 @@ KOrder::recover_yu(int i, int j)
|
|||
matA.multInv(*g_yiuj);
|
||||
insertDerivative<t>(std::move(g_yiuj));
|
||||
|
||||
gs<t>().multAndAdd(gss<t>().get(Symmetry {1, 0, 0, 0}), *G_yiuj_ptr);
|
||||
gs<t>().multAndAdd(gss<t>().get(Symmetry{1, 0, 0, 0}), *G_yiuj_ptr);
|
||||
}
|
||||
|
||||
/* Here we solve [F_yⁱσʲ]+[Dᵢⱼ]+[Eᵢⱼ]=0 to obtain g_yⁱσʲ. We calculate
|
||||
|
@ -529,7 +523,7 @@ template<Storage t>
|
|||
void
|
||||
KOrder::recover_ys(int i, int j)
|
||||
{
|
||||
Symmetry sym {i, 0, 0, j};
|
||||
Symmetry sym{i, 0, 0, j};
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Recovering symmetry " << sym << endrec;
|
||||
|
||||
|
@ -561,7 +555,7 @@ KOrder::recover_ys(int i, int j)
|
|||
insertDerivative<t>(std::move(g_yisj));
|
||||
|
||||
Gstack<t>().multAndAdd(1, gss<t>(), *G_yisj_ptr);
|
||||
Gstack<t>().multAndAdd(i + j, gss<t>(), *G_yisj_ptr);
|
||||
Gstack<t>().multAndAdd(i+j, gss<t>(), *G_yisj_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,7 +576,7 @@ template<Storage t>
|
|||
void
|
||||
KOrder::recover_yus(int i, int j, int k)
|
||||
{
|
||||
Symmetry sym {i, j, 0, k};
|
||||
Symmetry sym{i, j, 0, k};
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Recovering symmetry " << sym << endrec;
|
||||
|
||||
|
@ -640,7 +634,7 @@ template<Storage t>
|
|||
void
|
||||
KOrder::recover_s(int i)
|
||||
{
|
||||
Symmetry sym {0, 0, 0, i};
|
||||
Symmetry sym{0, 0, 0, i};
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Recovering symmetry " << sym << endrec;
|
||||
|
||||
|
@ -683,9 +677,9 @@ void
|
|||
KOrder::fillG(int i, int j, int k)
|
||||
{
|
||||
for (int m = 1; m <= k; m++)
|
||||
if (is_even(k - m))
|
||||
if (is_even(k-m))
|
||||
{
|
||||
auto G_yiujupms = faaDiBrunoG<t>(Symmetry {i, j, m, k - m});
|
||||
auto G_yiujupms = faaDiBrunoG<t>(Symmetry{i, j, m, k-m});
|
||||
G<t>().insert(std::move(G_yiujupms));
|
||||
}
|
||||
}
|
||||
|
@ -700,12 +694,12 @@ template<Storage t>
|
|||
typename ctraits<t>::Ttensor
|
||||
KOrder::calcD_ijk(int i, int j, int k) const
|
||||
{
|
||||
typename ctraits<t>::Ttensor res(ny, TensorDimens(Symmetry {i, j, 0, 0}, nvs));
|
||||
typename ctraits<t>::Ttensor res(ny, TensorDimens(Symmetry{i, j, 0, 0}, nvs));
|
||||
res.zeros();
|
||||
if (is_even(k))
|
||||
{
|
||||
auto tmp = faaDiBrunoZ<t>(Symmetry {i, j, k, 0});
|
||||
tmp->contractAndAdd(2, res, m<t>().get(Symmetry {k}));
|
||||
auto tmp = faaDiBrunoZ<t>(Symmetry{i, j, k, 0});
|
||||
tmp->contractAndAdd(2, res, m<t>().get(Symmetry{k}));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -720,13 +714,13 @@ template<Storage t>
|
|||
typename ctraits<t>::Ttensor
|
||||
KOrder::calcE_ijk(int i, int j, int k) const
|
||||
{
|
||||
typename ctraits<t>::Ttensor res(ny, TensorDimens(Symmetry {i, j, 0, 0}, nvs));
|
||||
typename ctraits<t>::Ttensor res(ny, TensorDimens(Symmetry{i, j, 0, 0}, nvs));
|
||||
res.zeros();
|
||||
for (int n = 2; n <= k - 1; n += 2)
|
||||
for (int n = 2; n <= k-1; n += 2)
|
||||
{
|
||||
auto tmp = faaDiBrunoZ<t>(Symmetry {i, j, n, k - n});
|
||||
auto tmp = faaDiBrunoZ<t>(Symmetry{i, j, n, k-n});
|
||||
tmp->mult(static_cast<double>(PascalTriangle::noverk(k, n)));
|
||||
tmp->contractAndAdd(2, res, m<t>().get(Symmetry {n}));
|
||||
tmp->contractAndAdd(2, res, m<t>().get(Symmetry{n}));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -783,24 +777,25 @@ template<Storage t>
|
|||
void
|
||||
KOrder::performStep(int order)
|
||||
{
|
||||
KORD_RAISE_IF(order - 1 != g<t>().getMaxDim(), "Wrong order for KOrder::performStep");
|
||||
KORD_RAISE_IF(order-1 != g<t>().getMaxDim(),
|
||||
"Wrong order for KOrder::performStep");
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Performing step for order = " << order << endrec;
|
||||
|
||||
recover_y<t>(order);
|
||||
|
||||
for (int i = 0; i < order; i++)
|
||||
recover_yu<t>(i, order - i);
|
||||
recover_yu<t>(i, order-i);
|
||||
|
||||
for (int j = 1; j < order; j++)
|
||||
{
|
||||
for (int i = j - 1; i >= 1; i--)
|
||||
recover_yus<t>(order - j, i, j - i);
|
||||
recover_ys<t>(order - j, j);
|
||||
for (int i = j-1; i >= 1; i--)
|
||||
recover_yus<t>(order-j, i, j-i);
|
||||
recover_ys<t>(order-j, j);
|
||||
}
|
||||
|
||||
for (int i = order - 1; i >= 1; i--)
|
||||
recover_yus<t>(0, i, order - i);
|
||||
for (int i = order-1; i >= 1; i--)
|
||||
recover_yus<t>(0, i, order-i);
|
||||
|
||||
recover_s<t>(order);
|
||||
}
|
||||
|
@ -813,7 +808,8 @@ template<Storage t>
|
|||
double
|
||||
KOrder::check(int dim) const
|
||||
{
|
||||
KORD_RAISE_IF(dim > g<t>().getMaxDim(), "Wrong dimension for KOrder::check");
|
||||
KORD_RAISE_IF(dim > g<t>().getMaxDim(),
|
||||
"Wrong dimension for KOrder::check");
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Checking residuals for order = " << dim << endrec;
|
||||
|
||||
|
@ -822,7 +818,7 @@ KOrder::check(int dim) const
|
|||
// Check for F_yⁱuʲ=0
|
||||
for (int i = 0; i <= dim; i++)
|
||||
{
|
||||
Symmetry sym {dim - i, i, 0, 0};
|
||||
Symmetry sym{dim-i, i, 0, 0};
|
||||
auto r = faaDiBrunoZ<t>(sym);
|
||||
double err = r->getData().getMax();
|
||||
JournalRecord(journal) << "\terror for symmetry " << sym << "\tis " << err << endrec;
|
||||
|
@ -830,14 +826,14 @@ KOrder::check(int dim) const
|
|||
}
|
||||
|
||||
// Check for F_yⁱuʲu′ᵏ+Dᵢⱼₖ+Eᵢⱼₖ=0
|
||||
for (auto& si : SymmetrySet(dim, 3))
|
||||
for (auto &si : SymmetrySet(dim, 3))
|
||||
{
|
||||
int i = si[0];
|
||||
int j = si[1];
|
||||
int k = si[2];
|
||||
if (i + j > 0 && k > 0)
|
||||
if (i+j > 0 && k > 0)
|
||||
{
|
||||
Symmetry sym {i, j, 0, k};
|
||||
Symmetry sym{i, j, 0, k};
|
||||
auto r = faaDiBrunoZ<t>(sym);
|
||||
auto D_ijk = calcD_ijk<t>(i, j, k);
|
||||
r->add(1.0, D_ijk);
|
||||
|
@ -850,13 +846,13 @@ KOrder::check(int dim) const
|
|||
}
|
||||
|
||||
// Check for F_σⁱ+Dᵢ+Eᵢ=0
|
||||
auto r = faaDiBrunoZ<t>(Symmetry {0, 0, 0, dim});
|
||||
auto r = faaDiBrunoZ<t>(Symmetry{0, 0, 0, dim});
|
||||
auto D_k = calcD_k<t>(dim);
|
||||
r->add(1.0, D_k);
|
||||
auto E_k = calcE_k<t>(dim);
|
||||
r->add(1.0, E_k);
|
||||
double err = r->getData().getMax();
|
||||
Symmetry sym {0, 0, 0, dim};
|
||||
Symmetry sym{0, 0, 0, dim};
|
||||
JournalRecord(journal) << "\terror for symmetry " << sym << "\tis " << err << endrec;
|
||||
maxerror = std::max(err, maxerror);
|
||||
|
||||
|
@ -874,7 +870,7 @@ KOrder::calcStochShift(int order, double sigma) const
|
|||
if (is_even(j))
|
||||
{
|
||||
auto ten = calcD_k<t>(j);
|
||||
res.add(std::pow(sigma, j) / jfac, ten.getData());
|
||||
res.add(std::pow(sigma, j)/jfac, ten.getData());
|
||||
}
|
||||
return res;
|
||||
}
|
|
@ -23,13 +23,13 @@
|
|||
/* Same as MatrixA constructor, but the submatrix ‘gss_ys’ is passed
|
||||
directly. */
|
||||
|
||||
MatrixAA::MatrixAA(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatrix& gss_ys,
|
||||
const PartitionY& ypart) :
|
||||
PLUMatrix(ypart.ny())
|
||||
MatrixAA::MatrixAA(const FSSparseTensor &f, const IntSequence &ss,
|
||||
const TwoDMatrix &gss_ys, const PartitionY &ypart)
|
||||
: PLUMatrix(ypart.ny())
|
||||
{
|
||||
zeros();
|
||||
|
||||
IntSequence c {1};
|
||||
IntSequence c{1};
|
||||
FGSTensor f_y(f, ss, c, TensorDimens(ss, c));
|
||||
add(1.0, f_y);
|
||||
|
||||
|
@ -42,180 +42,168 @@ MatrixAA::MatrixAA(const FSSparseTensor& f, const IntSequence& ss, const TwoDMat
|
|||
}
|
||||
|
||||
// KOrderStoch folded constructor code
|
||||
KOrderStoch::KOrderStoch(const PartitionY& yp, int nu, const TensorContainer<FSSparseTensor>& fcont,
|
||||
const FGSContainer& hh, Journal& jr) :
|
||||
nvs {yp.nys(), nu, nu, 1},
|
||||
ypart(yp),
|
||||
journal(jr),
|
||||
_ug(4),
|
||||
_fg(4),
|
||||
_ugs(4),
|
||||
_fgs(4),
|
||||
_uG(4),
|
||||
_fG(4),
|
||||
_uh(nullptr),
|
||||
_fh(&hh),
|
||||
KOrderStoch::KOrderStoch(const PartitionY &yp, int nu,
|
||||
const TensorContainer<FSSparseTensor> &fcont,
|
||||
const FGSContainer &hh, Journal &jr)
|
||||
: nvs{yp.nys(), nu, nu, 1}, ypart(yp), journal(jr),
|
||||
_ug(4), _fg(4), _ugs(4), _fgs(4), _uG(4), _fG(4),
|
||||
_uh(nullptr), _fh(&hh),
|
||||
_uZstack(&_uG, ypart.nyss(), &_ug, ypart.ny(), ypart.nys(), nu),
|
||||
_fZstack(&_fG, ypart.nyss(), &_fg, ypart.ny(), ypart.nys(), nu),
|
||||
_uGstack(&_ugs, ypart.nys(), nu),
|
||||
_fGstack(&_fgs, ypart.nys(), nu),
|
||||
f(fcont),
|
||||
matA(fcont.get(Symmetry {1}), _uZstack.getStackSizes(), hh.get(Symmetry {1, 0, 0, 0}), ypart)
|
||||
matA(fcont.get(Symmetry{1}), _uZstack.getStackSizes(), hh.get(Symmetry{1, 0, 0, 0}),
|
||||
ypart)
|
||||
{
|
||||
}
|
||||
|
||||
// KOrderStoch unfolded constructor code
|
||||
KOrderStoch::KOrderStoch(const PartitionY& yp, int nu, const TensorContainer<FSSparseTensor>& fcont,
|
||||
const UGSContainer& hh, Journal& jr) :
|
||||
nvs {yp.nys(), nu, nu, 1},
|
||||
ypart(yp),
|
||||
journal(jr),
|
||||
_ug(4),
|
||||
_fg(4),
|
||||
_ugs(4),
|
||||
_fgs(4),
|
||||
_uG(4),
|
||||
_fG(4),
|
||||
_uh(&hh),
|
||||
_fh(nullptr),
|
||||
KOrderStoch::KOrderStoch(const PartitionY &yp, int nu,
|
||||
const TensorContainer<FSSparseTensor> &fcont,
|
||||
const UGSContainer &hh, Journal &jr)
|
||||
: nvs{yp.nys(), nu, nu, 1}, ypart(yp), journal(jr),
|
||||
_ug(4), _fg(4), _ugs(4), _fgs(4), _uG(4), _fG(4),
|
||||
_uh(&hh), _fh(nullptr),
|
||||
_uZstack(&_uG, ypart.nyss(), &_ug, ypart.ny(), ypart.nys(), nu),
|
||||
_fZstack(&_fG, ypart.nyss(), &_fg, ypart.ny(), ypart.nys(), nu),
|
||||
_uGstack(&_ugs, ypart.nys(), nu),
|
||||
_fGstack(&_fgs, ypart.nys(), nu),
|
||||
f(fcont),
|
||||
matA(fcont.get(Symmetry {1}), _uZstack.getStackSizes(), hh.get(Symmetry {1, 0, 0, 0}), ypart)
|
||||
matA(fcont.get(Symmetry{1}), _uZstack.getStackSizes(), hh.get(Symmetry{1, 0, 0, 0}),
|
||||
ypart)
|
||||
{
|
||||
}
|
||||
|
||||
// KOrderStoch convenience method specializations
|
||||
template<>
|
||||
ctraits<Storage::unfold>::Tg&
|
||||
ctraits<Storage::unfold>::Tg &
|
||||
KOrderStoch::g<Storage::unfold>()
|
||||
{
|
||||
return _ug;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::Tg&
|
||||
const ctraits<Storage::unfold>::Tg &
|
||||
KOrderStoch::g<Storage::unfold>() const
|
||||
{
|
||||
return _ug;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::Tg&
|
||||
ctraits<Storage::fold>::Tg &
|
||||
KOrderStoch::g<Storage::fold>()
|
||||
{
|
||||
return _fg;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::Tg&
|
||||
const ctraits<Storage::fold>::Tg &
|
||||
KOrderStoch::g<Storage::fold>() const
|
||||
{
|
||||
return _fg;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::Tgs&
|
||||
ctraits<Storage::unfold>::Tgs &
|
||||
KOrderStoch::gs<Storage::unfold>()
|
||||
{
|
||||
return _ugs;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::Tgs&
|
||||
const ctraits<Storage::unfold>::Tgs &
|
||||
KOrderStoch::gs<Storage::unfold>() const
|
||||
{
|
||||
return _ugs;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::Tgs&
|
||||
ctraits<Storage::fold>::Tgs &
|
||||
KOrderStoch::gs<Storage::fold>()
|
||||
{
|
||||
return _fgs;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::Tgs&
|
||||
const ctraits<Storage::fold>::Tgs &
|
||||
KOrderStoch::gs<Storage::fold>() const
|
||||
{
|
||||
return _fgs;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::Tgss&
|
||||
const ctraits<Storage::unfold>::Tgss &
|
||||
KOrderStoch::h<Storage::unfold>() const
|
||||
{
|
||||
return *_uh;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::Tgss&
|
||||
const ctraits<Storage::fold>::Tgss &
|
||||
KOrderStoch::h<Storage::fold>() const
|
||||
{
|
||||
return *_fh;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::TG&
|
||||
ctraits<Storage::unfold>::TG &
|
||||
KOrderStoch::G<Storage::unfold>()
|
||||
{
|
||||
return _uG;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::TG&
|
||||
const ctraits<Storage::unfold>::TG &
|
||||
KOrderStoch::G<Storage::unfold>() const
|
||||
{
|
||||
return _uG;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::TG&
|
||||
ctraits<Storage::fold>::TG &
|
||||
KOrderStoch::G<Storage::fold>()
|
||||
{
|
||||
return _fG;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::TG&
|
||||
const ctraits<Storage::fold>::TG &
|
||||
KOrderStoch::G<Storage::fold>() const
|
||||
{
|
||||
return _fG;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::TZXstack&
|
||||
ctraits<Storage::unfold>::TZXstack &
|
||||
KOrderStoch::Zstack<Storage::unfold>()
|
||||
{
|
||||
return _uZstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::TZXstack&
|
||||
const ctraits<Storage::unfold>::TZXstack &
|
||||
KOrderStoch::Zstack<Storage::unfold>() const
|
||||
{
|
||||
return _uZstack;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::TZXstack&
|
||||
ctraits<Storage::fold>::TZXstack &
|
||||
KOrderStoch::Zstack<Storage::fold>()
|
||||
{
|
||||
return _fZstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::TZXstack&
|
||||
const ctraits<Storage::fold>::TZXstack &
|
||||
KOrderStoch::Zstack<Storage::fold>() const
|
||||
{
|
||||
return _fZstack;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::unfold>::TGXstack&
|
||||
ctraits<Storage::unfold>::TGXstack &
|
||||
KOrderStoch::Gstack<Storage::unfold>()
|
||||
{
|
||||
return _uGstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::unfold>::TGXstack&
|
||||
const ctraits<Storage::unfold>::TGXstack &
|
||||
KOrderStoch::Gstack<Storage::unfold>() const
|
||||
{
|
||||
return _uGstack;
|
||||
}
|
||||
template<>
|
||||
ctraits<Storage::fold>::TGXstack&
|
||||
ctraits<Storage::fold>::TGXstack &
|
||||
KOrderStoch::Gstack<Storage::fold>()
|
||||
{
|
||||
return _fGstack;
|
||||
}
|
||||
template<>
|
||||
const ctraits<Storage::fold>::TGXstack&
|
||||
const ctraits<Storage::fold>::TGXstack &
|
||||
KOrderStoch::Gstack<Storage::fold>() const
|
||||
{
|
||||
return _fGstack;
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2023 Dynare Team
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -38,14 +38,11 @@
|
|||
h as an extrapolation based on an approximation to g at lower σ.
|
||||
*/
|
||||
|
||||
#ifndef KORDER_STOCH_HH
|
||||
#define KORDER_STOCH_HH
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "korder.hh"
|
||||
#include "faa_di_bruno.hh"
|
||||
#include "journal.hh"
|
||||
#include "korder.hh"
|
||||
#include "pascal_triangle.hh"
|
||||
|
||||
/* This class is a container, which has a specialized constructor integrating
|
||||
|
@ -55,8 +52,8 @@ template<Storage t>
|
|||
class IntegDerivs : public ctraits<t>::Tgss
|
||||
{
|
||||
public:
|
||||
IntegDerivs(int r, const IntSequence& nvs, const typename ctraits<t>::Tgss& g,
|
||||
const typename ctraits<t>::Tm& mom, double at_sigma);
|
||||
IntegDerivs(int r, const IntSequence &nvs, const typename ctraits<t>::Tgss &g,
|
||||
const typename ctraits<t>::Tm &mom, double at_sigma);
|
||||
};
|
||||
|
||||
/* This constructor integrates a rule (namely its g** part) with respect to
|
||||
|
@ -105,17 +102,17 @@ public:
|
|||
and this is exactly what the code does.
|
||||
*/
|
||||
template<Storage t>
|
||||
IntegDerivs<t>::IntegDerivs(int r, const IntSequence& nvs, const typename ctraits<t>::Tgss& g,
|
||||
const typename ctraits<t>::Tm& mom, double at_sigma) :
|
||||
ctraits<t>::Tgss(4)
|
||||
IntegDerivs<t>::IntegDerivs(int r, const IntSequence &nvs, const typename ctraits<t>::Tgss &g,
|
||||
const typename ctraits<t>::Tm &mom, double at_sigma)
|
||||
: ctraits<t>::Tgss(4)
|
||||
{
|
||||
int maxd = g.getMaxDim();
|
||||
for (int d = 1; d <= maxd; d++)
|
||||
{
|
||||
for (int i = 0; i <= d; i++)
|
||||
{
|
||||
int p = d - i;
|
||||
Symmetry sym {i, 0, 0, p};
|
||||
int p = d-i;
|
||||
Symmetry sym{i, 0, 0, p};
|
||||
auto ten = std::make_unique<typename ctraits<t>::Ttensor>(r, TensorDimens(sym, nvs));
|
||||
|
||||
// Calculate derivative h_yⁱσᵖ
|
||||
|
@ -130,20 +127,20 @@ IntegDerivs<t>::IntegDerivs(int r, const IntSequence& nvs, const typename ctrait
|
|||
ten->zeros();
|
||||
for (int n = 0; n <= p; n++)
|
||||
{
|
||||
int k = p - n;
|
||||
int k = p-n;
|
||||
int povern = PascalTriangle::noverk(p, n);
|
||||
int mfac = 1;
|
||||
for (int m = 0; i + m + n + k <= maxd; m++, mfac *= m)
|
||||
for (int m = 0; i+m+n+k <= maxd; m++, mfac *= m)
|
||||
{
|
||||
double mult = (pow(at_sigma, m) * povern) / mfac;
|
||||
Symmetry sym_mn {i, m + n, 0, k};
|
||||
if (m + n == 0 && g.check(sym_mn))
|
||||
double mult = (pow(at_sigma, m)*povern)/mfac;
|
||||
Symmetry sym_mn{i, m+n, 0, k};
|
||||
if (m+n == 0 && g.check(sym_mn))
|
||||
ten->add(mult, g.get(sym_mn));
|
||||
if (m + n > 0 && KOrder::is_even(m + n) && g.check(sym_mn))
|
||||
if (m+n > 0 && KOrder::is_even(m+n) && g.check(sym_mn))
|
||||
{
|
||||
typename ctraits<t>::Ttensor gtmp(g.get(sym_mn));
|
||||
gtmp.mult(mult);
|
||||
gtmp.contractAndAdd(1, *ten, mom.get(Symmetry {m + n}));
|
||||
gtmp.contractAndAdd(1, *ten, mom.get(Symmetry{m+n}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,8 +160,9 @@ template<Storage t>
|
|||
class StochForwardDerivs : public ctraits<t>::Tgss
|
||||
{
|
||||
public:
|
||||
StochForwardDerivs(const PartitionY& ypart, int nu, const typename ctraits<t>::Tgss& g,
|
||||
const typename ctraits<t>::Tm& m, const Vector& ydelta, double sdelta,
|
||||
StochForwardDerivs(const PartitionY &ypart, int nu,
|
||||
const typename ctraits<t>::Tgss &g, const typename ctraits<t>::Tm &m,
|
||||
const Vector &ydelta, double sdelta,
|
||||
double at_sigma);
|
||||
};
|
||||
|
||||
|
@ -183,11 +181,12 @@ public:
|
|||
— Recover general symmetry tensors from the (full symmetric) polynomial
|
||||
*/
|
||||
template<Storage t>
|
||||
StochForwardDerivs<t>::StochForwardDerivs(const PartitionY& ypart, int nu,
|
||||
const typename ctraits<t>::Tgss& g,
|
||||
const typename ctraits<t>::Tm& m, const Vector& ydelta,
|
||||
double sdelta, double at_sigma) :
|
||||
ctraits<t>::Tgss(4)
|
||||
StochForwardDerivs<t>::StochForwardDerivs(const PartitionY &ypart, int nu,
|
||||
const typename ctraits<t>::Tgss &g,
|
||||
const typename ctraits<t>::Tm &m,
|
||||
const Vector &ydelta, double sdelta,
|
||||
double at_sigma)
|
||||
: ctraits<t>::Tgss(4)
|
||||
{
|
||||
int maxd = g.getMaxDim();
|
||||
int r = ypart.nyss();
|
||||
|
@ -197,21 +196,24 @@ StochForwardDerivs<t>::StochForwardDerivs(const PartitionY& ypart, int nu,
|
|||
the tensors has zero dimensions for shocks, this is because we need to
|
||||
⎡y*⎤
|
||||
make easily stacks of the form ⎣σ ⎦ in the next step. */
|
||||
IntSequence nvs {ypart.nys(), 0, 0, 1};
|
||||
IntSequence nvs{ypart.nys(), 0, 0, 1};
|
||||
IntegDerivs<t> g_int(r, nvs, g, m, at_sigma);
|
||||
|
||||
// Make ‘g_int_sym’ be full symmetric polynomial from ‘g_int’
|
||||
/* Here we just form a polynomial whose unique variable corresponds to
|
||||
⎡y*⎤
|
||||
⎣σ ⎦ stack. */
|
||||
typename ctraits<t>::Tpol g_int_sym(r, ypart.nys() + 1);
|
||||
typename ctraits<t>::Tpol g_int_sym(r, ypart.nys()+1);
|
||||
for (int d = 1; d <= maxd; d++)
|
||||
{
|
||||
auto ten = std::make_unique<typename ctraits<t>::Ttensym>(r, ypart.nys() + 1, d);
|
||||
auto ten = std::make_unique<typename ctraits<t>::Ttensym>(r, ypart.nys()+1, d);
|
||||
ten->zeros();
|
||||
for (int i = 0; i <= d; i++)
|
||||
if (int k {d - i}; g_int.check(Symmetry {i, 0, 0, k}))
|
||||
ten->addSubTensor(g_int.get(Symmetry {i, 0, 0, k}));
|
||||
{
|
||||
int k = d-i;
|
||||
if (g_int.check(Symmetry{i, 0, 0, k}))
|
||||
ten->addSubTensor(g_int.get(Symmetry{i, 0, 0, k}));
|
||||
}
|
||||
g_int_sym.insert(std::move(ten));
|
||||
}
|
||||
|
||||
|
@ -220,15 +222,15 @@ StochForwardDerivs<t>::StochForwardDerivs(const PartitionY& ypart, int nu,
|
|||
was centralized about (ỹ,σ~). This is done by derivating and evaluating
|
||||
the derivated polynomial at (ȳ−ỹ,σ¯-σ~). The stack of this vector is
|
||||
‘delta’ in the code. */
|
||||
Vector delta(ypart.nys() + 1);
|
||||
Vector delta(ypart.nys()+1);
|
||||
Vector dy(delta, 0, ypart.nys());
|
||||
ConstVector dy_in(ydelta, ypart.nstat, ypart.nys());
|
||||
dy = dy_in;
|
||||
delta[ypart.nys()] = sdelta;
|
||||
typename ctraits<t>::Tpol g_int_cent(r, ypart.nys() + 1);
|
||||
typename ctraits<t>::Tpol g_int_cent(r, ypart.nys()+1);
|
||||
for (int d = 1; d <= maxd; d++)
|
||||
{
|
||||
g_int_sym.derivative(d - 1);
|
||||
g_int_sym.derivative(d-1);
|
||||
auto der = g_int_sym.evalPartially(d, delta);
|
||||
g_int_cent.insert(std::move(der));
|
||||
}
|
||||
|
@ -236,19 +238,20 @@ StochForwardDerivs<t>::StochForwardDerivs(const PartitionY& ypart, int nu,
|
|||
// Pull out general symmetry tensors from ‘g_int_cent’
|
||||
/* Here we only recover the general symmetry derivatives from the full
|
||||
symmetric polynomial. Note that the derivative get the true ‘nvs’. */
|
||||
IntSequence ss {ypart.nys(), 0, 0, 1};
|
||||
IntSequence pp {0, 1, 2, 3};
|
||||
IntSequence ss{ypart.nys(), 0, 0, 1};
|
||||
IntSequence pp{0, 1, 2, 3};
|
||||
IntSequence true_nvs(nvs);
|
||||
true_nvs[1] = nu;
|
||||
true_nvs[2] = nu;
|
||||
for (int d = 1; d <= maxd; d++)
|
||||
if (g_int_cent.check(Symmetry {d}))
|
||||
if (g_int_cent.check(Symmetry{d}))
|
||||
for (int i = 0; i <= d; i++)
|
||||
{
|
||||
Symmetry sym {i, 0, 0, d - i};
|
||||
Symmetry sym{i, 0, 0, d-i};
|
||||
IntSequence coor(pp.unfold(sym));
|
||||
auto ten = std::make_unique<typename ctraits<t>::Ttensor>(
|
||||
g_int_cent.get(Symmetry {d}), ss, coor, TensorDimens(sym, true_nvs));
|
||||
auto ten = std::make_unique<typename ctraits<t>::Ttensor>(g_int_cent.get(Symmetry{d}),
|
||||
ss, coor,
|
||||
TensorDimens(sym, true_nvs));
|
||||
this->insert(std::move(ten));
|
||||
}
|
||||
}
|
||||
|
@ -264,10 +267,11 @@ public:
|
|||
using _Stype = StackContainerInterface<_Ttype>;
|
||||
using _Ctype = typename StackContainer<_Ttype>::_Ctype;
|
||||
using itype = typename StackContainer<_Ttype>::itype;
|
||||
GXContainer(const _Ctype* gs, int ngs, int nu) : GContainer<_Ttype>(gs, ngs, nu)
|
||||
GXContainer(const _Ctype *gs, int ngs, int nu)
|
||||
: GContainer<_Ttype>(gs, ngs, nu)
|
||||
{
|
||||
}
|
||||
itype getType(int i, const Symmetry& s) const override;
|
||||
itype getType(int i, const Symmetry &s) const override;
|
||||
};
|
||||
|
||||
/* This routine corresponds to this stack:
|
||||
|
@ -278,26 +282,22 @@ public:
|
|||
*/
|
||||
template<class _Ttype>
|
||||
typename GXContainer<_Ttype>::itype
|
||||
GXContainer<_Ttype>::getType(int i, const Symmetry& s) const
|
||||
GXContainer<_Ttype>::getType(int i, const Symmetry &s) const
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
}
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
if (i == 1)
|
||||
return itype::zero;
|
||||
if (i == 2)
|
||||
return itype::zero;
|
||||
if (i == 3)
|
||||
{
|
||||
if (s == Symmetry {0, 0, 0, 1})
|
||||
return itype::unit;
|
||||
else
|
||||
return itype::zero;
|
||||
}
|
||||
if (s == Symmetry{0, 0, 0, 1})
|
||||
return itype::unit;
|
||||
else
|
||||
return itype::zero;
|
||||
|
||||
KORD_RAISE("Wrong stack index in GXContainer::getType");
|
||||
}
|
||||
|
@ -313,11 +313,11 @@ public:
|
|||
using _Stype = StackContainerInterface<_Ttype>;
|
||||
using _Ctype = typename StackContainer<_Ttype>::_Ctype;
|
||||
using itype = typename StackContainer<_Ttype>::itype;
|
||||
ZXContainer(const _Ctype* gss, int ngss, const _Ctype* g, int ng, int ny, int nu) :
|
||||
ZContainer<_Ttype>(gss, ngss, g, ng, ny, nu)
|
||||
ZXContainer(const _Ctype *gss, int ngss, const _Ctype *g, int ng, int ny, int nu)
|
||||
: ZContainer<_Ttype>(gss, ngss, g, ng, ny, nu)
|
||||
{
|
||||
}
|
||||
itype getType(int i, const Symmetry& s) const override;
|
||||
itype getType(int i, const Symmetry &s) const override;
|
||||
};
|
||||
|
||||
/* This getType() method corresponds to this stack:
|
||||
|
@ -328,36 +328,28 @@ public:
|
|||
*/
|
||||
template<class _Ttype>
|
||||
typename ZXContainer<_Ttype>::itype
|
||||
ZXContainer<_Ttype>::getType(int i, const Symmetry& s) const
|
||||
ZXContainer<_Ttype>::getType(int i, const Symmetry &s) const
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
}
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
if (i == 1)
|
||||
{
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
}
|
||||
if (s[2] > 0)
|
||||
return itype::zero;
|
||||
else
|
||||
return itype::matrix;
|
||||
if (i == 2)
|
||||
{
|
||||
if (s == Symmetry {1, 0, 0, 0})
|
||||
return itype::unit;
|
||||
else
|
||||
return itype::zero;
|
||||
}
|
||||
if (s == Symmetry{1, 0, 0, 0})
|
||||
return itype::unit;
|
||||
else
|
||||
return itype::zero;
|
||||
if (i == 3)
|
||||
{
|
||||
if (s == Symmetry {0, 1, 0, 0})
|
||||
return itype::unit;
|
||||
else
|
||||
return itype::zero;
|
||||
}
|
||||
if (s == Symmetry{0, 1, 0, 0})
|
||||
return itype::unit;
|
||||
else
|
||||
return itype::zero;
|
||||
|
||||
KORD_RAISE("Wrong stack index in ZXContainer::getType");
|
||||
}
|
||||
|
@ -366,7 +358,8 @@ class UnfoldedGXContainer : public GXContainer<UGSTensor>, public UnfoldedStackC
|
|||
{
|
||||
public:
|
||||
using _Ctype = TensorContainer<UGSTensor>;
|
||||
UnfoldedGXContainer(const _Ctype* gs, int ngs, int nu) : GXContainer<UGSTensor>(gs, ngs, nu)
|
||||
UnfoldedGXContainer(const _Ctype *gs, int ngs, int nu)
|
||||
: GXContainer<UGSTensor>(gs, ngs, nu)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -375,7 +368,8 @@ class FoldedGXContainer : public GXContainer<FGSTensor>, public FoldedStackConta
|
|||
{
|
||||
public:
|
||||
using _Ctype = TensorContainer<FGSTensor>;
|
||||
FoldedGXContainer(const _Ctype* gs, int ngs, int nu) : GXContainer<FGSTensor>(gs, ngs, nu)
|
||||
FoldedGXContainer(const _Ctype *gs, int ngs, int nu)
|
||||
: GXContainer<FGSTensor>(gs, ngs, nu)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -384,8 +378,8 @@ class UnfoldedZXContainer : public ZXContainer<UGSTensor>, public UnfoldedStackC
|
|||
{
|
||||
public:
|
||||
using _Ctype = TensorContainer<UGSTensor>;
|
||||
UnfoldedZXContainer(const _Ctype* gss, int ngss, const _Ctype* g, int ng, int ny, int nu) :
|
||||
ZXContainer<UGSTensor>(gss, ngss, g, ng, ny, nu)
|
||||
UnfoldedZXContainer(const _Ctype *gss, int ngss, const _Ctype *g, int ng, int ny, int nu)
|
||||
: ZXContainer<UGSTensor>(gss, ngss, g, ng, ny, nu)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -394,8 +388,8 @@ class FoldedZXContainer : public ZXContainer<FGSTensor>, public FoldedStackConta
|
|||
{
|
||||
public:
|
||||
using _Ctype = TensorContainer<FGSTensor>;
|
||||
FoldedZXContainer(const _Ctype* gss, int ngss, const _Ctype* g, int ng, int ny, int nu) :
|
||||
ZXContainer<FGSTensor>(gss, ngss, g, ng, ny, nu)
|
||||
FoldedZXContainer(const _Ctype *gss, int ngss, const _Ctype *g, int ng, int ny, int nu)
|
||||
: ZXContainer<FGSTensor>(gss, ngss, g, ng, ny, nu)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -411,8 +405,8 @@ public:
|
|||
class MatrixAA : public PLUMatrix
|
||||
{
|
||||
public:
|
||||
MatrixAA(const FSSparseTensor& f, const IntSequence& ss, const TwoDMatrix& gyss,
|
||||
const PartitionY& ypart);
|
||||
MatrixAA(const FSSparseTensor &f, const IntSequence &ss,
|
||||
const TwoDMatrix &gyss, const PartitionY &ypart);
|
||||
};
|
||||
|
||||
/* This class calculates derivatives of g given implicitly by
|
||||
|
@ -432,79 +426,77 @@ class KOrderStoch
|
|||
protected:
|
||||
IntSequence nvs;
|
||||
PartitionY ypart;
|
||||
Journal& journal;
|
||||
Journal &journal;
|
||||
UGSContainer _ug;
|
||||
FGSContainer _fg;
|
||||
UGSContainer _ugs;
|
||||
FGSContainer _fgs;
|
||||
UGSContainer _uG;
|
||||
FGSContainer _fG;
|
||||
const UGSContainer* _uh;
|
||||
const FGSContainer* _fh;
|
||||
const UGSContainer *_uh;
|
||||
const FGSContainer *_fh;
|
||||
UnfoldedZXContainer _uZstack;
|
||||
FoldedZXContainer _fZstack;
|
||||
UnfoldedGXContainer _uGstack;
|
||||
FoldedGXContainer _fGstack;
|
||||
const TensorContainer<FSSparseTensor>& f;
|
||||
const TensorContainer<FSSparseTensor> &f;
|
||||
MatrixAA matA;
|
||||
|
||||
public:
|
||||
KOrderStoch(const PartitionY& ypart, int nu, const TensorContainer<FSSparseTensor>& fcont,
|
||||
const FGSContainer& hh, Journal& jr);
|
||||
KOrderStoch(const PartitionY& ypart, int nu, const TensorContainer<FSSparseTensor>& fcont,
|
||||
const UGSContainer& hh, Journal& jr);
|
||||
KOrderStoch(const PartitionY &ypart, int nu, const TensorContainer<FSSparseTensor> &fcont,
|
||||
const FGSContainer &hh, Journal &jr);
|
||||
KOrderStoch(const PartitionY &ypart, int nu, const TensorContainer<FSSparseTensor> &fcont,
|
||||
const UGSContainer &hh, Journal &jr);
|
||||
template<Storage t>
|
||||
void performStep(int order);
|
||||
[[nodiscard]] const FGSContainer&
|
||||
const FGSContainer &
|
||||
getFoldDers() const
|
||||
{
|
||||
return _fg;
|
||||
}
|
||||
[[nodiscard]] const UGSContainer&
|
||||
const UGSContainer &
|
||||
getUnfoldDers() const
|
||||
{
|
||||
return _ug;
|
||||
}
|
||||
[[nodiscard]] const FGSContainer&
|
||||
const FGSContainer &
|
||||
getFoldDersS() const
|
||||
{
|
||||
return _fgs;
|
||||
}
|
||||
|
||||
protected:
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoZ(const Symmetry& sym) const;
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoZ(const Symmetry &sym) const;
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoG(const Symmetry& sym) const;
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoG(const Symmetry &sym) const;
|
||||
|
||||
// Convenience access methods
|
||||
template<Storage t>
|
||||
typename ctraits<t>::Tg& g();
|
||||
typename ctraits<t>::Tg &g();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::Tg& g() const;
|
||||
const typename ctraits<t>::Tg &g() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::Tgs& gs();
|
||||
typename ctraits<t>::Tgs &gs();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::Tgs& gs() const;
|
||||
const typename ctraits<t>::Tgs &gs() const;
|
||||
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::Tgss& h() const;
|
||||
const typename ctraits<t>::Tgss &h() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::TG& G();
|
||||
typename ctraits<t>::TG &G();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::TG& G() const;
|
||||
const typename ctraits<t>::TG &G() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::TZXstack& Zstack();
|
||||
typename ctraits<t>::TZXstack &Zstack();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::TZXstack& Zstack() const;
|
||||
const typename ctraits<t>::TZXstack &Zstack() const;
|
||||
|
||||
template<Storage t>
|
||||
typename ctraits<t>::TGXstack& Gstack();
|
||||
typename ctraits<t>::TGXstack &Gstack();
|
||||
template<Storage t>
|
||||
const typename ctraits<t>::TGXstack& Gstack() const;
|
||||
const typename ctraits<t>::TGXstack &Gstack() const;
|
||||
};
|
||||
|
||||
/* This calculates a derivative of f(G(y,u,σ),g(y,u,σ),y,u) of a given
|
||||
|
@ -512,7 +504,7 @@ protected:
|
|||
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor>
|
||||
KOrderStoch::faaDiBrunoZ(const Symmetry& sym) const
|
||||
KOrderStoch::faaDiBrunoZ(const Symmetry &sym) const
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Faà Di Bruno ZX container for " << sym << endrec;
|
||||
|
@ -527,7 +519,7 @@ KOrderStoch::faaDiBrunoZ(const Symmetry& sym) const
|
|||
|
||||
template<Storage t>
|
||||
std::unique_ptr<typename ctraits<t>::Ttensor>
|
||||
KOrderStoch::faaDiBrunoG(const Symmetry& sym) const
|
||||
KOrderStoch::faaDiBrunoG(const Symmetry &sym) const
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Faà Di Bruno GX container for " << sym << endrec;
|
||||
|
@ -553,9 +545,9 @@ void
|
|||
KOrderStoch::performStep(int order)
|
||||
{
|
||||
int maxd = g<t>().getMaxDim();
|
||||
KORD_RAISE_IF(order - 1 != maxd && (order != 1 || maxd != -1),
|
||||
KORD_RAISE_IF(order-1 != maxd && (order != 1 || maxd != -1),
|
||||
"Wrong order for KOrderStoch::performStep");
|
||||
for (auto& si : SymmetrySet(order, 4))
|
||||
for (auto &si : SymmetrySet(order, 4))
|
||||
if (si[2] == 0)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
|
@ -570,11 +562,9 @@ KOrderStoch::performStep(int order)
|
|||
g_sym->mult(-1.0);
|
||||
matA.multInv(*g_sym);
|
||||
g<t>().insert(std::move(g_sym));
|
||||
gs<t>().insert(
|
||||
std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat, ypart.nys(), *g_sym_ptr));
|
||||
gs<t>().insert(std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat, ypart.nys(),
|
||||
*g_sym_ptr));
|
||||
|
||||
Gstack<t>().multAndAdd(1, h<t>(), *G_sym_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright © 2007 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "normal_conjugate.hh"
|
||||
#include "kord_exception.hh"
|
||||
|
||||
// NormalConj diffuse prior constructor
|
||||
NormalConj::NormalConj(int d)
|
||||
: mu(d), kappa(0), nu(-1), lambda(d, d)
|
||||
{
|
||||
mu.zeros();
|
||||
lambda.zeros();
|
||||
}
|
||||
|
||||
// NormalConj data update constructor
|
||||
NormalConj::NormalConj(const ConstTwoDMatrix &ydata)
|
||||
: mu(ydata.nrows()), kappa(ydata.ncols()), nu(ydata.ncols()-1),
|
||||
lambda(ydata.nrows(), ydata.nrows())
|
||||
{
|
||||
mu.zeros();
|
||||
for (int i = 0; i < ydata.ncols(); i++)
|
||||
mu.add(1.0/ydata.ncols(), ydata.getCol(i));
|
||||
|
||||
lambda.zeros();
|
||||
for (int i = 0; i < ydata.ncols(); i++)
|
||||
{
|
||||
Vector diff{ydata.getCol(i)};
|
||||
diff.add(-1, mu);
|
||||
lambda.addOuter(diff);
|
||||
}
|
||||
}
|
||||
|
||||
// NormalConj::update() one observation code
|
||||
/* The method performs the following:
|
||||
|
||||
κ₀ 1
|
||||
μ₁ = ──── μ₀ + ──── y
|
||||
κ₀+1 κ₀+1
|
||||
|
||||
κ₁ = κ₀ + 1
|
||||
|
||||
ν₁ = ν₀ + 1
|
||||
|
||||
κ₀
|
||||
Λ₁ = Λ₀ + ──── (y − μ₀)(y − μ₀)ᵀ
|
||||
κ₀+1
|
||||
*/
|
||||
void
|
||||
NormalConj::update(const ConstVector &y)
|
||||
{
|
||||
KORD_RAISE_IF(y.length() != mu.length(),
|
||||
"Wrong length of a vector in NormalConj::update");
|
||||
|
||||
mu.mult(kappa/(1.0+kappa));
|
||||
mu.add(1.0/(1.0+kappa), y);
|
||||
|
||||
Vector diff(y);
|
||||
diff.add(-1, mu);
|
||||
lambda.addOuter(diff, kappa/(1.0+kappa));
|
||||
|
||||
kappa++;
|
||||
nu++;
|
||||
}
|
||||
|
||||
// NormalConj::update() multiple observations code
|
||||
/* The method evaluates the formula in the header file. */
|
||||
void
|
||||
NormalConj::update(const ConstTwoDMatrix &ydata)
|
||||
{
|
||||
NormalConj nc(ydata);
|
||||
update(nc);
|
||||
}
|
||||
|
||||
// NormalConj::update() with NormalConj code
|
||||
void
|
||||
NormalConj::update(const NormalConj &nc)
|
||||
{
|
||||
double wold = static_cast<double>(kappa)/(kappa+nc.kappa);
|
||||
double wnew = 1-wold;
|
||||
|
||||
mu.mult(wold);
|
||||
mu.add(wnew, nc.mu);
|
||||
|
||||
Vector diff(nc.mu);
|
||||
diff.add(-1, mu);
|
||||
lambda.add(1.0, nc.lambda);
|
||||
lambda.addOuter(diff);
|
||||
|
||||
kappa = kappa + nc.kappa;
|
||||
nu = nu + nc.kappa;
|
||||
}
|
||||
|
||||
/* This returns 1/(ν−d−1)·Λ, which is the mean of the variance in the posterior
|
||||
distribution. If the number of degrees of freedom is less than d, then NaNs
|
||||
are returned. */
|
||||
void
|
||||
NormalConj::getVariance(TwoDMatrix &v) const
|
||||
{
|
||||
if (nu > getDim()+1)
|
||||
{
|
||||
v = const_cast<const TwoDMatrix &>(lambda);
|
||||
v.mult(1.0/(nu-getDim()-1));
|
||||
}
|
||||
else
|
||||
v.nans();
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright © 2007 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Conjugate family for normal distribution
|
||||
|
||||
/* The main purpose here is to implement a class representing conjugate
|
||||
distributions for mean and variance of the normal distribution. The class
|
||||
has two main methods: the first one is to update itself with respect to one
|
||||
observation, the second one is to update itself with respect to anothe
|
||||
object of the class. In the both methods, the previous state of the class
|
||||
corresponds to the prior distribution, and the final state corresponds to
|
||||
the posterior distribution.
|
||||
|
||||
The algebra can be found in Gelman, Carlin, Stern, Rubin (p.87). It goes as
|
||||
follows. Prior conjugate distribution takes the following form:
|
||||
|
||||
Σ ↝ InvWishart_ν₀(Λ₀⁻¹)
|
||||
μ|Σ ↝ 𝒩(μ₀,Σ/κ₀)
|
||||
|
||||
If the observations are y₁…yₙ, then the posterior distribution has the same
|
||||
form with the following parameters:
|
||||
|
||||
κ₀ n
|
||||
μₙ = ──── μ₀ + ──── ȳ
|
||||
κ₀+n κ₀+n
|
||||
|
||||
κₙ = κ₀ + n
|
||||
|
||||
νₙ = ν₀ + n
|
||||
|
||||
κ₀·n
|
||||
Λₙ = Λ₀ + S + ──── (ȳ − μ₀)(ȳ − μ₀)ᵀ
|
||||
κ₀+n
|
||||
|
||||
where
|
||||
|
||||
1 ₙ
|
||||
ȳ = ─ ∑ yᵢ
|
||||
n ⁱ⁼¹
|
||||
|
||||
ₙ
|
||||
S = ∑ (yᵢ − ȳ)(yᵢ − ȳ)ᵀ
|
||||
ⁱ⁼¹
|
||||
*/
|
||||
|
||||
#ifndef NORMAL_CONJUGATE_H
|
||||
#define NORMAL_CONJUGATE_H
|
||||
|
||||
#include "twod_matrix.hh"
|
||||
|
||||
/* The class is described by the four parameters: μ, κ, ν and Λ. */
|
||||
|
||||
class NormalConj
|
||||
{
|
||||
protected:
|
||||
Vector mu;
|
||||
int kappa;
|
||||
int nu;
|
||||
TwoDMatrix lambda;
|
||||
public:
|
||||
/* We provide the following constructors: The first constructs diffuse
|
||||
(Jeffrey’s) prior. It sets κ and Λ to zeros, ν to −1 and also the mean μ
|
||||
to zero (it should not be referenced). The second constructs the posterior
|
||||
using the diffuse prior and the observed data (columnwise). The third is a
|
||||
copy constructor. */
|
||||
NormalConj(int d);
|
||||
NormalConj(const ConstTwoDMatrix &ydata);
|
||||
NormalConj(const NormalConj &) = default;
|
||||
NormalConj(NormalConj &&) = default;
|
||||
|
||||
virtual ~NormalConj() = default;
|
||||
void update(const ConstVector &y);
|
||||
void update(const ConstTwoDMatrix &ydata);
|
||||
void update(const NormalConj &nc);
|
||||
int
|
||||
getDim() const
|
||||
{
|
||||
return mu.length();
|
||||
}
|
||||
const Vector &
|
||||
getMean() const
|
||||
{
|
||||
return mu;
|
||||
}
|
||||
void getVariance(TwoDMatrix &v) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "seed_generator.hh"
|
||||
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
|
||||
namespace seed_generator
|
||||
{
|
||||
std::mutex mut;
|
||||
|
||||
std::mt19937 rng;
|
||||
|
||||
std::uniform_int_distribution<std::mt19937::result_type> seed_generator(std::numeric_limits<std::mt19937::result_type>::min(),
|
||||
std::numeric_limits<std::mt19937::result_type>::max());
|
||||
|
||||
std::mt19937::result_type
|
||||
get_new_seed()
|
||||
{
|
||||
std::lock_guard<std::mutex> lk{mut};
|
||||
return seed_generator(rng);
|
||||
}
|
||||
|
||||
void
|
||||
set_meta_seed(std::mt19937::result_type s)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk{mut};
|
||||
rng.seed(s);
|
||||
}
|
||||
};
|
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
|
@ -18,14 +17,18 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dynamic_model.hh"
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
void
|
||||
NameList::print() const
|
||||
namespace seed_generator
|
||||
{
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
std::cout << getName(i) << '\n';
|
||||
}
|
||||
// Produces seeds that can be used with Mersenne-Twister generators (thread-safe)
|
||||
std::mt19937::result_type get_new_seed();
|
||||
|
||||
// Sets the seed for the seed generator (!)
|
||||
void set_meta_seed(std::mt19937::result_type s);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "korder.hh"
|
||||
#include "SylvException.hh"
|
||||
|
||||
struct Rand
|
||||
{
|
||||
static std::mt19937 mtgen;
|
||||
static std::uniform_real_distribution<> dis;
|
||||
static void init(int n1, int n2, int n3, int n4, int n5);
|
||||
static double get(double m);
|
||||
static int get(int m);
|
||||
static bool discrete(double prob); // answers true with given probability
|
||||
};
|
||||
|
||||
std::mt19937 Rand::mtgen;
|
||||
std::uniform_real_distribution<> Rand::dis;
|
||||
|
||||
ConstTwoDMatrix
|
||||
make_matrix(int rows, int cols, const double *p)
|
||||
{
|
||||
return ConstTwoDMatrix{rows, cols, ConstVector{p, rows*cols}};
|
||||
}
|
||||
|
||||
void
|
||||
Rand::init(int n1, int n2, int n3, int n4, int n5)
|
||||
{
|
||||
decltype(mtgen)::result_type seed = n1;
|
||||
seed = 256*seed+n2;
|
||||
seed = 256*seed+n3;
|
||||
seed = 256*seed+n4;
|
||||
seed = 256*seed+n5;
|
||||
mtgen.seed(seed);
|
||||
}
|
||||
|
||||
double
|
||||
Rand::get(double m)
|
||||
{
|
||||
return 2*m*(dis(mtgen)-0.5);
|
||||
}
|
||||
|
||||
int
|
||||
Rand::get(int m)
|
||||
{
|
||||
return static_cast<int>(get(0.9999*m));
|
||||
}
|
||||
|
||||
bool
|
||||
Rand::discrete(double prob)
|
||||
{
|
||||
return dis(mtgen) < prob;
|
||||
}
|
||||
|
||||
struct SparseGenerator
|
||||
{
|
||||
static std::unique_ptr<FSSparseTensor> makeTensor(int dim, int nv, int r,
|
||||
double fill, double m);
|
||||
static void fillContainer(TensorContainer<FSSparseTensor> &c,
|
||||
int maxdim, int nv, int r, double m);
|
||||
};
|
||||
|
||||
std::unique_ptr<FSSparseTensor>
|
||||
SparseGenerator::makeTensor(int dim, int nv, int r,
|
||||
double fill, double m)
|
||||
{
|
||||
auto res = std::make_unique<FSSparseTensor>(dim, nv, r);
|
||||
FFSTensor dummy(0, nv, dim);
|
||||
for (Tensor::index fi = dummy.begin(); fi != dummy.end(); ++fi)
|
||||
for (int i = 0; i < r; i++)
|
||||
if (Rand::discrete(fill))
|
||||
{
|
||||
double x = Rand::get(m);
|
||||
res->insert(fi.getCoor(), i, x);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
SparseGenerator::fillContainer(TensorContainer<FSSparseTensor> &c,
|
||||
int maxdim, int nv, int r,
|
||||
double m)
|
||||
{
|
||||
Rand::init(maxdim, nv, r, static_cast<int>(5*m), 0);
|
||||
double fill = 0.5;
|
||||
for (int d = 1; d <= maxdim; d++)
|
||||
{
|
||||
c.insert(makeTensor(d, nv, r, fill, m));
|
||||
fill *= 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
const double vdata[] =
|
||||
{ // 3x3
|
||||
0.1307870268, 0.1241940078, 0.1356703123,
|
||||
0.1241940078, 0.1986920419, 0.2010160581,
|
||||
0.1356703123, 0.2010160581, 0.2160336975
|
||||
};
|
||||
|
||||
const double gy_data[] =
|
||||
{ // 8x4
|
||||
0.3985178619, -0.5688233582, 0.9572900437, -0.6606847776, 0.1453004017,
|
||||
0.3025310675, -0.8627437750, -0.6903410191, 0.4751910580, -0.7270018589,
|
||||
-0.0939612498, -0.1463831989, 0.6742110220, 0.6046671043, 0.5215893126,
|
||||
-1.0412969986, -0.3524898417, -1.0986703430, 0.8006531522, 0.8879776376,
|
||||
-0.1037608317, -0.5587378073, -0.1010366945, 0.9462411248, -0.2439199881,
|
||||
1.3420621236, -0.7820285935, 0.3205293447, 0.3606124791, 0.2975422208,
|
||||
-0.5452861965, 1.6320340279
|
||||
};
|
||||
|
||||
const double gu_data[] =
|
||||
{ // just some numbers, no structure
|
||||
1.8415286914, -0.2638743845, 1.7690713274, 0.9668585956, 0.2303143646,
|
||||
-0.2229624279, -0.4381991822, 1.0082401405, -0.3186555860, -0.0624691529,
|
||||
-0.5189085756, 1.4269672156, 0.1163282969, 1.4020183445, -0.0952660426,
|
||||
0.2099097124, 0.6912400502, -0.5180935114, 0.5288316624, 0.2188053448,
|
||||
0.5715516767, 0.7813893410, -0.6385073106, 0.8335131513, 0.3605202168,
|
||||
-1.1167944865, -1.2263750934, 0.6113636081, 0.6964915482, -0.6451217688,
|
||||
0.4062810500, -2.0552251116, -1.6383406284, 0.0198915095, 0.0111014458,
|
||||
-1.2421792262, -1.0724161722, -0.4276904972, 0.1801494950, -2.0716473264
|
||||
};
|
||||
|
||||
const double vdata2[] =
|
||||
{ // 10×10 positive definite
|
||||
0.79666, -0.15536, 0.05667, -0.21026, 0.20262, 0.28505, 0.60341, -0.09703, 0.32363, 0.13299,
|
||||
-0.15536, 0.64380, -0.01131, 0.00980, 0.03755, 0.43791, 0.21784, -0.31755, -0.55911, -0.29655,
|
||||
0.05667, -0.01131, 0.56165, -0.34357, -0.40584, 0.20990, 0.28348, 0.20398, -0.19856, 0.35820,
|
||||
-0.21026, 0.00980, -0.34357, 0.56147, 0.10972, -0.34146, -0.49906, -0.19685, 0.21088, -0.31560,
|
||||
0.20262, 0.03755, -0.40584, 0.10972, 0.72278, 0.02155, 0.04089, -0.19696, 0.03446, -0.12919,
|
||||
0.28505, 0.43791, 0.20990, -0.34146, 0.02155, 0.75867, 0.77699, -0.31125, -0.55141, -0.02155,
|
||||
0.60341, 0.21784, 0.28348, -0.49906, 0.04089, 0.77699, 1.34553, -0.18613, -0.25811, -0.19016,
|
||||
-0.09703, -0.31755, 0.20398, -0.19685, -0.19696, -0.31125, -0.18613, 0.59470, 0.08386, 0.41750,
|
||||
0.32363, -0.55911, -0.19856, 0.21088, 0.03446, -0.55141, -0.25811, 0.08386, 0.98917, -0.12992,
|
||||
0.13299, -0.29655, 0.35820, -0.31560, -0.12919, -0.02155, -0.19016, 0.41750, -0.12992, 0.89608
|
||||
};
|
||||
|
||||
const double gy_data2[] =
|
||||
{ // 600 items make gy 30×20, whose gy(6:25,:) has spectrum within unit
|
||||
0.39414, -0.29766, 0.08948, -0.19204, -0.00750, 0.21159, 0.05494, 0.06225, 0.01771, 0.21913,
|
||||
-0.01373, 0.20086, -0.06086, -0.10955, 0.14424, -0.08390, 0.03948, -0.14713, 0.11674, 0.05091,
|
||||
0.24039, 0.28307, -0.11835, 0.13030, 0.11682, -0.27444, -0.19311, -0.16654, 0.12867, 0.25116,
|
||||
-0.19781, 0.45242, -0.15862, 0.24428, -0.11966, 0.11483, -0.32279, 0.29727, 0.20934, -0.18190,
|
||||
-0.15080, -0.09477, -0.30551, -0.02672, -0.26919, 0.11165, -0.06390, 0.03449, -0.26622, 0.22197,
|
||||
0.45141, -0.41683, 0.09760, 0.31094, -0.01652, 0.05809, -0.04514, -0.05645, 0.00554, 0.47980,
|
||||
0.11726, 0.42459, -0.13136, -0.30902, -0.14648, 0.11455, 0.02947, -0.03835, -0.04044, 0.03559,
|
||||
-0.26575, -0.01783, 0.31243, -0.14412, -0.13218, -0.05080, 0.18576, 0.13840, -0.05560, 0.35530,
|
||||
-0.25573, -0.11560, 0.15187, -0.18431, 0.08193, -0.32278, 0.17560, -0.05529, -0.10020, -0.23088,
|
||||
-0.20979, -0.49245, 0.09915, -0.16909, -0.03443, 0.19497, 0.18473, 0.25662, 0.29605, -0.20531,
|
||||
-0.39244, -0.43369, 0.05588, 0.24823, -0.14236, -0.08311, 0.16371, -0.19975, 0.30605, -0.17087,
|
||||
-0.01270, 0.00123, -0.22426, -0.13810, 0.05079, 0.06971, 0.01922, -0.09952, -0.23177, -0.41962,
|
||||
-0.41991, 0.41430, -0.04247, -0.13706, -0.12048, -0.28906, -0.22813, -0.25057, -0.18579, -0.20642,
|
||||
-0.47976, 0.25490, -0.05138, -0.30794, 0.31651, 0.02034, 0.12954, -0.20110, 0.13336, -0.40775,
|
||||
-0.30195, -0.13704, 0.12396, 0.28152, 0.02986, 0.27669, 0.24623, 0.08635, -0.11956, -0.02949,
|
||||
0.37401, 0.20838, 0.24801, -0.26872, 0.11195, 0.00315, -0.19069, 0.12839, -0.23036, -0.48228,
|
||||
0.08434, -0.39872, -0.28896, -0.28754, 0.24668, 0.23285, 0.25437, 0.10456, -0.14124, 0.20483,
|
||||
-0.19117, -0.33836, -0.24875, 0.08207, -0.03930, 0.20364, 0.15384, -0.15270, 0.24372, -0.11199,
|
||||
-0.46591, 0.30319, 0.05745, 0.09084, 0.06058, 0.31884, 0.05071, -0.28899, -0.30793, -0.03566,
|
||||
0.02286, 0.28178, 0.00736, -0.31378, -0.18144, -0.22346, -0.27239, 0.31043, -0.26228, 0.22181,
|
||||
-0.15096, -0.36953, -0.06032, 0.21496, 0.29545, -0.13112, 0.16420, -0.07573, -0.43111, -0.43057,
|
||||
0.26716, -0.31209, -0.05866, -0.29101, -0.27437, -0.18727, 0.28732, -0.19014, 0.08837, 0.30405,
|
||||
0.06103, -0.35612, 0.00173, 0.25134, -0.08987, -0.22766, -0.03254, -0.18662, -0.08491, 0.49401,
|
||||
-0.12145, -0.02961, -0.03668, -0.30043, -0.08555, 0.01701, -0.12544, 0.10969, -0.48202, 0.07245,
|
||||
0.20673, 0.11408, 0.04343, -0.01815, -0.31594, -0.23632, -0.06258, -0.27474, 0.12180, 0.16613,
|
||||
-0.37931, 0.30219, 0.15765, 0.25489, 0.17529, -0.17020, -0.30060, 0.22058, -0.02450, -0.42143,
|
||||
0.49642, 0.46899, -0.28552, -0.22549, -0.01333, 0.21567, 0.22251, 0.21639, -0.19194, -0.19140,
|
||||
-0.24106, 0.10952, -0.11019, 0.29763, -0.02039, -0.25748, 0.23169, 0.01357, 0.09802, -0.19022,
|
||||
0.37604, -0.40777, 0.18131, -0.10258, 0.29573, -0.31773, 0.09069, -0.02198, -0.26594, 0.48302,
|
||||
-0.10041, 0.20210, -0.05609, -0.01169, -0.17339, 0.17862, -0.22502, 0.29009, -0.45160, 0.19771,
|
||||
0.27634, 0.31695, -0.09993, 0.17167, 0.12394, 0.28088, -0.12502, -0.16967, -0.06296, -0.17036,
|
||||
0.27320, 0.01595, 0.16955, 0.30146, -0.15173, -0.29807, 0.08178, -0.06811, 0.21655, 0.26348,
|
||||
0.06316, 0.45661, -0.29756, -0.05742, -0.14715, -0.03037, -0.16656, -0.08768, 0.38078, 0.40679,
|
||||
-0.32779, -0.09106, 0.16107, -0.07301, 0.07700, -0.22694, -0.15692, -0.02548, 0.38749, -0.12203,
|
||||
-0.02980, -0.22067, 0.00680, -0.23058, -0.29112, 0.23032, -0.16026, 0.23392, -0.09990, 0.03628,
|
||||
-0.42592, -0.33474, -0.09499, -0.17442, -0.20110, 0.24618, -0.06418, -0.06715, 0.40754, 0.29377,
|
||||
0.29543, -0.16832, -0.08468, 0.06491, -0.01410, 0.19988, 0.24950, 0.14626, -0.27851, 0.06079,
|
||||
0.48134, -0.13475, 0.25398, 0.11738, 0.23369, -0.00661, -0.16811, -0.04557, -0.12030, -0.39527,
|
||||
-0.35760, 0.01840, -0.15941, 0.03290, 0.09988, -0.08307, 0.06644, -0.24637, 0.34112, -0.08026,
|
||||
0.00951, 0.27656, 0.16247, 0.28217, 0.17198, -0.16389, -0.03835, -0.02675, -0.08032, -0.21045,
|
||||
-0.38946, 0.23207, 0.10987, -0.31674, -0.28653, -0.27430, -0.29109, -0.00648, 0.38431, -0.38478,
|
||||
-0.41195, -0.19364, -0.20977, -0.05524, 0.05558, -0.20109, 0.11803, -0.19884, 0.43318, -0.39255,
|
||||
0.26612, -0.21771, 0.12471, 0.12856, -0.15104, -0.11676, 0.17582, -0.25330, 0.00298, -0.31712,
|
||||
0.21532, -0.20319, 0.14507, -0.04588, -0.22995, -0.06470, 0.18849, -0.13444, 0.37107, 0.07387,
|
||||
-0.14008, 0.09896, 0.13727, -0.28417, -0.09461, -0.18703, 0.04080, 0.02343, -0.49988, 0.17993,
|
||||
0.23189, -0.30581, -0.18334, -0.09667, -0.27699, -0.05998, 0.09118, -0.32453, 0.46251, 0.41500,
|
||||
-0.45314, -0.00544, 0.08529, 0.29099, -0.00937, -0.31650, 0.26163, 0.14506, 0.37498, -0.16454,
|
||||
0.35215, 0.31642, -0.09161, -0.31452, -0.04792, -0.04677, -0.19523, 0.27998, 0.05491, 0.44461,
|
||||
-0.01258, -0.27887, 0.18361, -0.04539, -0.02977, 0.30821, 0.29454, -0.17932, 0.16193, 0.23934,
|
||||
0.47923, 0.25373, 0.23258, 0.31484, -0.17958, -0.01136, 0.17681, 0.12869, 0.03235, 0.43762,
|
||||
0.13734, -0.09433, -0.03735, 0.17949, 0.14122, -0.17814, 0.06359, 0.16044, 0.12249, -0.22314,
|
||||
0.40775, 0.05147, 0.12389, 0.04290, -0.01642, 0.00082, -0.18056, 0.02875, 0.32690, 0.17712,
|
||||
0.34001, -0.21581, -0.01086, -0.18180, 0.17480, -0.17774, -0.07503, 0.28438, -0.19747, 0.29595,
|
||||
-0.28002, -0.02073, -0.16522, -0.18234, -0.20565, 0.29620, 0.07502, 0.01429, -0.31418, 0.43693,
|
||||
-0.12212, 0.11178, -0.28503, 0.04683, 0.00072, 0.05566, 0.18857, 0.26101, -0.38891, -0.21216,
|
||||
-0.21850, -0.15147, -0.30749, -0.23762, 0.14984, 0.03535, -0.02862, -0.00105, -0.39907, -0.06909,
|
||||
-0.36094, 0.21717, 0.15930, -0.18924, 0.13741, 0.01039, 0.13613, 0.00659, 0.07676, -0.13711,
|
||||
0.24285, -0.07564, -0.28349, -0.15658, 0.03135, -0.30909, -0.22534, 0.17363, -0.19376, 0.26038,
|
||||
0.05546, -0.22607, 0.32420, -0.02552, -0.05400, 0.13388, 0.04643, -0.31535, -0.06181, 0.30237,
|
||||
-0.04680, -0.29441, 0.12231, 0.03960, -0.01188, 0.01406, 0.25402, 0.03315, 0.25026, -0.10922
|
||||
};
|
||||
|
||||
const double gu_data2[] =
|
||||
{ // raw data 300 items
|
||||
0.26599, 0.41329, 0.31846, 0.92590, 0.43050, 0.17466, 0.02322, 0.72621, 0.37921, 0.70597,
|
||||
0.97098, 0.14023, 0.57619, 0.09938, 0.02281, 0.92341, 0.72654, 0.71000, 0.76687, 0.70182,
|
||||
0.88752, 0.49524, 0.42549, 0.42806, 0.57615, 0.76051, 0.15341, 0.47457, 0.60066, 0.40880,
|
||||
0.20668, 0.41949, 0.97620, 0.94318, 0.71491, 0.56402, 0.23553, 0.94387, 0.78567, 0.06362,
|
||||
0.85252, 0.86262, 0.25190, 0.03274, 0.93216, 0.37971, 0.08797, 0.14596, 0.73871, 0.06574,
|
||||
0.67447, 0.28575, 0.43911, 0.92133, 0.12327, 0.87762, 0.71060, 0.07141, 0.55443, 0.53310,
|
||||
0.91529, 0.25121, 0.07593, 0.94490, 0.28656, 0.82174, 0.68887, 0.67337, 0.99291, 0.03316,
|
||||
0.02849, 0.33891, 0.25594, 0.90071, 0.01248, 0.67871, 0.65953, 0.65369, 0.97574, 0.31578,
|
||||
0.23678, 0.39220, 0.06706, 0.80943, 0.57694, 0.08220, 0.18151, 0.19969, 0.37096, 0.37858,
|
||||
0.70153, 0.46816, 0.76511, 0.02520, 0.39387, 0.25527, 0.39050, 0.60141, 0.30322, 0.46195,
|
||||
0.12025, 0.33616, 0.04174, 0.00196, 0.68886, 0.74445, 0.15869, 0.18994, 0.95195, 0.62874,
|
||||
0.82874, 0.53369, 0.34383, 0.50752, 0.97023, 0.22695, 0.62407, 0.25840, 0.71279, 0.28785,
|
||||
0.31611, 0.20391, 0.19702, 0.40760, 0.85158, 0.68369, 0.63760, 0.09879, 0.11924, 0.32920,
|
||||
0.53052, 0.15900, 0.21229, 0.84080, 0.33933, 0.93651, 0.42705, 0.06199, 0.50092, 0.47192,
|
||||
0.57152, 0.01818, 0.31404, 0.50173, 0.87725, 0.50530, 0.10717, 0.04035, 0.32901, 0.33538,
|
||||
0.04780, 0.40984, 0.78216, 0.91288, 0.11314, 0.25248, 0.23823, 0.74001, 0.48089, 0.55531,
|
||||
0.82486, 0.01058, 0.05409, 0.44357, 0.52641, 0.68188, 0.94629, 0.61627, 0.33037, 0.11961,
|
||||
0.57988, 0.19653, 0.91902, 0.59838, 0.52974, 0.28364, 0.45767, 0.65836, 0.63045, 0.76140,
|
||||
0.27918, 0.27256, 0.46035, 0.77418, 0.92918, 0.14095, 0.89645, 0.25146, 0.21172, 0.47910,
|
||||
0.95451, 0.34377, 0.29927, 0.79220, 0.97654, 0.67591, 0.44385, 0.38434, 0.44860, 0.28170,
|
||||
0.90712, 0.20337, 0.00292, 0.55046, 0.62255, 0.45127, 0.80896, 0.43965, 0.59145, 0.23801,
|
||||
0.33601, 0.30119, 0.89935, 0.40850, 0.98226, 0.75430, 0.68318, 0.65407, 0.68067, 0.32942,
|
||||
0.11756, 0.27626, 0.83879, 0.72174, 0.75430, 0.13702, 0.03402, 0.58781, 0.07393, 0.23067,
|
||||
0.92537, 0.29445, 0.43437, 0.47685, 0.54548, 0.66082, 0.23805, 0.60208, 0.94337, 0.21363,
|
||||
0.72637, 0.57181, 0.77679, 0.63931, 0.72860, 0.38901, 0.94920, 0.04535, 0.12863, 0.40550,
|
||||
0.90095, 0.21418, 0.13953, 0.99639, 0.02526, 0.70018, 0.21828, 0.20294, 0.20191, 0.30954,
|
||||
0.39490, 0.68955, 0.11506, 0.15748, 0.40252, 0.91680, 0.61547, 0.78443, 0.19693, 0.67630,
|
||||
0.56552, 0.58556, 0.53554, 0.53507, 0.09831, 0.21229, 0.83135, 0.26375, 0.89287, 0.97069,
|
||||
0.70615, 0.42041, 0.43117, 0.21291, 0.26086, 0.26978, 0.77340, 0.43833, 0.46179, 0.54418,
|
||||
0.67878, 0.42776, 0.61454, 0.55915, 0.36363, 0.31999, 0.42442, 0.86649, 0.62513, 0.02047
|
||||
};
|
||||
|
||||
class TestRunnable
|
||||
{
|
||||
public:
|
||||
const std::string name;
|
||||
int dim; // dimension of the solved problem
|
||||
int nvar; // number of variable of the solved problem
|
||||
TestRunnable(std::string n, int d, int nv)
|
||||
: name{std::move(n)}, dim(d), nvar(nv)
|
||||
{
|
||||
}
|
||||
virtual ~TestRunnable() = default;
|
||||
bool test() const;
|
||||
virtual bool run() const = 0;
|
||||
protected:
|
||||
static double korder_unfold_fold(int maxdim, int unfold_dim,
|
||||
int nstat, int npred, int nboth, int forw,
|
||||
const TwoDMatrix &gy, const TwoDMatrix &gu,
|
||||
const TwoDMatrix &v);
|
||||
};
|
||||
|
||||
bool
|
||||
TestRunnable::test() const
|
||||
{
|
||||
std::cout << "Running test <" << name << ">" << std::endl;
|
||||
clock_t start = clock();
|
||||
auto start_real = std::chrono::steady_clock::now();
|
||||
bool passed = run();
|
||||
clock_t end = clock();
|
||||
auto end_real = std::chrono::steady_clock::now();
|
||||
std::chrono::duration<double> duration = end_real - start_real;
|
||||
std::cout << "CPU time " << std::setprecision(4) << std::setw(8)
|
||||
<< static_cast<double>(end-start)/CLOCKS_PER_SEC << " (CPU seconds)\n"
|
||||
<< "Real time " << std::setw(8) << duration.count() << " (seconds).....................";
|
||||
if (passed)
|
||||
std::cout << "passed\n\n";
|
||||
else
|
||||
std::cout << "FAILED\n\n";
|
||||
return passed;
|
||||
}
|
||||
|
||||
double
|
||||
TestRunnable::korder_unfold_fold(int maxdim, int unfold_dim,
|
||||
int nstat, int npred, int nboth, int nforw,
|
||||
const TwoDMatrix &gy, const TwoDMatrix &gu,
|
||||
const TwoDMatrix &v)
|
||||
{
|
||||
TensorContainer<FSSparseTensor> c(1);
|
||||
int ny = nstat+npred+nboth+nforw;
|
||||
int nu = v.nrows();
|
||||
int nz = nboth+nforw+ny+nboth+npred+nu;
|
||||
SparseGenerator::fillContainer(c, maxdim, nz, ny, 5.0);
|
||||
for (int d = 1; d <= maxdim; d++)
|
||||
std::cout << "\ttensor fill for dim=" << d << " is: "
|
||||
<< std::setprecision(2) << std::setw(6) << std::fixed
|
||||
<< c.get(Symmetry{d}).getFillFactor()*100.0 << " %\n"
|
||||
<< std::defaultfloat;
|
||||
Journal jr("out.txt");
|
||||
KOrder kord(nstat, npred, nboth, nforw, c, gy, gu, v, jr);
|
||||
// Perform unfolded steps until unfold_dim
|
||||
double maxerror = 0.0;
|
||||
for (int d = 2; d <= unfold_dim; d++)
|
||||
{
|
||||
clock_t pertime = clock();
|
||||
kord.performStep<Storage::unfold>(d);
|
||||
pertime = clock()-pertime;
|
||||
std::cout << "\ttime for unfolded step dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(pertime)/CLOCKS_PER_SEC << std::endl;
|
||||
clock_t checktime = clock();
|
||||
double err = kord.check<Storage::unfold>(d);
|
||||
checktime = clock()-checktime;
|
||||
std::cout << "\ttime for step check dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(checktime)/CLOCKS_PER_SEC << '\n'
|
||||
<< "\tmax error in step dim=" << d << ": " << std::setprecision(6) << err
|
||||
<< std::endl;
|
||||
maxerror = std::max(err, maxerror);
|
||||
}
|
||||
// Perform folded steps until maxdim
|
||||
if (unfold_dim < maxdim)
|
||||
{
|
||||
clock_t swtime = clock();
|
||||
kord.switchToFolded();
|
||||
swtime = clock()-swtime;
|
||||
std::cout << "\ttime for switching dim=" << unfold_dim << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(swtime)/CLOCKS_PER_SEC << std::endl;
|
||||
|
||||
for (int d = unfold_dim+1; d <= maxdim; d++)
|
||||
{
|
||||
clock_t pertime = clock();
|
||||
kord.performStep<Storage::fold>(d);
|
||||
pertime = clock()-pertime;
|
||||
std::cout << "\ttime for folded step dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(pertime)/CLOCKS_PER_SEC << std::endl;
|
||||
clock_t checktime = clock();
|
||||
double err = kord.check<Storage::fold>(d);
|
||||
checktime = clock()-checktime;
|
||||
std::cout << "\ttime for step check dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(checktime)/CLOCKS_PER_SEC << '\n'
|
||||
<< "\tmax error in step dim=" << d << ": " << std::setprecision(6) << err
|
||||
<< std::endl;
|
||||
maxerror = std::max(err, maxerror);
|
||||
}
|
||||
}
|
||||
return maxerror;
|
||||
}
|
||||
|
||||
class UnfoldKOrderSmall : public TestRunnable
|
||||
{
|
||||
public:
|
||||
UnfoldKOrderSmall()
|
||||
: TestRunnable("unfold-3 fold-4 korder (stat=2,pred=3,both=1,forw=2,u=3,dim=4)",
|
||||
4, 18)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
TwoDMatrix gy{make_matrix(8, 4, gy_data)};
|
||||
TwoDMatrix gu{make_matrix(8, 3, gu_data)};
|
||||
TwoDMatrix v{make_matrix(3, 3, vdata)};
|
||||
double err = korder_unfold_fold(4, 3, 2, 3, 1, 2,
|
||||
gy, gu, v);
|
||||
|
||||
return err < 5e-7;
|
||||
}
|
||||
};
|
||||
|
||||
// Same dimension as Smets & Wouters
|
||||
class UnfoldKOrderSW : public TestRunnable
|
||||
{
|
||||
public:
|
||||
UnfoldKOrderSW()
|
||||
: TestRunnable("unfold S&W korder (stat=5,pred=12,both=8,forw=5,u=10,dim=4)",
|
||||
4, 73)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
TwoDMatrix gy{make_matrix(30, 20, gy_data2)};
|
||||
TwoDMatrix gu{make_matrix(30, 10, gu_data2)};
|
||||
TwoDMatrix v{make_matrix(10, 10, vdata2)};
|
||||
v.mult(0.001);
|
||||
gu.mult(.01);
|
||||
double err = korder_unfold_fold(4, 4, 5, 12, 8, 5,
|
||||
gy, gu, v);
|
||||
|
||||
return err < 0.5;
|
||||
}
|
||||
};
|
||||
|
||||
class UnfoldFoldKOrderSW : public TestRunnable
|
||||
{
|
||||
public:
|
||||
UnfoldFoldKOrderSW()
|
||||
: TestRunnable("unfold-2 fold-3 S&W korder (stat=5,pred=12,both=8,forw=5,u=10,dim=3)",
|
||||
4, 73)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
TwoDMatrix gy{make_matrix(30, 20, gy_data2)};
|
||||
TwoDMatrix gu{make_matrix(30, 10, gu_data2)};
|
||||
TwoDMatrix v{make_matrix(10, 10, vdata2)};
|
||||
v.mult(0.001);
|
||||
gu.mult(.01);
|
||||
double err = korder_unfold_fold(4, 3, 5, 12, 8, 5,
|
||||
gy, gu, v);
|
||||
|
||||
return err < 0.5;
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::vector<std::unique_ptr<TestRunnable>> all_tests;
|
||||
// Fill in vector of all tests
|
||||
all_tests.push_back(std::make_unique<UnfoldKOrderSmall>());
|
||||
all_tests.push_back(std::make_unique<UnfoldKOrderSW>());
|
||||
all_tests.push_back(std::make_unique<UnfoldFoldKOrderSW>());
|
||||
|
||||
// Find maximum dimension and maximum nvar
|
||||
int dmax = 0;
|
||||
int nvmax = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
if (dmax < test->dim)
|
||||
dmax = test->dim;
|
||||
if (nvmax < test->nvar)
|
||||
nvmax = test->nvar;
|
||||
}
|
||||
TLStatic::init(dmax, nvmax); // initialize library
|
||||
|
||||
// Launch the tests
|
||||
int success = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (test->test())
|
||||
success++;
|
||||
}
|
||||
catch (const TLException &e)
|
||||
{
|
||||
std::cout << "Caught TL exception in <" << test->name << ">:" << std::endl;
|
||||
e.print();
|
||||
}
|
||||
catch (SylvException &e)
|
||||
{
|
||||
std::cout << "Caught Sylv exception in <" << test->name << ">:" << std::endl;
|
||||
e.printMessage();
|
||||
}
|
||||
}
|
||||
|
||||
int nfailed = all_tests.size() - success;
|
||||
std::cout << "There were " << nfailed << " tests that failed out of "
|
||||
<< all_tests.size() << " tests run." << std::endl;
|
||||
|
||||
if (nfailed)
|
||||
return EXIT_FAILURE;
|
||||
else
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
noinst_LIBRARIES = libparser.a
|
||||
|
||||
GENERATED_FILES = assign_tab.cc formula_tab.cc matrix_tab.cc assign_tab.hh formula_tab.hh matrix_tab.hh assign_ll.cc formula_ll.cc matrix_ll.cc
|
||||
|
||||
libparser_a_SOURCES = \
|
||||
location.hh \
|
||||
atom_assignings.cc \
|
||||
atom_assignings.hh \
|
||||
atom_substitutions.cc \
|
||||
atom_substitutions.hh \
|
||||
dynamic_atoms.cc \
|
||||
dynamic_atoms.hh \
|
||||
fine_atoms.cc \
|
||||
fine_atoms.hh \
|
||||
formula_parser.cc \
|
||||
formula_parser.hh \
|
||||
matrix_parser.cc \
|
||||
matrix_parser.hh \
|
||||
parser_exception.cc \
|
||||
parser_exception.hh \
|
||||
static_atoms.cc \
|
||||
static_atoms.hh \
|
||||
static_fine_atoms.cc \
|
||||
static_fine_atoms.hh \
|
||||
tree.cc \
|
||||
tree.hh \
|
||||
$(GENERATED_FILES)
|
||||
|
||||
libparser_a_CPPFLAGS = -I../.. $(BOOST_CPPFLAGS)
|
||||
|
||||
BUILT_SOURCES = $(GENERATED_FILES)
|
||||
|
||||
EXTRA_DIST = assign.yy formula.yy matrix.yy assign.ll formula.ll matrix.ll
|
||||
|
||||
%_tab.cc %_tab.hh: %.yy
|
||||
$(YACC) -W -o$*_tab.cc $<
|
||||
|
||||
%_tab.$(OBJEXT): CXXFLAGS += -Wno-old-style-cast
|
||||
|
||||
%_ll.cc: %.ll
|
||||
$(LEX) -i -o$@ $<
|
||||
|
||||
%_ll.$(OBJEXT): CXXFLAGS += -Wno-old-style-cast
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- C++ -*- */
|
||||
/*
|
||||
* Copyright © 2004-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
%{
|
||||
#include "location.hh"
|
||||
#include "assign_tab.hh"
|
||||
|
||||
#define YY_USER_ACTION SET_LLOC(asgn_);
|
||||
%}
|
||||
|
||||
%option nounput
|
||||
%option noyy_top_state
|
||||
%option stack
|
||||
%option yylineno
|
||||
%option prefix="asgn_"
|
||||
%option never-interactive
|
||||
%x CMT
|
||||
|
||||
%%
|
||||
|
||||
/* comments */
|
||||
<*>"/*" {yy_push_state(CMT);}
|
||||
<CMT>[^*\n]*
|
||||
<CMT>"*"+[^*/\n]*
|
||||
<CMT>"*"+"/" {yy_pop_state();}
|
||||
<CMT>[\n]
|
||||
"//".*\n
|
||||
|
||||
/* spaces */
|
||||
[ \t\r\n] {return BLANK;}
|
||||
|
||||
/* names */
|
||||
[A-Za-z_][A-Za-z0-9_]* {
|
||||
asgn_lval.string = asgn_text;
|
||||
return NAME;
|
||||
}
|
||||
|
||||
; {return SEMICOLON;}
|
||||
= {return EQUAL_SIGN;}
|
||||
. {
|
||||
asgn_lval.character = asgn_text[0];
|
||||
return CHARACTER;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
int
|
||||
asgn_wrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
asgn__destroy_buffer(void* p)
|
||||
{
|
||||
asgn__delete_buffer(static_cast<YY_BUFFER_STATE>(p));
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// -*- C++ -*-
|
||||
/*
|
||||
* Copyright © 2006-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%code requires
|
||||
{
|
||||
#include "location.hh"
|
||||
#define ASGN_LTYPE ogp::location_type
|
||||
}
|
||||
|
||||
%code
|
||||
{
|
||||
#include "atom_assignings.hh"
|
||||
#include <string>
|
||||
|
||||
void asgn_error(std::string);
|
||||
int asgn_lex();
|
||||
extern ogp::AtomAssignings* aparser;
|
||||
}
|
||||
|
||||
%union
|
||||
{
|
||||
int integer;
|
||||
char *string;
|
||||
char character;
|
||||
}
|
||||
|
||||
%token EQUAL_SIGN SEMICOLON CHARACTER BLANK
|
||||
%token <string> NAME;
|
||||
|
||||
%define api.prefix {asgn_}
|
||||
|
||||
%locations
|
||||
%defines
|
||||
%define parse.error verbose
|
||||
|
||||
%%
|
||||
|
||||
root : assignments | %empty;
|
||||
|
||||
assignments : assignments BLANK | assignments assignment | assignment | BLANK;
|
||||
|
||||
assignment : NAME EQUAL_SIGN material SEMICOLON {
|
||||
aparser->add_assignment(@1.off, $1, @1.ll, @3.off-@1.off, @3.ll + @4.ll);}
|
||||
| NAME space EQUAL_SIGN material SEMICOLON {
|
||||
aparser->add_assignment(@1.off, $1, @1.ll, @4.off-@1.off, @4.ll + @5.ll);}
|
||||
;
|
||||
|
||||
material : material CHARACTER | material NAME | material BLANK | NAME | CHARACTER | BLANK;
|
||||
|
||||
space : space BLANK | BLANK;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
asgn_error(std::string mes)
|
||||
{
|
||||
aparser->error(std::move(mes));
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019-2022 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/>.
|
||||
*/
|
||||
|
||||
#include "atom_assignings.hh"
|
||||
#include "location.hh"
|
||||
#include "parser_exception.hh"
|
||||
|
||||
#include "utils/cc/exception.hh"
|
||||
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a)
|
||||
: atoms(a), expr(aa.expr, atoms), left_names(aa.left_names),
|
||||
lname2expr(aa.lname2expr), order(aa.order)
|
||||
{
|
||||
}
|
||||
|
||||
/** A global symbol for passing info to the AtomAssignings from
|
||||
* asgn_parse(). */
|
||||
AtomAssignings *aparser;
|
||||
|
||||
/** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc
|
||||
* generated from assign.lex assign.y */
|
||||
void *asgn__scan_string(const char *);
|
||||
void asgn__destroy_buffer(void *);
|
||||
void asgn_parse();
|
||||
extern location_type asgn_lloc;
|
||||
|
||||
void
|
||||
AtomAssignings::parse(const string &stream)
|
||||
{
|
||||
asgn_lloc.off = 0;
|
||||
asgn_lloc.ll = 0;
|
||||
void *p = asgn__scan_string(stream.c_str());
|
||||
aparser = this;
|
||||
asgn_parse();
|
||||
asgn__destroy_buffer(p);
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::error(string mes)
|
||||
{
|
||||
throw ParserException(std::move(mes), asgn_lloc.off);
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::add_assignment_to_double(string name, double val)
|
||||
{
|
||||
// if left hand side is a registered atom, insert it to tree
|
||||
int t;
|
||||
try
|
||||
{
|
||||
if (atoms.check(name))
|
||||
t = expr.add_nulary(name);
|
||||
else
|
||||
t = -1;
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
t = -1;
|
||||
}
|
||||
// register left hand side in order
|
||||
order.push_back(t);
|
||||
|
||||
// add the double to the tree
|
||||
std::ostringstream buf;
|
||||
buf << std::setprecision(std::numeric_limits<double>::max_digits10)
|
||||
<< val;
|
||||
try
|
||||
{
|
||||
expr.parse(buf.str());
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
// should never happen
|
||||
throw ParserException("Error parsing double "+buf.str()+": "+e.message(), 0);
|
||||
}
|
||||
|
||||
// register name of the left hand side and put to lname2expr
|
||||
left_names.insert(name);
|
||||
lname2expr.emplace(std::move(name), order.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::add_assignment(int asgn_off, const string &str, int name_len,
|
||||
int right_off, int right_len)
|
||||
{
|
||||
// the order of doing things here is important: since the
|
||||
// FormulaParser requires that all references from the i-th tree
|
||||
// refere to trees with index lass than i, so to capture also a
|
||||
// nulary term for the left hand side, it must be inserted to the
|
||||
// expression tree before the expression is parsed.
|
||||
|
||||
// find the name in the atoms
|
||||
string name = str.substr(0, name_len);
|
||||
|
||||
// if left hand side is a registered atom, insert it to tree
|
||||
int t;
|
||||
try
|
||||
{
|
||||
t = atoms.check(name);
|
||||
if (t == -1)
|
||||
t = expr.add_nulary(name);
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
atoms.register_name(name);
|
||||
t = expr.add_nulary(name);
|
||||
}
|
||||
// register left hand side in order
|
||||
order.push_back(t);
|
||||
|
||||
// parse expression on the right
|
||||
try
|
||||
{
|
||||
expr.parse(str.substr(right_off, right_len));
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
throw ParserException(e, asgn_off+right_off);
|
||||
}
|
||||
|
||||
// register name of the left hand side and put to lname2expr
|
||||
left_names.insert(name);
|
||||
if (lname2expr.find(name) != lname2expr.end())
|
||||
{
|
||||
// Prevent the occurrence of #415
|
||||
std::cerr << "Changing the value of " << name << " through a second assignment (e.g. in initval) is not supported. Aborting." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
lname2expr[name] = order.size()-1;
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
|
||||
{
|
||||
// go through all old variables and see what are their derived new
|
||||
// variables
|
||||
for (const auto &it : mm)
|
||||
{
|
||||
const string &oldname = it.first;
|
||||
const AtomSubstitutions::Tshiftnameset &sset = it.second;
|
||||
if (!sset.empty())
|
||||
{
|
||||
int told = atoms.index(oldname);
|
||||
if (told < 0 && !atoms.get_name_storage().query(oldname))
|
||||
atoms.register_name(oldname);
|
||||
if (told == -1)
|
||||
told = expr.add_nulary(oldname);
|
||||
// at least one substitution here, so make an expression
|
||||
expr.add_formula(told);
|
||||
// say that this expression is not assigned to any atom
|
||||
order.push_back(-1);
|
||||
// now go through all new names derived from the old name and
|
||||
// reference to the newly added formula
|
||||
for (const auto &itt : sset)
|
||||
{
|
||||
const string &newname = itt.first;
|
||||
left_names.insert(newname);
|
||||
lname2expr.emplace(newname, expr.nformulas()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::print() const
|
||||
{
|
||||
std::cout << "Atom Assignings\nExpressions:\n";
|
||||
expr.print();
|
||||
std::cout << "Left names:\n";
|
||||
for (auto it : lname2expr)
|
||||
std::cout << it.first << " ⇒ " << expr.formula(it.second) << " (t=" << order[it.second] << ")\n";
|
||||
}
|
||||
|
||||
void
|
||||
AtomAsgnEvaluator::setValues(EvalTree &et) const
|
||||
{
|
||||
// set values of constants
|
||||
aa.atoms.setValues(et);
|
||||
|
||||
// set values of variables to NaN or to user set values
|
||||
double nan = std::numeric_limits<double>::quiet_NaN();
|
||||
for (int i = 0; i < aa.atoms.nvar(); i++)
|
||||
{
|
||||
const string &ss = aa.atoms.name(i);
|
||||
int t = aa.atoms.index(ss);
|
||||
if (t >= 0)
|
||||
{
|
||||
auto it = user_values.find(t);
|
||||
if (it == user_values.end())
|
||||
et.set_nulary(t, nan);
|
||||
else
|
||||
et.set_nulary(t, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AtomAsgnEvaluator::set_user_value(const string &name, double val)
|
||||
{
|
||||
int t = aa.atoms.index(name);
|
||||
if (t >= 0)
|
||||
{
|
||||
auto it = user_values.find(t);
|
||||
if (it == user_values.end())
|
||||
user_values.emplace(t, val);
|
||||
else
|
||||
it->second = val;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AtomAsgnEvaluator::load(int i, double res)
|
||||
{
|
||||
// set the value
|
||||
operator[](i) = res;
|
||||
// if i-th expression is atom, set its value to this EvalTree
|
||||
int t = aa.order[i];
|
||||
if (t >= 0)
|
||||
etree.set_nulary(t, res);
|
||||
}
|
||||
|
||||
double
|
||||
AtomAsgnEvaluator::get_value(const string &name) const
|
||||
{
|
||||
auto it = aa.lname2expr.find(name);
|
||||
if (it == aa.lname2expr.end())
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
else
|
||||
return operator[](it->second);
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGP_ATOM_ASSIGNINGS_H
|
||||
#define OGP_ATOM_ASSIGNINGS_H
|
||||
|
||||
#include "static_atoms.hh"
|
||||
#include "formula_parser.hh"
|
||||
#include "atom_substitutions.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
class AtomAsgnEvaluator;
|
||||
|
||||
/** This class represents atom assignments used in parameters
|
||||
* settings and initval initialization. It maintains atoms of the
|
||||
* all expressions on the right hand side, the parsed formulas of
|
||||
* the right hand sides, and the information about the left hand
|
||||
* sides. See documentation to the order member below. */
|
||||
class AtomAssignings
|
||||
{
|
||||
friend class AtomAsgnEvaluator;
|
||||
protected:
|
||||
using Tvarintmap = std::map<string, int>;
|
||||
/** All atoms which should be sufficient for formulas at the
|
||||
* right hand sides. The atoms should be filled with names
|
||||
* (preregistered). This is a responsibility of the caller. */
|
||||
StaticAtoms &atoms;
|
||||
/** The formulas of right hand sides. */
|
||||
FormulaParser expr;
|
||||
/** Name storage of the names from left hand sides. */
|
||||
NameStorage left_names;
|
||||
/** Information on left hand sides. This maps a name to the
|
||||
* index of its assigned expression in expr. More than one
|
||||
* name may reference to the same expression. */
|
||||
Tvarintmap lname2expr;
|
||||
/** Information on left hand sides. If order[i] >= 0, then it
|
||||
* says that i-th expression in expr is assigned to atom with
|
||||
* order[i] tree index. */
|
||||
std::vector<int> order;
|
||||
public:
|
||||
/** Construct the object using the provided static atoms. */
|
||||
AtomAssignings(StaticAtoms &a) : atoms(a), expr(atoms)
|
||||
{
|
||||
}
|
||||
/** Make a copy with provided reference to (posibly different)
|
||||
* static atoms. */
|
||||
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
|
||||
virtual ~AtomAssignings() = default;
|
||||
/** Parse the assignments from the given string. */
|
||||
void parse(const string &stream);
|
||||
/** Process a syntax error from bison. */
|
||||
void error(string mes);
|
||||
/** Add an assignment of the given name to the given
|
||||
* double. Can be called by a user, anytime. */
|
||||
void add_assignment_to_double(string name, double val);
|
||||
/** Add an assignment. Called from assign.y. */
|
||||
void add_assignment(int asgn_off, const string &str, int name_len,
|
||||
int right_off, int right_len);
|
||||
/** This applies old2new map (possibly from atom
|
||||
* substitutions) to this object. It registers new variables
|
||||
* in the atoms, and adds the expressions to expr, and left
|
||||
* names to lname2expr. The information about dynamical part
|
||||
* of substitutions is ignored, since we are now in the static
|
||||
* world. */
|
||||
void apply_subst(const AtomSubstitutions::Toldnamemap &mm);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
/** This class basically evaluates the atom assignments
|
||||
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
|
||||
* is also a storage for the results of the evaluation stored as a
|
||||
* vector, so the class inherits from std::vector<double> and
|
||||
* ogp::FormulaEvalLoader. As the expressions for atoms are
|
||||
* evaluated, the results are values for atoms which will be
|
||||
* used in subsequent evaluations. For this reason, the class
|
||||
* inherits also from AtomValues. */
|
||||
class AtomAsgnEvaluator : public FormulaEvalLoader,
|
||||
public AtomValues,
|
||||
protected FormulaEvaluator,
|
||||
public std::vector<double>
|
||||
{
|
||||
protected:
|
||||
using Tusrvalmap = std::map<int, double>;
|
||||
Tusrvalmap user_values;
|
||||
const AtomAssignings &aa;
|
||||
public:
|
||||
AtomAsgnEvaluator(const AtomAssignings &a)
|
||||
: FormulaEvaluator(a.expr),
|
||||
std::vector<double>(a.expr.nformulas()), aa(a)
|
||||
{
|
||||
}
|
||||
~AtomAsgnEvaluator() override = default;
|
||||
/** This sets all initial values to NaNs, all constants and
|
||||
* all values set by user by call set_value. This is called by
|
||||
* FormulaEvaluator::eval() method, which is called by eval()
|
||||
* method passing this argument as AtomValues. So the
|
||||
* ogp::EvalTree will be always this->etree. */
|
||||
void setValues(EvalTree &et) const override;
|
||||
/** User setting of the values. For example in initval,
|
||||
* parameters are known and should be set to their values. In
|
||||
* constrast endogenous variables are set initially to NaNs by
|
||||
* AtomValues::setValues. */
|
||||
void set_user_value(const string &name, double val);
|
||||
/** This sets the result of i-th expression in aa to res, and
|
||||
* also checks whether the i-th expression is an atom. If so,
|
||||
* it sets the value of the atom in ogp::EvalTree
|
||||
* this->etree. */
|
||||
void load(int i, double res) override;
|
||||
/** After the user values have been set, the assignments can
|
||||
* be evaluated. For this purpose we have eval() method. The
|
||||
* result is that this object as std::vector<double> will
|
||||
* contain the values. It is ordered given by formulas in
|
||||
* expr. */
|
||||
void
|
||||
eval()
|
||||
{
|
||||
FormulaEvaluator::eval(*this, *this);
|
||||
}
|
||||
/** This returns a value for a given name. If the name is not
|
||||
* found among atoms, or there is no assignment for the atom,
|
||||
* NaN is returned. */
|
||||
double get_value(const string &name) const;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019-2022 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/>.
|
||||
*/
|
||||
|
||||
#include "atom_substitutions.hh"
|
||||
#include "utils/cc/exception.hh"
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa,
|
||||
FineAtoms &na)
|
||||
: new2old(as.new2old), old2new(as.old2new), old_atoms(oa), new_atoms(na)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AtomSubstitutions::add_substitution(string newname, string oldname, int tshift)
|
||||
{
|
||||
// insert to new2old map
|
||||
new2old.emplace(newname, Tshiftname(oldname, tshift));
|
||||
// insert to old2new map
|
||||
auto it = old2new.find(oldname);
|
||||
if (it != old2new.end())
|
||||
it->second.emplace(std::move(newname), -tshift);
|
||||
else
|
||||
{
|
||||
Tshiftnameset snset;
|
||||
snset.emplace(std::move(newname), -tshift);
|
||||
old2new.emplace(std::move(oldname), snset);
|
||||
}
|
||||
|
||||
// put to info
|
||||
info.num_substs++;
|
||||
}
|
||||
|
||||
void
|
||||
AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
|
||||
{
|
||||
// create an external ordering of new_atoms from old_atoms
|
||||
const vector<string> &oa_ext = old_atoms.get_allvar();
|
||||
vector<string> na_ext;
|
||||
for (const auto &oname : oa_ext)
|
||||
{
|
||||
// add the old name itself
|
||||
na_ext.push_back(oname);
|
||||
// add all new names derived from the old name
|
||||
auto it = old2new.find(oname);
|
||||
if (it != old2new.end())
|
||||
for (const auto &itt : it->second)
|
||||
na_ext.push_back(itt.first);
|
||||
}
|
||||
|
||||
// call parsing finished for the new_atoms
|
||||
new_atoms.parsing_finished(ot, na_ext);
|
||||
}
|
||||
|
||||
string
|
||||
AtomSubstitutions::get_new4old(const string &oldname, int tshift) const
|
||||
{
|
||||
auto it = old2new.find(oldname);
|
||||
if (it != old2new.end())
|
||||
{
|
||||
const Tshiftnameset &sset = it->second;
|
||||
for (const auto &itt : sset)
|
||||
if (itt.second == -tshift)
|
||||
return itt.first;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void
|
||||
AtomSubstitutions::print() const
|
||||
{
|
||||
std::cout << "Atom Substitutions:\nOld ⇒ New:\n";
|
||||
for (const auto &it : old2new)
|
||||
for (const auto &itt : it.second)
|
||||
std::cout << " " << it.first << " ⇒ [" << itt.first << ", " << itt.second << "]\n";
|
||||
|
||||
std::cout << "Old ⇐ New:\n";
|
||||
for (const auto &it : new2old)
|
||||
std::cout << " [" << it.second.first << ", " << it.second.second << "] ⇐ " << it.first << '\n';
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
|
||||
{
|
||||
string name;
|
||||
|
||||
int mlead, mlag;
|
||||
endovarspan(mlead, mlag);
|
||||
|
||||
// substitute all endo lagged more than 1
|
||||
while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty())
|
||||
makeAuxVariables(name, -1, -2, mlag, fp, as);
|
||||
// substitute all endo leaded more than 1
|
||||
while (!(name = findEndoWithLeadInInterval(2, mlead)).empty())
|
||||
makeAuxVariables(name, 1, 2, mlead, fp, as);
|
||||
|
||||
exovarspan(mlead, mlag);
|
||||
|
||||
// substitute all lagged exo
|
||||
while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
|
||||
makeAuxVariables(name, -1, -1, mlag, fp, as);
|
||||
// substitute all leaded exo
|
||||
while (!(name = findExoWithLeadInInterval(1, mlead)).empty())
|
||||
makeAuxVariables(name, 1, 1, mlead, fp, as);
|
||||
|
||||
// notify that substitution have been finished
|
||||
as.substitutions_finished(order_type);
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as)
|
||||
{
|
||||
string name;
|
||||
|
||||
int mlead, mlag;
|
||||
endovarspan(mlead, mlag);
|
||||
|
||||
// substitute all endo lagged more than 1
|
||||
while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty())
|
||||
makeAuxVariables(name, -1, -2, mlag, fp, as);
|
||||
|
||||
exovarspan(mlead, mlag);
|
||||
|
||||
// substitute all lagged exo
|
||||
while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
|
||||
makeAuxVariables(name, -1, -1, mlag, fp, as);
|
||||
// substitute all leaded exo by 1
|
||||
while (!(name = findExoWithLeadInInterval(1, 1)).empty())
|
||||
makeAuxVariables(name, 1, 1, 1, fp, as);
|
||||
|
||||
// notify that substitution have been finished
|
||||
as.substitutions_finished(order_type);
|
||||
}
|
||||
|
||||
string
|
||||
SAtoms::findNameWithLeadInInterval(const vector<string> &names,
|
||||
int ll1, int ll2) const
|
||||
{
|
||||
for (auto name : names)
|
||||
{
|
||||
auto it = vars.find(name);
|
||||
if (it != vars.end())
|
||||
{
|
||||
const DynamicAtoms::Tlagmap &lmap = it->second;
|
||||
for (auto itt : lmap)
|
||||
if (itt.first >= ll1 && itt.first <= ll2)
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
// nothing found
|
||||
return "";
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::attemptAuxName(const string &str, int ll, string &out) const
|
||||
{
|
||||
char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm';
|
||||
string absll = std::to_string(std::abs(ll));
|
||||
int iter = 1;
|
||||
do
|
||||
{
|
||||
out = str + '_';
|
||||
for (int i = 0; i < iter; i++)
|
||||
out += c;
|
||||
if (ll != 0)
|
||||
out += absll;
|
||||
iter++;
|
||||
}
|
||||
while (varnames.query(out));
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::makeAuxVariables(const string &name, int step, int start, int limit_lead,
|
||||
FormulaParser &fp, AtomSubstitutions &as)
|
||||
{
|
||||
if (!(step == 1 || step == -1))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong value of step in SAtoms::makeAuxVariables");
|
||||
if (step*start > step*limit_lead)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong value of start in SAtoms::makeAuxVariables");
|
||||
|
||||
// make sure that we do not go further than necessary, this is
|
||||
// that the limit lead is not behind maxlead or minlag
|
||||
int mlead, mlag;
|
||||
varspan(name, mlead, mlag);
|
||||
if (step == -1)
|
||||
limit_lead = std::max(limit_lead, mlag);
|
||||
else
|
||||
limit_lead = std::min(limit_lead, mlead);
|
||||
|
||||
// Comment to comments: name="a"; start=-3; step=-1;
|
||||
|
||||
// recover tree index of a previous atom, i.e. set tprev to a tree
|
||||
// index of atom "a(-2)"
|
||||
int tprev = index(name, start-step);
|
||||
if (tprev == -1)
|
||||
tprev = fp.add_nulary(name + '(' + std::to_string(start-step) + ')');
|
||||
|
||||
int ll = start;
|
||||
do
|
||||
{
|
||||
// either create atom "a_m2(0)" with tree index taux and add
|
||||
// equation "a_m2(0)=a(-2)"
|
||||
// or
|
||||
// check if "a_m2(0)" has not been already created (with
|
||||
// different step), in this case do not add equation "a_m2(0)
|
||||
// = a(-2)"
|
||||
string newname, newname_str;
|
||||
int taux;
|
||||
if ((newname = as.get_new4old(name, ll-step)).empty())
|
||||
{
|
||||
attemptAuxName(name, ll-step, newname_str);
|
||||
newname = newname_str;
|
||||
register_uniq_endo(newname);
|
||||
taux = fp.add_nulary(newname + "(0)");
|
||||
// add to substitutions
|
||||
as.add_substitution(newname, name, ll-step);
|
||||
|
||||
// add equation "a_m2(0) = a(-2)", this is taux = tprev
|
||||
fp.add_formula(fp.add_binary(code_t::MINUS, taux, tprev));
|
||||
}
|
||||
else
|
||||
{
|
||||
// example: exogenous EPS and occurrence at both EPS(-1)
|
||||
// EPS(+1)
|
||||
// first call makeAuxVariables("EPS",1,1,...) will make endo EPS_p0 = EPS
|
||||
// second call makeAuxVariables("EPS",-1,-1,...) will use this EPS_p0
|
||||
// to substitute for EPS(-1)
|
||||
taux = index(newname, 0);
|
||||
if (taux < 0)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find tree index of previously substituted variable");
|
||||
}
|
||||
|
||||
// create atom "a_m2(-1)" or turn "a(-3)" if any to "a_m2(-1)"; tree index t
|
||||
int t = index(name, ll);
|
||||
if (t == -1)
|
||||
{
|
||||
// no "a(-3)", make t <-> a_m2(-1)
|
||||
t = fp.add_nulary(newname + '(' + std::to_string(step) + ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn a(-3) to a_m2(-1)
|
||||
unassign_variable(name, ll, t);
|
||||
assign_variable(newname, step, t);
|
||||
}
|
||||
|
||||
// next iteration starts with tprev <-> "a_m2(-1)" (this will be made equal to "a_m3(0)")
|
||||
tprev = t;
|
||||
|
||||
ll += step;
|
||||
}
|
||||
while (step*ll <= step*limit_lead);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue