From 01c35cc1dc2928e0a1e57b99a9316918834468b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Telemachus=29?= Date: Mon, 10 Nov 2014 18:21:26 +0100 Subject: [PATCH 001/101] Initial commit. --- .gitignore | 3 +++ LICENSE.md | 16 ++++++++++++++++ README.md | 6 ++++++ doc/README.md | 19 +++++++++++++++++++ notes.org | 3 +++ 5 files changed, 47 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 doc/README.md create mode 100644 notes.org diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..310406d7e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*~ +*.mat +doc/build/* \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..233611e8f --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,16 @@ +The Dynare particles module is distributed under the GNU GPL: + +> Copyright © 2014 Dynare Team +> +> This program is free software: you can redistribute it and/or modify +> it under the terms of the GNU General Public License as published by +> the Free Software Foundation, either version 3 of the License, or +> (at your option) any later version. +> +> This program is distributed in the hope that it will be useful, +> but WITHOUT ANY WARRANTY; without even the implied warranty of +> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +> GNU General Public License for more details. +> +> You should have received a copy of the GNU General Public License +> along with this program. If not, see . \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..21f08a958 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# particless Dynare module + +This package, used in [Dynare](http://www.dynare.org), provides +nonlinear filtering algorithmss. The documentation is available in the +[doc](https://github.com/DynareTeam/particles/tree/master/doc) +subfolder. \ No newline at end of file diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 000000000..86f42ad85 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,19 @@ +# Documentation for particles Dynare module + +The documentation is written with sphinx, so you need to have +[Python](https://www.python.org/) on your system with +[sphinx](http://sphinx-doc.org/). You also need to install the [Read +the docs](https://readthedocs.org/) theme and the sphinx matlab +domain, this can be done with pip in a terminal: + +``` + ~$ pip install sphinx_rtd_theme + ~$ pip install sphinxcontrib-matlab +``` + +To obtain the documentation as an html file in subfolder +```build/html``` you just have to use the provided Makefile: + +``` + ~$ make html +``` \ No newline at end of file diff --git a/notes.org b/notes.org new file mode 100644 index 000000000..2caf58eed --- /dev/null +++ b/notes.org @@ -0,0 +1,3 @@ +#+STARTUP: overview +#+STARTUP: hidestars +#+AUTHOR: Stéphane Adjemian From bd951bdcce4922bcb47b98fdb5a377e73b09830f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Telemachus=29?= Date: Mon, 10 Nov 2014 18:38:48 +0100 Subject: [PATCH 002/101] Added provisions for documentation. --- doc/Makefile | 177 +++++++++++++++++++++++ doc/make.bat | 242 +++++++++++++++++++++++++++++++ doc/source/conf.py | 331 +++++++++++++++++++++++++++++++++++++++++++ doc/source/index.rst | 22 +++ 4 files changed, 772 insertions(+) create mode 100644 doc/Makefile create mode 100644 doc/make.bat create mode 100644 doc/source/conf.py create mode 100644 doc/source/index.rst diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 000000000..b1e0378a1 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Particles.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Particles.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Particles" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Particles" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 000000000..a61048826 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,242 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +set I18NSPHINXOPTS=%SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Particles.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Particles.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 000000000..fe9915ab5 --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,331 @@ +# -*- coding: utf-8 -*- +# +# Particles documentation build configuration file, created by +# sphinx-quickstart on Mon Nov 10 18:37:39 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.mathjax', + 'sphinx.ext.ifconfig', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Particles' +copyright = u'2014, Stéphane Adjemian' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.0.0' +# The full version, including alpha/beta/rc tags. +release = '0.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Particlesdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'Particles.tex', u'Particles Documentation', + u'Stéphane Adjemian', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'particles', u'Particles Documentation', + [u'Stéphane Adjemian'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'Particles', u'Particles Documentation', + u'Stéphane Adjemian', 'Particles', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = u'Particles' +epub_author = u'Stéphane Adjemian' +epub_publisher = u'Stéphane Adjemian' +epub_copyright = u'2014, Stéphane Adjemian' + +# The basename for the epub file. It defaults to the project name. +#epub_basename = u'Particles' + +# The HTML theme for the epub output. Since the default themes are not optimized +# for small screen space, using the same theme for HTML and epub output is +# usually not wise. This defaults to 'epub', a theme designed to save visual +# space. +#epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or en if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files shat should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +#epub_tocscope = 'default' + +# Fix unsupported image types using the PIL. +#epub_fix_images = False + +# Scale large images. +#epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#epub_show_urls = 'inline' + +# If false, no index is generated. +#epub_use_index = True diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 000000000..b9be40976 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,22 @@ +.. Particles documentation master file, created by + sphinx-quickstart on Mon Nov 10 18:37:39 2014. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Particles's documentation! +===================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + From b577de9b871c74e19d4509047f0d6f24dab06419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Telemachus=29?= Date: Mon, 10 Nov 2014 19:00:16 +0100 Subject: [PATCH 003/101] Imported files from DynareTeam/dynare github repository. --- src/auxiliary_initialization.m | 116 ++++++ src/auxiliary_particle_filter.m | 159 ++++++++ src/conditional_filter_proposal.m | 123 ++++++ src/conditional_particle_filter.m | 125 ++++++ src/fit_gaussian_mixture.m | 52 +++ src/gaussian_densities.m | 52 +++ src/gaussian_filter.m | 162 ++++++++ src/gaussian_filter_bank.m | 122 ++++++ src/gaussian_mixture_densities.m | 58 +++ src/gaussian_mixture_filter.m | 225 +++++++++++ src/gaussian_mixture_filter_bank.m | 138 +++++++ src/importance_sampling.m | 29 ++ src/index_resample.m | 72 ++++ .../local_state_space_iteration_2.m | 275 +++++++++++++ src/measurement_equations.m | 33 ++ src/multivariate_smooth_resampling.m | 72 ++++ src/mykmeans.m | 53 +++ src/neff.m | 21 + src/online_auxiliary_filter.m | 373 ++++++++++++++++++ src/probability.m | 39 ++ src/probability2.m | 38 ++ src/resample.m | 74 ++++ src/residual_resampling.m | 143 +++++++ src/sequential_importance_particle_filter.m | 178 +++++++++ src/solve_model_for_online_filter.m | 344 ++++++++++++++++ src/spherical_radial_sigma_points.m | 36 ++ src/traditional_resampling.m | 237 +++++++++++ src/univariate_smooth_resampling.m | 82 ++++ src/unscented_sigma_points.m | 42 ++ 29 files changed, 3473 insertions(+) create mode 100644 src/auxiliary_initialization.m create mode 100644 src/auxiliary_particle_filter.m create mode 100644 src/conditional_filter_proposal.m create mode 100644 src/conditional_particle_filter.m create mode 100644 src/fit_gaussian_mixture.m create mode 100644 src/gaussian_densities.m create mode 100644 src/gaussian_filter.m create mode 100644 src/gaussian_filter_bank.m create mode 100644 src/gaussian_mixture_densities.m create mode 100644 src/gaussian_mixture_filter.m create mode 100644 src/gaussian_mixture_filter_bank.m create mode 100644 src/importance_sampling.m create mode 100644 src/index_resample.m create mode 100644 src/local_state_space_iteration/local_state_space_iteration_2.m create mode 100644 src/measurement_equations.m create mode 100644 src/multivariate_smooth_resampling.m create mode 100644 src/mykmeans.m create mode 100644 src/neff.m create mode 100644 src/online_auxiliary_filter.m create mode 100644 src/probability.m create mode 100644 src/probability2.m create mode 100644 src/resample.m create mode 100644 src/residual_resampling.m create mode 100644 src/sequential_importance_particle_filter.m create mode 100644 src/solve_model_for_online_filter.m create mode 100644 src/spherical_radial_sigma_points.m create mode 100644 src/traditional_resampling.m create mode 100644 src/univariate_smooth_resampling.m create mode 100644 src/unscented_sigma_points.m diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m new file mode 100644 index 000000000..784550000 --- /dev/null +++ b/src/auxiliary_initialization.m @@ -0,0 +1,116 @@ +function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,DynareOptions) +% Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. +% +% INPUTS +% ReducedForm [structure] Matlab's structure describing the reduced form model. +% ReducedForm.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% ReducedForm.state.Q [double] (qq x qq) variance matrix of state errors. +% ReducedForm.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% mf [integer] pp*1 vector of indices. +% number_of_particles [integer] scalar. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. + +% Copyright (C) 2013 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . +persistent init_flag mf0 mf1 number_of_particles +persistent number_of_observed_variables number_of_structural_innovations + +% Set default +if isempty(start) + start = 1; +end + +% Set flag for prunning +%pruning = DynareOptions.particle.pruning; + +% Get steady state and mean. +%steadystate = ReducedForm.steadystate; +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables. +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + number_of_particles = DynareOptions.particle.number_of_particles; + init_flag = 1; +end + +% Set local state space model (first order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; +% Set local state space model (second order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +% Get covariance matrices +Q = ReducedForm.Q; +H = ReducedForm.H; +if isempty(H) + H = 0; +end + +% Get initial condition for the state vector. +StateVectorMean = ReducedForm.StateVectorMean; +StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +state_variance_rank = size(StateVectorVarianceSquareRoot,2); +%Q_lower_triangular_cholesky = chol(Q)'; +%if pruning +% StateVectorMean_ = StateVectorMean; +% StateVectorVarianceSquareRoot_ = StateVectorVarianceSquareRoot; +%end + +% Set seed for randn(). +set_dynare_seed('default'); + +% Initialization of the likelihood. +const_lik = log(2*pi)*number_of_observed_variables; + +% Initialization of the weights across particles. +weights = ones(1,number_of_particles)/number_of_particles ; +StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); +%if pruning +% StateVectors_ = StateVectors; +%end +yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); +%if pruning +% yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); +% [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); +%else + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); +%end +PredictedObservedMean = weights*(tmp(mf1,:)'); +PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); +dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean'); +PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' + H; +wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; +tau_tilde = weights.*wtilde ; +tau_tilde = tau_tilde/sum(tau_tilde); +initial_distribution = resample(StateVectors',tau_tilde',DynareOptions)' ; \ No newline at end of file diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m new file mode 100644 index 000000000..e869484fe --- /dev/null +++ b/src/auxiliary_particle_filter.m @@ -0,0 +1,159 @@ +function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,DynareOptions) +% Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. +% +% INPUTS +% ReducedForm [structure] Matlab's structure describing the reduced form model. +% ReducedForm.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% ReducedForm.state.Q [double] (qq x qq) variance matrix of state errors. +% ReducedForm.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% mf [integer] pp*1 vector of indices. +% number_of_particles [integer] scalar. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. + +% Copyright (C) 2011-2013 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . +persistent init_flag mf0 mf1 number_of_particles +persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations + +% Set default +if isempty(start) + start = 1; +end + +% Set flag for prunning +pruning = DynareOptions.particle.pruning; + +% Get steady state and mean. +steadystate = ReducedForm.steadystate; +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables. +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + number_of_particles = DynareOptions.particle.number_of_particles; + init_flag = 1; +end + +% Set local state space model (first order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; +% Set local state space model (second order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +% Get covariance matrices +Q = ReducedForm.Q; +H = ReducedForm.H; +if isempty(H) + H = 0; +end + +% Get initial condition for the state vector. +StateVectorMean = ReducedForm.StateVectorMean; +StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +state_variance_rank = size(StateVectorVarianceSquareRoot,2); +Q_lower_triangular_cholesky = chol(Q)'; +if pruning + StateVectorMean_ = StateVectorMean; + StateVectorVarianceSquareRoot_ = StateVectorVarianceSquareRoot; +end + +% Set seed for randn(). +set_dynare_seed('default'); + +% Initialization of the likelihood. +const_lik = log(2*pi)*number_of_observed_variables; +lik = NaN(sample_size,1); +LIK = NaN; + +% Initialization of the weights across particles. +weights = ones(1,number_of_particles)/number_of_particles ; +StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); +if pruning + StateVectors_ = StateVectors; +end +for t=1:sample_size + yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); + if pruning + yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); + [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + else + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + end + PredictedObservedMean = weights*(tmp(mf1,:)'); + PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); + dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean'); + PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' +H; + wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; + tau_tilde = weights.*wtilde ; + sum_tau_tilde = sum(tau_tilde) ; + %var_wtilde = wtilde-sum_tau_tilde ; + %var_wtilde = var_wtilde'*var_wtilde/(number_of_particles-1) ; + lik(t) = log(sum_tau_tilde) ; %+ .5*var_wtilde/(number_of_particles*(sum_tau_tilde*sum_tau_tilde)) ; + tau_tilde = tau_tilde/sum_tau_tilde; + if pruning + temp = resample([yhat' yhat_'],tau_tilde',DynareOptions); + yhat = temp(:,1:number_of_state_variables)' ; + yhat_ = temp(:,number_of_state_variables+1:2*number_of_state_variables)' ; + else + yhat = resample(yhat',tau_tilde',DynareOptions)' ; + end + if pruning + [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + else + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + end + PredictedObservedMean = weights*(tmp(mf1,:)'); + PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); + dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean'); + PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' +H; + wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; + epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); + if pruning + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + StateVectors_ = tmp_(mf0,:); + else + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + end + StateVectors = tmp(mf0,:); + PredictedObservedMean = mean(tmp(mf1,:),2); + PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); + dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + PredictedObservedVariance = (dPredictedObservedMean*dPredictedObservedMean')/number_of_particles + H; + lnw = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))); + wtilde = lnw./wtilde; + weights = wtilde/sum(wtilde); +end + +LIK = -sum(lik(start:end)); \ No newline at end of file diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m new file mode 100644 index 000000000..aa82a449a --- /dev/null +++ b/src/conditional_filter_proposal.m @@ -0,0 +1,123 @@ +function [ProposalStateVector,Weights] = conditional_filter_proposal(ReducedForm,obs,StateVectors,SampleWeights,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions,normconst2) +% +% Computes the proposal for each past particle using Gaussian approximations +% for the state errors and the Kalman filter +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2012-2013 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 . +% +% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr +% stephane DOT adjemian AT univ DASH lemans DOT fr + +persistent init_flag2 mf0 mf1 +persistent number_of_state_variables number_of_observed_variables +persistent number_of_structural_innovations + +% Set local state space model (first-order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; +% Set local state space model (second-order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + ghx + ghu + ghxx + ghuu + ghxu +end + +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables. +if isempty(init_flag2) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + init_flag2 = 1; +end + +if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo + [nodes,weights] = spherical_radial_sigma_points(number_of_structural_innovations); + weights_c = weights ; +elseif DynareOptions.particle.proposal_approximation.unscented + [nodes,weights,weights_c] = unscented_sigma_points(number_of_structural_innovations,DynareOptions); +else + error('Estimation: This approximation for the proposal is not implemented or unknown!') +end + +epsilon = Q_lower_triangular_cholesky*(nodes') ; +yhat = repmat(StateVectors-state_variables_steady_state,1,size(epsilon,2)) ; + +tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + +PredictedStateMean = tmp(mf0,:)*weights ; +PredictedObservedMean = tmp(mf1,:)*weights; + +if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo + PredictedStateMean = sum(PredictedStateMean,2) ; + PredictedObservedMean = sum(PredictedObservedMean,2) ; + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights) ; + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)'.*sqrt(weights); + big_mat = [dObserved dState; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; + [mat1,mat] = qr2(big_mat,0); + mat = mat'; + clear('mat1'); + PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); + CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); + StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); + StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*(obs - PredictedObservedMean); +else + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + PredictedStateVariance = dState*diag(weights_c)*dState'; + PredictedObservedVariance = dObserved*diag(weights_c)*dObserved' + H; + PredictedStateAndObservedCovariance = dState*diag(weights_c)*dObserved'; + KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance ; + StateVectorMean = PredictedStateMean + KalmanFilterGain*(obs - PredictedObservedMean); + StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; + StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); + StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; +end + +ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; +ypred = measurement_equations(ProposalStateVector,ReducedForm,DynareOptions) ; +foo = H_lower_triangular_cholesky \ (obs - ypred) ; +likelihood = exp(-0.5*(foo)'*foo)/normconst2 + 1e-99 ; +Weights = SampleWeights.*likelihood; diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m new file mode 100644 index 000000000..3f365f85c --- /dev/null +++ b/src/conditional_particle_filter.m @@ -0,0 +1,125 @@ +function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,DynareOptions) +% +% Evaluates the likelihood of a non-linear model with a particle filter +% - the proposal is built using the Kalman updating step for each particle. +% - we need draws in the errors distributions +% Whether we use Monte-Carlo draws from a multivariate gaussian distribution +% as in Amisano & Tristani (JEDC 2010). +% Whether we use multidimensional Gaussian sparse grids approximations: +% - a univariate Kronrod-Paterson Gaussian quadrature combined by the Smolyak +% operator (ref: Winschel & Kratzig, 2010). +% - a spherical-radial cubature (ref: Arasaratnam & Haykin, 2009a,2009b). +% - a scaled unscented transform cubature (ref: Julier & Uhlmann 1997, van der +% Merwe & Wan 2003). +% +% Pros: +% - Allows using current observable information in the proposal +% - The use of sparse grids Gaussian approximation is much faster than the Monte-Carlo approach +% Cons: +% - The use of the Kalman updating step may biais the proposal distribution since +% it has been derived in a linear context and is implemented in a nonlinear +% context. That is why particle resampling is performed. +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% smolyak_accuracy [integer] scalar. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2010 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr +% stephane DOT adjemian AT univ DASH lemans DOT fr + +persistent init_flag mf0 mf1 +persistent number_of_particles +persistent sample_size number_of_state_variables number_of_observed_variables + +% Set default +if isempty(start) + start = 1; +end + +% Set persistent variables. +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + init_flag = 1; + number_of_particles = DynareOptions.particle.number_of_particles ; +end + +% Get covariance matrices +Q = ReducedForm.Q; +H = ReducedForm.H; +if isempty(H) + H = 0; + H_lower_triangular_cholesky = 0; +else + H_lower_triangular_cholesky = reduced_rank_cholesky(H)'; +end + +% Get initial condition for the state vector. +StateVectorMean = ReducedForm.StateVectorMean; +StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +state_variance_rank = size(StateVectorVarianceSquareRoot,2); +Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; + +% Set seed for randn(). +set_dynare_seed('default'); + +% Initialization of the likelihood. +normconst2 = log(2*pi)*number_of_observed_variables*prod(diag(H_lower_triangular_cholesky)) ; +lik = NaN(sample_size,1); +LIK = NaN; + +ks = 0 ; + +StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); +SampleWeights = ones(1,number_of_particles)/number_of_particles ; +for t=1:sample_size + for i=1:number_of_particles + [StateParticles(:,i),SampleWeights(i)] = ... + conditional_filter_proposal(ReducedForm,Y(:,t),StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions,normconst2) ; + end + SumSampleWeights = sum(SampleWeights) ; + lik(t) = log(SumSampleWeights) ; + SampleWeights = SampleWeights./SumSampleWeights ; + if (DynareOptions.particle.resampling.status.generic && neff(SampleWeights). + +[dim,Ndata] = size(X); +M = size(StateMu,2) ; +if check % Ensure that covariances don't collapse + MIN_COVAR_SQRT = sqrt(eps); + init_covars = StateSqrtP; +end +eold = -Inf; +for n=1:niters + % Calculate posteriors based on old parameters + [prior,likelihood,marginal,posterior] = probability(StateMu,StateSqrtP,StateWeights,X); + e = sum(log(marginal)); + if (n > 1 && abs((e - eold)/eold) < crit) + return; + else + eold = e; + end + new_pr = (sum(posterior,2))'; + StateWeights = new_pr/Ndata; + StateMu = bsxfun(@rdivide,(posterior*X')',new_pr); + for j=1:M + diffs = bsxfun(@minus,X,StateMu(:,j)); + tpost = (1/sqrt(new_pr(j)))*sqrt(posterior(j,:)); + diffs = bsxfun(@times,diffs,tpost); + [foo,tcov] = qr2(diffs',0); + StateSqrtP(:,:,j) = tcov'; + if check + if min(abs(diag(StateSqrtP(:,:,j)))) < MIN_COVAR_SQRT + StateSqrtP(:,:,j) = init_covars(:,:,j); + end + end + end +end + diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m new file mode 100644 index 000000000..3a770118d --- /dev/null +++ b/src/gaussian_densities.m @@ -0,0 +1,52 @@ +function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,DynareOptions) +% +% Elements to calculate the importance sampling ratio +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% smolyak_accuracy [integer] scalar. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2010 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +% proposal density +proposal = probability2(mut_t,sqr_Pss_t_t,particles) ; +% prior density +prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; +% likelihood +yt_t_1_i = measurement_equations(particles,ReducedForm,DynareOptions) ; +eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; +yt_t_1 = sum(yt_t_1_i*weigths1,2) ; +tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; +Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; +sqr_det = sqrt(det(Pyy)) ; +foo = (eta_t_i/Pyy).*eta_t_i ; +likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +IncrementalWeights = likelihood.*prior./proposal ; diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m new file mode 100644 index 000000000..da3840c74 --- /dev/null +++ b/src/gaussian_filter.m @@ -0,0 +1,162 @@ +function [LIK,lik] = gaussian_filter(ReducedForm,Y,start,DynareOptions) +% Evaluates the likelihood of a non-linear model approximating the +% predictive (prior) and filtered (posterior) densities for state variables +% by gaussian distributions. +% Gaussian approximation is done by: +% - a Kronrod-Paterson gaussian quadrature with a limited number of nodes. +% Multidimensional quadrature is obtained by the Smolyak operator (ref: Winschel & Kratzig, 2010). +% - a spherical-radial cubature (ref: Arasaratnam & Haykin, 2008,2009). +% - a scaled unscented transform cubature (ref: ) +% - Monte-Carlo draws from a multivariate gaussian distribution. +% First and second moments of prior and posterior state densities are computed +% from the resulting nodes/particles and allows to generate new distributions at the +% following observation. +% => The use of nodes is much faster than Monte-Carlo Gaussian particle and standard particles +% filters since it treats a lesser number of particles and there is no need +% of resampling. +% However, estimations may reveal biaised if the model is truly non-gaussian +% since predictive and filtered densities are unimodal. +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% smolyak_accuracy [integer] scalar. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2013 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +persistent init_flag mf0 mf1 +persistent nodes2 weights2 weights_c2 number_of_particles +persistent sample_size number_of_state_variables number_of_observed_variables + +% Set default +if isempty(start) + start = 1; +end + +% Set persistent variables. +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_particles = DynareOptions.particle.number_of_particles; + init_flag = 1; +end + +% compute gaussian quadrature nodes and weights on states and shocks +if isempty(nodes2) + if DynareOptions.particle.distribution_approximation.cubature + [nodes2,weights2] = spherical_radial_sigma_points(number_of_state_variables); + weights_c2 = weights2; + elseif DynareOptions.particle.distribution_approximation.unscented + [nodes2,weights2,weights_c2] = unscented_sigma_points(number_of_state_variables,DynareOptions); + else + if ~DynareOptions.particle.distribution_approximation.montecarlo + error('Estimation: This approximation for the proposal is not implemented or unknown!') + end + end +end + +if DynareOptions.particle.distribution_approximation.montecarlo + set_dynare_seed('default'); +end + +% Get covariance matrices +Q = ReducedForm.Q; +H = ReducedForm.H; +if isempty(H) + H = 0; + H_lower_triangular_cholesky = 0; +else + H_lower_triangular_cholesky = reduced_rank_cholesky(H)'; +end + +% Get initial condition for the state vector. +StateVectorMean = ReducedForm.StateVectorMean; +StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +state_variance_rank = size(StateVectorVarianceSquareRoot,2); +Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; + +% Initialization of the likelihood. +const_lik = (2*pi)^(number_of_observed_variables/2) ; +lik = NaN(sample_size,1); +LIK = NaN; + +SampleWeights = 1/number_of_particles ; +ks = 0 ; +%Estimate = zeros(number_of_state_variables,sample_size) ; +%V_Estimate = zeros(number_of_state_variables,number_of_state_variables,sample_size) ; +for t=1:sample_size + % build the proposal + [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = ... + gaussian_filter_bank(ReducedForm,Y(:,t),StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions) ; + %Estimate(:,t) = PredictedStateMean ; + %V_Estimate(:,:,t) = PredictedStateVarianceSquareRoot ; + if DynareOptions.particle.distribution_approximation.cubature || DynareOptions.particle.distribution_approximation.unscented + StateParticles = bsxfun(@plus,StateVectorMean,StateVectorVarianceSquareRoot*nodes2') ; + IncrementalWeights = ... + gaussian_densities(Y(:,t),StateVectorMean,... + StateVectorVarianceSquareRoot,PredictedStateMean,... + PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... + weights2,weights_c2,ReducedForm,DynareOptions) ; + SampleWeights = weights2.*IncrementalWeights ; + SumSampleWeights = sum(SampleWeights) ; + lik(t) = log(SumSampleWeights) ; + SampleWeights = SampleWeights./SumSampleWeights ; + else % Monte-Carlo draws + StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean) ; + IncrementalWeights = ... + gaussian_densities(Y(:,t),StateVectorMean,... + StateVectorVarianceSquareRoot,PredictedStateMean,... + PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... + 1/number_of_particles,1/number_of_particles,ReducedForm,DynareOptions) ; + SampleWeights = SampleWeights.*IncrementalWeights ; + SumSampleWeights = sum(SampleWeights) ; + %VarSampleWeights = IncrementalWeights-SumSampleWeights ; + %VarSampleWeights = VarSampleWeights*VarSampleWeights'/(number_of_particles-1) ; + lik(t) = log(SumSampleWeights) ; %+ .5*VarSampleWeights/(number_of_particles*(SumSampleWeights*SumSampleWeights)) ; + SampleWeights = SampleWeights./SumSampleWeights ; + Neff = 1/sum(bsxfun(@power,SampleWeights,2)) ; + if (Neff<.5*sample_size && DynareOptions.particle.resampling.status.generic) || DynareOptions.particle.resampling.status.systematic + ks = ks + 1 ; + StateParticles = resample(StateParticles',SampleWeights,DynareOptions)' ; + StateVectorMean = mean(StateParticles,2) ; + StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/(number_of_particles-1) - StateVectorMean*(StateVectorMean') )'; + SampleWeights = 1/number_of_particles ; + elseif DynareOptions.particle.resampling.status.none + StateVectorMean = (sampleWeights*StateParticles)' ; + temp = sqrt(SampleWeights').*StateParticles ; + StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp'*temp - StateVectorMean*(StateVectorMean') )'; + end + end +end + +LIK = -sum(lik(start:end)); diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m new file mode 100644 index 000000000..6094dbcf1 --- /dev/null +++ b/src/gaussian_filter_bank.m @@ -0,0 +1,122 @@ +function [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = gaussian_filter_bank(ReducedForm,obs,StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions) +% +% Computes the proposal with a gaussian approximation for importance +% sampling +% This proposal is a gaussian distribution calculated à la Kalman +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2012 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +persistent init_flag2 mf0 mf1 +persistent number_of_state_variables number_of_observed_variables +persistent number_of_structural_innovations + +% Set local state space model (first-order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; +% Set local state space model (second-order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + ghx + ghu + ghxx + ghuu + ghxu +end + +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables. +if isempty(init_flag2) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + init_flag2 = 1; +end + +if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo + [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations) ; + weights_c = weights ; +elseif DynareOptions.particle.proposal_approximation.unscented + [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables+number_of_structural_innovations,DynareOptions); +else + error('Estimation: This approximation for the proposal is not implemented or unknown!') +end + +xbar = [StateVectorMean ; zeros(number_of_structural_innovations,1) ] ; +sqr_Px = [ [ StateVectorVarianceSquareRoot zeros(number_of_state_variables,number_of_structural_innovations) ] ; + [ zeros(number_of_structural_innovations,number_of_state_variables) Q_lower_triangular_cholesky ] ]; +sigma_points = bsxfun(@plus,xbar,sqr_Px*(nodes')); +StateVectors = sigma_points(1:number_of_state_variables,:); +epsilon = sigma_points(number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations,:); +yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); +tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); +PredictedStateMean = tmp(mf0,:)*weights ; +PredictedObservedMean = tmp(mf1,:)*weights; + +if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo + PredictedStateMean = sum(PredictedStateMean,2); + PredictedObservedMean = sum(PredictedObservedMean,2); + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights); + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)'.*sqrt(weights); + PredictedStateVarianceSquareRoot = chol(dState'*dState)'; + big_mat = [dObserved dState ; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; + [mat1,mat] = qr2(big_mat,0); + mat = mat'; + clear('mat1'); + PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); + CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); + StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); + PredictionError = obs - PredictedObservedMean; + StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*PredictionError; +else + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + PredictedStateVariance = dState*diag(weights_c)*dState'; + PredictedObservedVariance = dObserved*diag(weights_c)*dObserved' + H; + PredictedStateAndObservedCovariance = dState*diag(weights_c)*dObserved'; + PredictedStateVarianceSquareRoot = chol(PredictedStateVariance)'; + PredictionError = obs - PredictedObservedMean; + KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance; + StateVectorMean = PredictedStateMean + KalmanFilterGain*PredictionError; + StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; + StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); + StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; +end \ No newline at end of file diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m new file mode 100644 index 000000000..9a5b28e05 --- /dev/null +++ b/src/gaussian_mixture_densities.m @@ -0,0 +1,58 @@ +function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... + StateMuPost,StateSqrtPPost,StateWeightsPost,... + StateParticles,H,normconst,weigths1,weigths2,ReducedForm,DynareOptions) + +% +% Elements to calculate the importance sampling ratio +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% smolyak_accuracy [integer] scalar. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2012 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 . + +% Compute the density of particles under the prior distribution +[ras,ras,prior] = probability(StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateParticles) ; +prior = prior' ; +% Compute the density of particles under the proposal distribution +[ras,ras,proposal] = probability(StateMuPost,StateSqrtPPost,StateWeightsPost,StateParticles) ; +proposal = proposal' ; +% Compute the density of the current observation conditionally to each particle +yt_t_1_i = measurement_equations(StateParticles,ReducedForm,DynareOptions) ; +eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; +yt_t_1 = sum(yt_t_1_i*weigths1,2) ; +tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; +Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; +sqr_det = sqrt(det(Pyy)) ; +foo = (eta_t_i/Pyy).*eta_t_i ; +likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +IncrementalWeights = likelihood.*prior./proposal ; + diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m new file mode 100644 index 000000000..5c60a81fb --- /dev/null +++ b/src/gaussian_mixture_filter.m @@ -0,0 +1,225 @@ +function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,DynareOptions) +% Evaluates the likelihood of a non-linear model approximating the state +% variables distributions with gaussian mixtures. Gaussian Mixture allows reproducing +% a wide variety of generalized distributions (when multimodal for instance). +% Each gaussian distribution is obtained whether +% - with a Smolyak quadrature à la Kronrod & Paterson (Heiss & Winschel 2010, Winschel & Kratzig 2010). +% - with a radial-spherical cubature +% - with scaled unscented sigma-points +% A Sparse grid Kalman Filter is implemented on each component of the mixture, +% which confers it a weight about current information. +% Information on the current observables is then embodied in the proposal +% distribution in which we draw particles, which allows +% - reaching a greater precision relatively to a standard particle filter, +% - reducing the number of particles needed, +% - still being faster. +% +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% Van der Meerwe & Wan, Gaussian Mixture Sigma-Point Particle Filters for Sequential +% Probabilistic Inference in Dynamic State-Space Models. +% Heiss & Winschel, 2010, Journal of Applied Economics. +% Winschel & Kratzig, 2010, Econometrica. +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2013 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + + +persistent init_flag mf0 mf1 Gprime Gsecond +persistent nodes weights weights_c I J G number_of_particles +persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations + +% Set default +if isempty(start) + start = 1; +end + +% Set persistent variables. +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + G = DynareOptions.particle.mixture_state_variables; % number of GM components in state + I = DynareOptions.particle.mixture_structural_shocks ; % number of GM components in structural noise + J = DynareOptions.particle.mixture_measurement_shocks ; % number of GM components in observation noise + Gprime = G*I ; + Gsecond = G*I*J ; + number_of_particles = DynareOptions.particle.number_of_particles; + init_flag = 1; +end + +SampleWeights = ones(Gsecond,1)/Gsecond ; + +% compute gaussian quadrature nodes and weights on states and shocks +if isempty(nodes) + if DynareOptions.particle.distribution_approximation.cubature + [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables); + weights_c = weights; + elseif DynareOptions.particle.distribution_approximation.unscented + [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables,DynareOptions); + else + if ~DynareOptions.particle.distribution_approximation.montecarlo + error('Estimation: This approximation for the proposal is not implemented or unknown!') + end + end +end + +if DynareOptions.particle.distribution_approximation.montecarlo + set_dynare_seed('default'); + SampleWeights = 1/number_of_particles ; +end + +% Get covariance matrices +Q = ReducedForm.Q; +H = ReducedForm.H; +if isempty(H) + H = 0; + H_lower_triangular_cholesky = 0; +else + H_lower_triangular_cholesky = reduced_rank_cholesky(H)'; +end +Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; + +% Initialize all matrices +StateWeights = ones(1,G)/G ; +StateMu = ReducedForm.StateVectorMean*ones(1,G) ; +StateSqrtP = zeros(number_of_state_variables,number_of_state_variables,G) ; +for g=1:G + StateSqrtP(:,:,g) = reduced_rank_cholesky(ReducedForm.StateVectorVariance)' ; +end + +StructuralShocksWeights = ones(1,I)/I ; +StructuralShocksMu = zeros(number_of_structural_innovations,I) ; +StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; +for i=1:I + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky ; +end + +ObservationShocksWeights = ones(1,J)/J ; +ObservationShocksMu = zeros(number_of_observed_variables,J) ; +ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; +for j=1:J + ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky ; +end + +StateWeightsPrior = zeros(1,Gprime) ; +StateMuPrior = zeros(number_of_state_variables,Gprime) ; +StateSqrtPPrior = zeros(number_of_state_variables,number_of_state_variables,Gprime) ; + +StateWeightsPost = zeros(1,Gsecond) ; +StateMuPost = zeros(number_of_state_variables,Gsecond) ; +StateSqrtPPost = zeros(number_of_state_variables,number_of_state_variables,Gsecond) ; + +%estimate = zeros(sample_size,number_of_state_variables,3) ; +const_lik = (2*pi)^(.5*number_of_observed_variables) ; + +ks = 0 ; +lik = NaN(sample_size,1); +LIK = NaN; +for t=1:sample_size + % Build the proposal joint quadratures of Gaussian on states, structural + % shocks and observation shocks based on each combination of mixtures + for i=1:I + for j=1:J + for g=1:G ; + a = g + (j-1)*G ; + b = a + (i-1)*Gprime ; + [StateMuPrior(:,a),StateSqrtPPrior(:,:,a),StateWeightsPrior(1,a),... + StateMuPost(:,b),StateSqrtPPost(:,:,b),StateWeightsPost(1,b)] =... + gaussian_mixture_filter_bank(ReducedForm,Y(:,t),StateMu(:,g),StateSqrtP(:,:,g),StateWeights(1,g),... + StructuralShocksMu(:,i),StructuralShocksSqrtP(:,:,i),StructuralShocksWeights(1,i),... + ObservationShocksMu(:,j),ObservationShocksSqrtP(:,:,j),ObservationShocksWeights(1,j),... + H,H_lower_triangular_cholesky,const_lik,DynareOptions) ; + end + end + end + + % Normalize weights + StateWeightsPrior = StateWeightsPrior/sum(StateWeightsPrior,2) ; + StateWeightsPost = StateWeightsPost/sum(StateWeightsPost,2) ; + + if DynareOptions.particle.distribution_approximation.cubature || DynareOptions.particle.distribution_approximation.unscented + for i=1:Gsecond + StateParticles = bsxfun(@plus,StateMuPost(:,i),StateSqrtPPost(:,:,i)*nodes') ; + IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... + StateMuPost,StateSqrtPPost,StateWeightsPost,... + StateParticles,H,const_lik,weights,weights_c,ReducedForm,DynareOptions) ; + SampleWeights(i) = sum(StateWeightsPost(i)*weights.*IncrementalWeights) ; + end + SumSampleWeights = sum(SampleWeights) ; + lik(t) = log(SumSampleWeights) ; + SampleWeights = SampleWeights./SumSampleWeights ; + [ras,SortedRandomIndx] = sort(rand(1,Gsecond)); + SortedRandomIndx = SortedRandomIndx(1:G); + indx = index_resample(0,SampleWeights,DynareOptions) ; + indx = indx(SortedRandomIndx) ; + StateMu = StateMuPost(:,indx); + StateSqrtP = StateSqrtPPost(:,:,indx); + StateWeights = ones(1,G)/G ; + else + % Sample particle in the proposal distribution, ie the posterior state GM + StateParticles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost',number_of_particles) ; + % Compute prior, proposal and likelihood of particles + IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... + StateMuPost,StateSqrtPPost,StateWeightsPost,... + StateParticles,H,const_lik,1/number_of_particles,... + 1/number_of_particles,ReducedForm,DynareOptions) ; + % calculate importance weights of particles + SampleWeights = SampleWeights.*IncrementalWeights ; + SumSampleWeights = sum(SampleWeights,1) ; + SampleWeights = SampleWeights./SumSampleWeights ; + lik(t) = log(SumSampleWeights) ; + % First possible state point estimates + %estimate(t,:,1) = SampleWeights*StateParticles' ; + % Resampling if needed of required + Neff = 1/sum(bsxfun(@power,SampleWeights,2)) ; + if (DynareOptions.particle.resampling.status.generic && Neff<.5*sample_size) || DynareOptions.particle.resampling.status.systematic + ks = ks + 1 ; + StateParticles = resample(StateParticles',SampleWeights,DynareOptions)' ; + StateVectorMean = mean(StateParticles,2) ; + StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/number_of_particles - StateVectorMean*(StateVectorMean') )'; + SampleWeights = 1/number_of_particles ; + elseif DynareOptions.particle.resampling.status.none + StateVectorMean = StateParticles*sampleWeights ; + temp = sqrt(SampleWeights').*StateParticles ; + StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp*temp' - StateVectorMean*(StateVectorMean') )'; + end + % Use the information from particles to update the gaussian mixture on state variables + [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(StateParticles,StateMu,StateSqrtP,StateWeights,0.001,10,1) ; + %estimate(t,:,3) = StateWeights*StateMu' ; + end +end + +LIK = -sum(lik(start:end)) ; \ No newline at end of file diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m new file mode 100644 index 000000000..3a3caa776 --- /dev/null +++ b/src/gaussian_mixture_filter_bank.m @@ -0,0 +1,138 @@ +function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPPost,StateWeightsPost] =... + gaussian_mixture_filter_bank(ReducedForm,obs,StateMu,StateSqrtP,StateWeights,... + StructuralShocksMu,StructuralShocksSqrtP,StructuralShocksWeights,... + ObservationShocksMu,ObservationShocksSqrtP,ObservationShocksWeights,... + H,H_lower_triangular_cholesky,normfactO,DynareOptions) +% +% Computes the proposal with a gaussian approximation for importance +% sampling +% This proposal is a gaussian distribution calculated à la Kalman +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2012 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + + + +persistent init_flag2 mf0 mf1 %nodes3 weights3 weights_c3 +persistent number_of_state_variables number_of_observed_variables +persistent number_of_structural_innovations + +% Set local state space model (first-order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; +% Set local state space model (second-order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + ghx + ghu + ghxx + ghuu + ghxu +end + +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables. +if isempty(init_flag2) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + init_flag2 = 1; +end + +numb = number_of_state_variables+number_of_structural_innovations ; + +if DynareOptions.particle.proposal_approximation.cubature + [nodes3,weights3] = spherical_radial_sigma_points(numb); + weights_c3 = weights3; +elseif DynareOptions.particle.proposal_approximation.unscented + [nodes3,weights3,weights_c3] = unscented_sigma_points(numb,DynareOptions); +else + error('Estimation: This approximation for the proposal is not implemented or unknown!') +end + +epsilon = bsxfun(@plus,StructuralShocksSqrtP*nodes3(:,number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations)',StructuralShocksMu) ; +StateVectors = bsxfun(@plus,StateSqrtP*nodes3(:,1:number_of_state_variables)',StateMu); +yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); +tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); +PredictedStateMean = tmp(mf0,:)*weights3; +PredictedObservedMean = tmp(mf1,:)*weights3; + +if DynareOptions.particle.proposal_approximation.cubature + PredictedStateMean = sum(PredictedStateMean,2); + PredictedObservedMean = sum(PredictedObservedMean,2); + dState = (bsxfun(@minus,tmp(mf0,:),PredictedStateMean)').*sqrt(weights3); + dObserved = (bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)').*sqrt(weights3); + PredictedStateVariance = dState'*dState; + big_mat = [dObserved dState ; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; + [mat1,mat] = qr2(big_mat,0); + mat = mat'; + clear('mat1'); + PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); + CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); + StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); + iPredictedObservedVarianceSquareRoot = inv(PredictedObservedVarianceSquareRoot); + iPredictedObservedVariance = iPredictedObservedVarianceSquareRoot'*iPredictedObservedVarianceSquareRoot; + sqrdet = 1/sqrt(det(iPredictedObservedVariance)); + PredictionError = obs - PredictedObservedMean; + StateVectorMean = PredictedStateMean + CovarianceObservedStateSquareRoot*iPredictedObservedVarianceSquareRoot*PredictionError; +else + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + PredictedStateVariance = dState*diag(weights_c3)*dState'; + PredictedObservedVariance = dObserved*diag(weights_c3)*dObserved' + H; + PredictedStateAndObservedCovariance = dState*diag(weights_c3)*dObserved'; + sqrdet = sqrt(det(PredictedObservedVariance)) ; + iPredictedObservedVariance = inv(PredictedObservedVariance); + PredictionError = obs - PredictedObservedMean; + KalmanFilterGain = PredictedStateAndObservedCovariance*iPredictedObservedVariance; + StateVectorMean = PredictedStateMean + KalmanFilterGain*PredictionError; + StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; + StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); + StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; +end + +data_lik_GM_g = exp(-0.5*PredictionError'*iPredictedObservedVariance*PredictionError)/abs(normfactO*sqrdet) + 1e-99; +StateMuPrior = PredictedStateMean ; +StateSqrtPPrior = reduced_rank_cholesky(PredictedStateVariance)'; +StateWeightsPrior = StateWeights*StructuralShocksWeights; +StateMuPost = StateVectorMean; +StateSqrtPPost = StateVectorVarianceSquareRoot; +StateWeightsPost = StateWeightsPrior*ObservationShocksWeights*data_lik_GM_g ; diff --git a/src/importance_sampling.m b/src/importance_sampling.m new file mode 100644 index 000000000..403b6beb3 --- /dev/null +++ b/src/importance_sampling.m @@ -0,0 +1,29 @@ +function State_Particles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost,numP) + +% Copyright (C) 2013 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 . + +[Xdim,Gsecond] = size(StateMuPost) ; +u = rand(numP,1); +[Nc,comp] = histc(u, cumsum([0; StateWeightsPost])); +State_Particles = zeros(Xdim,numP); +for k=1:Gsecond + idx = bsxfun(@eq,comp,k*ones(size(comp))) ; + State_Particles(:,idx) = StateSqrtPPost(:,:,k)*randn(Xdim,Nc(k)); +end +State_Particles= State_Particles + StateMuPost(:,comp); + diff --git a/src/index_resample.m b/src/index_resample.m new file mode 100644 index 000000000..e91645605 --- /dev/null +++ b/src/index_resample.m @@ -0,0 +1,72 @@ +function resampling_index = index_resample(particles,weights,DynareOptions) +% Resamples particles. + +%@info: +%! @deftypefn {Function File} {@var{indx} =} resample (@var{weights}, @var{method}) +%! @anchor{particle/resample} +%! @sp 1 +%! Resamples particles. +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item weights +%! n*1 vector of doubles, particles' weights. +%! @item method +%! string equal to 'residual' or 'traditional'. +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item indx +%! n*1 vector of intergers, indices. +%! @end table +%! @sp 2 +%! @strong{This function is called by:} +%! @sp 1 +%! @ref{particle/sequantial_importance_particle_filter} +%! @sp 2 +%! @strong{This function calls:} +%! @sp 1 +%! @ref{residual_resampling}, @ref{traditional_resampling} +%! @sp 2 +%! @end deftypefn +%@eod: + +% Copyright (C) 2013 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 . + +defaultmethod = 1; % For residual based method set this variable equal to 0. + +if defaultmethod + if DynareOptions.particle.resampling.method.kitagawa + resampling_index = traditional_resampling(particles,weights,rand); + elseif DynareOptions.particle.resampling.method.stratified + resampling_index = traditional_resampling(particles,weights,rand(size(weights))); + else + error('Unknow sampling method!') + end +else + if DynareOptions.particle.resampling.method.kitagawa + resampled_particles = residual_resampling(particles,weights,rand); + elseif DynareOptions.particle.resampling.method.stratified + resampled_particles = residual_resampling(particles,weights,rand(size(weights))); + else + error('Unknown sampling method!') + end +end \ No newline at end of file diff --git a/src/local_state_space_iteration/local_state_space_iteration_2.m b/src/local_state_space_iteration/local_state_space_iteration_2.m new file mode 100644 index 000000000..0c6a52d07 --- /dev/null +++ b/src/local_state_space_iteration/local_state_space_iteration_2.m @@ -0,0 +1,275 @@ +function [y,y_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,a,b,c)%yhat_,ss) + +%@info: +%! @deftypefn {Function File} {@var{y}, @var{y_} =} local_state_equation_2 (@var{yhat},@var{epsilon}, @var{ghx}, @var{ghu}, @var{constant}, @var{ghxx}, @var{ghuu}, @var{ghxu}, @var{yhat_}, @var{ss}) +%! @anchor{particle/local_state_space_iteration_2} +%! @sp 1 +%! Given the states (y) and structural innovations (epsilon), this routine computes the level of selected endogenous variables when the +%! model is approximated by an order two taylor expansion around the deterministic steady state. Depending on the number of input/output +%! argument the pruning algorithm advocated by C. Sims is used or not (this version should not be used if the selected endogenous variables +%! are not the states of the model). +%! +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item yhat +%! n*1 vector of doubles, initial condition, where n is the number of state variables. +%! @item epsilon +%! q*1 vector of doubles, structural innovations. +%! @item ghx +%! m*n matrix of doubles, restricted dr.ghx where we only consider the lines corresponding to a subset of endogenous variables. +%! @item ghu +%! m*q matrix of doubles, restricted dr.ghu where we only consider the lines corresponding to a subset of endogenous variables. +%! @item constant +%! m*1 vector of doubles, deterministic steady state plus second order correction for a subset of endogenous variables. +%! @item ghxx +%! m*n² matrix of doubles, restricted dr.ghxx where we only consider the lines corresponding to a subset of endogenous variables. +%! @item ghuu +%! m*q² matrix of doubles, restricted dr.ghuu where we only consider the lines corresponding to a subset of endogenous variables. +%! @item ghxu +%! m*(nq) matrix of doubles, subset of dr.ghxu where we only consider the lines corresponding to a subset of endogenous variables. +%! @item yhat_ +%! n*1 vector of doubles, spurious states for the pruning version. +%! @item ss +%! n*1 vector of doubles, steady state for the states. +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item y +%! m*1 vector of doubles, selected endogenous variables. +%! @item y_ +%! m*1 vector of doubles, update of the latent variables needed for the pruning version (first order update). +%! @end table +%! @sp 2 +%! @strong{Remarks} +%! @sp 1 +%! [1] If the function has 10 input arguments then it must have 2 output arguments (pruning version). +%! @sp 1 +%! [2] If the function has 08 input arguments then it must have 1 output argument. +%! @sp 2 +%! @strong{This function is called by:} +%! @sp 2 +%! @strong{This function calls:} +%! +%! +%! @end deftypefn +%@eod: + +% Copyright (C) 2011-2012 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 . + +% AUTHOR(S) stephane DOT adjemian AT univ DASH lemans DOT fr +% frederic DOT karame AT univ DASH evry DOT fr + +if nargin==9 + pruning = 0; numthreads = a; + if nargout>1 + error('local_state_space_iteration_2:: Numbers of input and output argument are inconsistent!') + end +elseif nargin==11 + pruning = 1; numthreads = c; yhat_ = a; ss = b; + if nargout~=2 + error('local_state_space_iteration_2:: Numbers of input and output argument are inconsistent!') + end +else + error('local_state_space_iteration_2:: Wrong number of input arguments!') +end + +number_of_threads = numthreads; + +switch pruning + case 0 + for i =1:size(yhat,2) + y(:,i) = constant + ghx*yhat(:,i) + ghu*epsilon(:,i) ... + + A_times_B_kronecker_C(.5*ghxx,yhat(:,i),number_of_threads) ... + + A_times_B_kronecker_C(.5*ghuu,epsilon(:,i),number_of_threads) ... + + A_times_B_kronecker_C(ghxu,yhat(:,i),epsilon(:,i),number_of_threads); + end + case 1 + for i =1:size(yhat,2) + y(:,i) = constant + ghx*yhat(:,i) + ghu*epsilon(:,i) ... + + A_times_B_kronecker_C(.5*ghxx,yhat_(:,i),number_of_threads) ... + + A_times_B_kronecker_C(.5*ghuu,epsilon(:,i),number_of_threads) ... + + A_times_B_kronecker_C(ghxu,yhat_(:,i),epsilon(:,i),number_of_threads); + end + y_ = ghx*yhat_+ghu*epsilon; + y_ = bsxfun(@plus,y_,ss); +end + +%@test:1 +%$ n = 2; +%$ q = 3; +%$ +%$ yhat = zeros(n,1); +%$ epsilon = zeros(q,1); +%$ ghx = rand(n,n); +%$ ghu = rand(n,q); +%$ constant = ones(n,1); +%$ ghxx = rand(n,n*n); +%$ ghuu = rand(n,q*q); +%$ ghxu = rand(n,n*q); +%$ yhat_ = zeros(n,1); +%$ ss = ones(n,1); +%$ +%$ % Call the tested routine. +%$ for i=1:10 +%$ y1 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); +%$ [y2,y2_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); +%$ end +%$ +%$ % Check the results. +%$ t(1) = dassert(y1,ones(n,1)); +%$ t(2) = dassert(y2,ones(n,1)); +%$ t(3) = dassert(y2_,ones(n,1)); +%$ T = all(t); +%@eof:1 + +%@test:2 +%$ old_path = pwd; +%$ cd([fileparts(which('dynare')) '/../tests/']); +%$ dynare('dsge_base2'); +%$ load dsge_base2; +%$ cd(old_path); +%$ dr = oo_.dr; +%$ clear('oo_','options_','M_'); +%$ delete([fileparts(which('dynare')) '/../tests/dsge_base2.mat']); +%$ istates = dr.nstatic+(1:dr.npred); +%$ n = dr.npred; +%$ q = size(dr.ghu,2); +%$ yhat = zeros(n,1); +%$ epsilon = zeros(q,1); +%$ ghx = dr.ghx(istates,:); +%$ ghu = dr.ghu(istates,:); +%$ constant = dr.ys(istates,:)+dr.ghs2(istates,:); +%$ ghxx = dr.ghxx(istates,:); +%$ ghuu = dr.ghuu(istates,:); +%$ ghxu = dr.ghxu(istates,:); +%$ yhat_ = zeros(n,1); +%$ ss = dr.ys(istates,:); +%$ +%$ t = ones(2,1); +%$ +%$ % Call the tested routine. +%$ try +%$ y1 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); +%$ catch +%$ t(1) = 0; +%$ end +%$ try +%$ [y2,y2_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); +%$ catch +%$ t(2) = 0; +%$ end +%$ +%$ % Check the results. +%$ T = all(t); +%@eof:2 + +%@test:3 +%$ Bohrbug = 1; % A bug that manifests reliably under a possibly unknown but well-defined set of conditions. +%$ if ~Bohrbug +%$ n = 2; +%$ q = 3; +%$ +%$ yhat = .01*randn(n,1); +%$ epsilon = .001*randn(q,1); +%$ ghx = rand(n,n); +%$ ghu = rand(n,q); +%$ constant = ones(n,1); +%$ ghxx = rand(n,n*n); +%$ ghuu = rand(n,q*q); +%$ ghxu = rand(n,n*q); +%$ yhat_ = zeros(n,1); +%$ ss = ones(n,1); +%$ +%$ % Call the tested routine (mex version). +%$ y1a = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); +%$ [y2a,y2a_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); +%$ +%$ % Call the tested routine (matlab version) +%$ path_to_mex = fileparts(which(['qmc_sequence.' mexext])); +%$ where_am_i_coming_from = pwd; +%$ cd(path_to_mex); +%$ tar('local_state_space_iteration_2.tar',['local_state_space_iteration_2.' mexext]); +%$ cd(where_am_i_coming_from); +%$ dynare_config([],0); +%$ y1b = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); +%$ [y2b,y2b_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); +%$ cd(path_to_mex); +%$ untar('local_state_space_iteration_2.tar'); +%$ delete('local_state_space_iteration_2.tar'); +%$ cd(where_am_i_coming_from); +%$ dynare_config([],0); +%$ % Check the results. +%$ t(1) = dassert(y1a,y1b); +%$ t(2) = dassert(y2a,y2b); +%$ t(3) = dassert(y2a_,y2b_); +%$ T = all(t); +%$ else +%$ t(1) = 1; +%$ T = all(t); +%$ end +%@eof:3 + + +%@test:4 +%$ % TIMING TEST (parallelization with openmp) +%$ old_path = pwd; +%$ cd([fileparts(which('dynare')) '/../tests/']); +%$ dynare('dsge_base2'); +%$ load dsge_base2; +%$ cd(old_path); +%$ dr = oo_.dr; +%$ clear('oo_','options_','M_'); +%$ delete([fileparts(which('dynare')) '/../tests/dsge_base2.mat']); +%$ istates = dr.nstatic+(1:dr.npred); +%$ n = dr.npred; +%$ q = size(dr.ghu,2); +%$ yhat = zeros(n,10000000); +%$ epsilon = zeros(q,10000000); +%$ ghx = dr.ghx(istates,:); +%$ ghu = dr.ghu(istates,:); +%$ constant = dr.ys(istates,:)+dr.ghs2(istates,:); +%$ ghxx = dr.ghxx(istates,:); +%$ ghuu = dr.ghuu(istates,:); +%$ ghxu = dr.ghxu(istates,:); +%$ yhat_ = zeros(n,10000000); +%$ ss = dr.ys(istates,:); +%$ +%$ t = NaN(4,1); +%$ tic, for i=1:10, y1 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); end +%$ t1 = toc; +%$ tic, for i=1:10, y2 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,2); end +%$ t2 = toc; +%$ t(1) = dassert(y1,y2,1e-15); clear('y1'); +%$ tic, for i=1:10, y3 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,3); end +%$ t3 = toc; +%$ t(2) = dassert(y2,y3,1e-15); clear('y2'); +%$ tic, for i=1:10, y4 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,4); end +%$ t4 = toc; +%$ t(3) = dassert(y4,y3,1e-15); clear('y3','y4'); +%$ t(4) = (t1>t2) && (t2>t3) && (t3>t4); +%$ if ~t(4) +%$ disp('Timmings:') +%$ [t1, t2, t3, t4] +%$ end +%$ % Check the results. +%$ T = all(t); +%@eof:4 diff --git a/src/measurement_equations.m b/src/measurement_equations.m new file mode 100644 index 000000000..c00d8ebc4 --- /dev/null +++ b/src/measurement_equations.m @@ -0,0 +1,33 @@ +function measure = measurement_equations(StateVectors,ReducedForm,DynareOptions) + +% Copyright (C) 2013 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 . + +mf1 = ReducedForm.mf1; +ghx = ReducedForm.ghx(mf1,:); +ghu = ReducedForm.ghu(mf1,:); +ghxx = ReducedForm.ghxx(mf1,:); +ghuu = ReducedForm.ghuu(mf1,:); +ghxu = ReducedForm.ghxu(mf1,:); +constant = ReducedForm.constant(mf1,:); +state_variables_steady_state = ReducedForm.state_variables_steady_state; +number_of_structural_innovations = length(ReducedForm.Q); +yhat = bsxfun(@minus,StateVectors,state_variables_steady_state) ; +measure = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,size(yhat,2)),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + + + diff --git a/src/multivariate_smooth_resampling.m b/src/multivariate_smooth_resampling.m new file mode 100644 index 000000000..09ca287b9 --- /dev/null +++ b/src/multivariate_smooth_resampling.m @@ -0,0 +1,72 @@ +function new_particles = multivariate_smooth_resampling(particles,weights) +% Smooth Resampling of the particles. + +%@info: +%! @deftypefn {Function File} {@var{new_particles} =} multivariate_smooth_resampling (@var{weights}, @var{particles}, @var{number_of_new_particles}, @var{number_of_partitions}) +%! @anchor{particle/multivariate_smooth_resampling} +%! @sp 1 +%! Smooth Resampling of the particles (multivariate version). +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item weights +%! n*1 vector of doubles, particles' weights. +%! @item particles +%! n*1 vector of doubles, particles. +%! @item number_of_new_particles +%! Integer scalar. +%! @item number_of_partitions +%! Integer scalar. +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item indx +%! number_of_new_particles*1 vector of doubles, new particles. +%! @end table +%! @sp 2 +%! @strong{This function is called by:} +%! @sp 1 +%! @ref{particle/sequantial_importance_particle_filter} +%! @sp 2 +%! @strong{This function calls:} +%! @sp 1 +%! @ref{particle/univariate_smooth_resampling} +%! @sp 2 +%! @end deftypefn +%@eod: + +% Copyright (C) 2012-2013 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 . + +% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr +% stephane DOT adjemian AT univ DASH lemans DOT fr + +number_of_particles = length(weights); +number_of_states = size(particles,2); +[P,D] = eig(particles'*(bsxfun(@times,1/number_of_particles,particles))) ; +D = diag(D) ; +vectors = bsxfun(@times,P,sqrt(D)') ; +orthogonalized_particles = bsxfun(@rdivide,particles*vectors,D') ; +new_particles = zeros(number_of_particles,number_of_states) ; +for j=1:number_of_states + tout = sortrows( [orthogonalized_particles(:,j) weights],1) ; + new_particles(:,j) = univariate_smooth_resampling(tout(:,2),tout(:,1),number_of_particles) ; +end +new_particles = new_particles*(vectors') ; diff --git a/src/mykmeans.m b/src/mykmeans.m new file mode 100644 index 000000000..56af5390b --- /dev/null +++ b/src/mykmeans.m @@ -0,0 +1,53 @@ +function [c,SqrtVariance,Weights] = mykmeans(x,g,init,cod) + +% Copyright (C) 2013 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 . + +[n,m] = size(x) ; +indold = zeros(1,m) ; +if cod==0 + d = transpose(sum(bsxfun(@power,bsxfun(@minus,x,mean(x)),2))); + d = sortrows( [transpose(1:m) d],2) ; + d = d((1+(0:1:g-1))*m/g,1) ; + c = x(:,d); +else + c = init ; +end +for iter=1:300 + dist = zeros(g,m) ; + for i=1:g + dist(i,:) = sum(bsxfun(@power,bsxfun(@minus,x,c(:,i)),2)); + end + [rien,ind] = min(dist) ; + if isequal(ind,indold) + break ; + end + indold = ind ; + for i=1:g + lin = bsxfun(@eq,ind,i.*ones(1,m)) ; + h = x(:,lin) ; + c(:,i) = mean(h,2) ; + end +end +SqrtVariance = zeros(n,n,g) ; +Weights = zeros(1,g) ; +for i=1:g + temp = x(:,bsxfun(@eq,ind,i*ones(1,m))) ; + u = bsxfun(@minus,temp,mean(temp,2)); %temp-mean(temp,1)' ; + SqrtVariance(:,:,i) = chol( (u*u')/size(temp,2) )' ; + Weights(i) = size(temp,2)/m ; +end diff --git a/src/neff.m b/src/neff.m new file mode 100644 index 000000000..5251b9f17 --- /dev/null +++ b/src/neff.m @@ -0,0 +1,21 @@ +function n = neff(w) +% Evaluates the criterion for resampling + +% Copyright (C) 2013 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 . + +n = dot(w,w); diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m new file mode 100644 index 000000000..4a8243a2d --- /dev/null +++ b/src/online_auxiliary_filter.m @@ -0,0 +1,373 @@ +function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) + +% Carvalho & Lopes particle filter = auxiliary particle filter including Liu & West filter on parameters. +% +% INPUTS +% ReducedForm [structure] Matlab's structure describing the reduced form model. +% ReducedForm.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% ReducedForm.state.Q [double] (qq x qq) variance matrix of state errors. +% ReducedForm.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% start [integer] scalar, likelihood evaluation starts at 'start'. +% mf [integer] pp*1 vector of indices. +% number_of_particles [integer] scalar. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. + +% Copyright (C) 2013 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . +persistent Y init_flag mf0 mf1 bounds number_of_particles number_of_parameters liu_west_delta liu_west_chol_sigma_bar +persistent start_param sample_size number_of_observed_variables number_of_structural_innovations + +% Set seed for randn(). +set_dynare_seed('default') ; +pruning = DynareOptions.particle.pruning; +second_resample = 1 ; +variance_update = 1 ; + +% initialization of state particles +[ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... + solve_model_for_online_filter(1,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; + +% Set persistent variables. +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + number_of_particles = DynareOptions.particle.number_of_particles; + number_of_parameters = size(xparam1,1) ; + Y = DynareDataset.data ; + sample_size = size(Y,2); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + liu_west_delta = DynareOptions.particle.liu_west_delta ; + %liu_west_chol_sigma_bar = DynareOptions.particle.liu_west_chol_sigma_bar*eye(number_of_parameters) ; + start_param = xparam1 ; + %liu_west_chol_sigma_bar = sqrt(bsxfun(@times,eye(number_of_parameters),BayesInfo.p2)) ; + %start_param = BayesInfo.p1 ; + bounds = [BayesInfo.lb BayesInfo.ub] ; + init_flag = 1; +end + +% Get initial conditions for the state particles +StateVectorMean = ReducedForm.StateVectorMean; +StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +state_variance_rank = size(StateVectorVarianceSquareRoot,2); +StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); +if pruning + StateVectors_ = StateVectors; +end + +% parameters for the Liu & West filter +h_square = (3*liu_west_delta-1)/(2*liu_west_delta) ; +h_square = 1-h_square*h_square ; +small_a = sqrt(1-h_square) ; + +% Initialization of parameter particles +xparam = zeros(number_of_parameters,number_of_particles) ; +stderr = sqrt(bsxfun(@power,bounds(:,2)+bounds(:,1),2)/12)/100 ; +stderr = sqrt(bsxfun(@power,bounds(:,2)+bounds(:,1),2)/12)/50 ; +i = 1 ; +while i<=number_of_particles + %candidate = start_param + .001*liu_west_chol_sigma_bar*randn(number_of_parameters,1) ; + candidate = start_param + bsxfun(@times,stderr,randn(number_of_parameters,1)) ; + if all(candidate(:) >= bounds(:,1)) && all(candidate(:) <= bounds(:,2)) + xparam(:,i) = candidate(:) ; + i = i+1 ; + end +end + +%xparam = bsxfun(@plus,bounds(:,1),bsxfun(@times,(bounds(:,2)-bounds(:,1)),rand(number_of_parameters,number_of_particles))) ; + +% Initialization of the weights of particles. +weights = ones(1,number_of_particles)/number_of_particles ; + +% Initialization of the likelihood. +const_lik = log(2*pi)*number_of_observed_variables; +mean_xparam = zeros(number_of_parameters,sample_size) ; +median_xparam = zeros(number_of_parameters,sample_size) ; +std_xparam = zeros(number_of_parameters,sample_size) ; +lb95_xparam = zeros(number_of_parameters,sample_size) ; +ub95_xparam = zeros(number_of_parameters,sample_size) ; + +%% The Online filter +for t=1:sample_size + disp(t) + % Moments of parameters particles distribution + m_bar = xparam*(weights') ; + temp = bsxfun(@minus,xparam,m_bar) ; + sigma_bar = (bsxfun(@times,weights,temp))*(temp') ; + if variance_update==1 + chol_sigma_bar = chol(h_square*sigma_bar)' ; + end + % Prediction (without shocks) + ObservedVariables = zeros(number_of_observed_variables,number_of_particles) ; + for i=1:number_of_particles + % model resolution + [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... + solve_model_for_online_filter(t,xparam(:,i),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; + steadystate = ReducedForm.steadystate; + state_variables_steady_state = ReducedForm.state_variables_steady_state; + % Set local state space model (second-order approximation). + constant = ReducedForm.constant; + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; + % particle likelihood contribution + yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); + if pruning + yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); + [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + else + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + end + ObservedVariables(:,i) = tmp(mf1,:) ; + end + PredictedObservedMean = sum(bsxfun(@times,weights,ObservedVariables),2) ; + PredictionError = bsxfun(@minus,Y(:,t),ObservedVariables); + dPredictedObservedMean = bsxfun(@minus,ObservedVariables,PredictedObservedMean); + PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' + ReducedForm.H ; + wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; + % unormalized weights and observation likelihood contribution + tau_tilde = weights.*wtilde ; + sum_tau_tilde = sum(tau_tilde) ; + % particles selection + tau_tilde = tau_tilde/sum_tau_tilde ; + indx = index_resample(0,tau_tilde',DynareOptions); + StateVectors = StateVectors(:,indx) ; + if pruning + StateVectors_ = StateVectors_(:,indx) ; + end + xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam) ; + xparam = xparam(:,indx) ; + wtilde = wtilde(indx) ; + % draw in the new distributions + i = 1 ; + while i<=number_of_particles + candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters,1) ; + if all(candidate >= bounds(:,1)) && all(candidate <= bounds(:,2)) + xparam(:,i) = candidate ; + % model resolution for new parameters particles + [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... + solve_model_for_online_filter(t,xparam(:,i),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; + steadystate = ReducedForm.steadystate; + state_variables_steady_state = ReducedForm.state_variables_steady_state; + % Set local state space model (second order approximation). + constant = ReducedForm.constant; + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; + % Get covariance matrices and structural shocks + epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations,1) ; + % compute particles likelihood contribution + yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); + if pruning + yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + StateVectors_(:,i) = tmp_(mf0,:) ; + else + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + end + StateVectors(:,i) = tmp(mf0,:) ; + ObservedVariables(:,i) = tmp(mf1,:) ; + i = i+1 ; + end + end + PredictedObservedMean = sum(bsxfun(@times,weights,ObservedVariables),2) ; + PredictionError = bsxfun(@minus,Y(:,t),ObservedVariables); + dPredictedObservedMean = bsxfun(@minus,ObservedVariables,PredictedObservedMean); + PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' + ReducedForm.H ; + lnw = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))); + % importance ratio + wtilde = lnw./wtilde ; + % normalization + weights = wtilde/sum(wtilde); + if (variance_update==1) && (neff(weights)0.025 && pass1==1 + lb95_xparam(i,t) = (temp(j-1,1)+temp(j,1))/2 ; + pass1 = 2 ; + end + if cumulated_weights(j)>0.5 && pass2==1 + median_xparam(i,t) = (temp(j-1,1)+temp(j,1))/2 ; + pass2 = 2 ; + end + if cumulated_weights(j)>0.975 && pass3==1 + ub95_xparam(i,t) = (temp(j-1,1)+temp(j,1))/2 ; + pass3 = 2 ; + end + end + end + end + disp([lb95_xparam(:,t) mean_xparam(:,t) ub95_xparam(:,t)]) +end +distrib_param = xparam ; +xparam = mean_xparam(:,sample_size) ; +std_param = std_xparam(:,sample_size) ; +lb_95 = lb95_xparam(:,sample_size) ; +ub_95 = ub95_xparam(:,sample_size) ; +median_param = median_xparam(:,sample_size) ; + +%% Plot parameters trajectory +TeX = DynareOptions.TeX; + +[nbplt,nr,nc,lr,lc,nstar] = pltorg(number_of_parameters); + +if TeX + fidTeX = fopen([Model.fname '_param_traj.TeX'],'w'); + fprintf(fidTeX,'%% TeX eps-loader file generated by online_auxiliary_filter.m (Dynare).\n'); + fprintf(fidTeX,['%% ' datestr(now,0) '\n']); + fprintf(fidTeX,' \n'); +end + +z = 1:1:sample_size ; + +for plt = 1:nbplt, + if TeX + NAMES = []; + TeXNAMES = []; + end + hh = dyn_figure(DynareOptions,'Name','Parameters Trajectories'); + for k=1:min(nstar,length(xparam)-(plt-1)*nstar) + subplot(nr,nc,k) + kk = (plt-1)*nstar+k; + [name,texname] = get_the_name(kk,TeX,Model,EstimatedParameters,DynareOptions); + if TeX + if isempty(NAMES) + NAMES = name; + TeXNAMES = texname; + else + NAMES = char(NAMES,name); + TeXNAMES = char(TeXNAMES,texname); + end + end + y = [mean_xparam(kk,:)' median_xparam(kk,:)' lb95_xparam(kk,:)' ub95_xparam(kk,:)' xparam(kk)*ones(sample_size,1)] ; + plot(z,y); + hold on + title(name,'interpreter','none') + hold off + axis tight + drawnow + end + dyn_saveas(hh,[ Model.fname '_param_traj' int2str(plt) ],DynareOptions); + if TeX + % TeX eps loader file + fprintf(fidTeX,'\\begin{figure}[H]\n'); + for jj = 1:min(nstar,length(x)-(plt-1)*nstar) + fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); + end + fprintf(fidTeX,'\\centering \n'); + fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParamTraj%s}\n',Model.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{Parameters trajectories.}'); + fprintf(fidTeX,'\\label{Fig:ParametersPlots:%s}\n',int2str(plt)); + fprintf(fidTeX,'\\end{figure}\n'); + fprintf(fidTeX,' \n'); + end +end + +%% Plot Parameter Densities +number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. +bandwidth = 0; % Rule of thumb optimal bandwidth parameter. +kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. +for plt = 1:nbplt, + if TeX + NAMES = []; + TeXNAMES = []; + end + hh = dyn_figure(DynareOptions,'Name','Parameters Densities'); + for k=1:min(nstar,length(xparam)-(plt-1)*nstar) + subplot(nr,nc,k) + kk = (plt-1)*nstar+k; + [name,texname] = get_the_name(kk,TeX,Model,EstimatedParameters,DynareOptions); + if TeX + if isempty(NAMES) + NAMES = name; + TeXNAMES = texname; + else + NAMES = char(NAMES,name); + TeXNAMES = char(TeXNAMES,texname); + end + end + optimal_bandwidth = mh_optimal_bandwidth(distrib_param(kk,:)',number_of_particles,bandwidth,kernel_function); + [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(kk,:)',number_of_grid_points,... + number_of_particles,optimal_bandwidth,kernel_function); + plot(density(:,1),density(:,2)); + hold on + title(name,'interpreter','none') + hold off + axis tight + drawnow + end + dyn_saveas(hh,[ Model.fname '_param_density' int2str(plt) ],DynareOptions); + if TeX + % TeX eps loader file + fprintf(fidTeX,'\\begin{figure}[H]\n'); + for jj = 1:min(nstar,length(x)-(plt-1)*nstar) + fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); + end + fprintf(fidTeX,'\\centering \n'); + fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',Model.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{ParametersDensities.}'); + fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); + fprintf(fidTeX,'\\end{figure}\n'); + fprintf(fidTeX,' \n'); + end +end + \ No newline at end of file diff --git a/src/probability.m b/src/probability.m new file mode 100644 index 000000000..5d76e49ee --- /dev/null +++ b/src/probability.m @@ -0,0 +1,39 @@ +function [prior,likelihood,C,posterior] = probability(mu,sqrtP,prior,X) + +% Copyright (C) 2013 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 . + +[dim,nov] = size(X); +M = size(mu,2) ; +if nargout>1 + likelihood = zeros(M,nov); + normfact = (2*pi)^(dim/2); + for k=1:M + XX = bsxfun(@minus,X,mu(:,k)); + S = sqrtP(:,:,k); + foo = S \ XX; + likelihood(k,:) = exp(-0.5*sum(foo.*foo, 1))/abs((normfact*prod(diag(S)))); + end +end +likelihood = likelihood + 1e-99; +if nargout>2 + C = prior*likelihood + 1e-99; +end +if nargout>3 + posterior = bsxfun(@rdivide,bsxfun(@times,prior',likelihood),C) + 1e-99 ; + posterior = bsxfun(@rdivide,posterior,sum(posterior,1)); +end diff --git a/src/probability2.m b/src/probability2.m new file mode 100644 index 000000000..57ab65f8f --- /dev/null +++ b/src/probability2.m @@ -0,0 +1,38 @@ +function [density] = probability2(mu,S,X) +% +% Multivariate gaussian density +% +% INPUTS +% n [integer] scalar, number of variables. +% +% OUTPUTS +% nodes [double] nodes of the cubature +% weigths [double] associated weigths +% +% REFERENCES +% +% +% NOTES +% +% Copyright (C) 2009-2012 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 . + +dim = size(X,1) ; +normfact = bsxfun(@power,(2*pi),(dim/2)) ; +foo = S\(bsxfun(@minus,X,mu)) ; +density = exp(-0.5*sum(foo.*foo)')./abs((normfact*prod(diag(S)))) + 1e-99 ; + diff --git a/src/resample.m b/src/resample.m new file mode 100644 index 000000000..a72894428 --- /dev/null +++ b/src/resample.m @@ -0,0 +1,74 @@ +function resampled_particles = resample(particles,weights,DynareOptions) +% Resamples particles. + +%@info: +%! @deftypefn {Function File} {@var{indx} =} resample (@var{weights}, @var{method}) +%! @anchor{particle/resample} +%! @sp 1 +%! Resamples particles. +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item weights +%! n*1 vector of doubles, particles' weights. +%! @item method +%! string equal to 'residual' or 'traditional'. +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item indx +%! n*1 vector of intergers, indices. +%! @end table +%! @sp 2 +%! @strong{This function is called by:} +%! @sp 1 +%! @ref{particle/sequantial_importance_particle_filter} +%! @sp 2 +%! @strong{This function calls:} +%! @sp 1 +%! @ref{residual_resampling}, @ref{traditional_resampling} +%! @sp 2 +%! @end deftypefn +%@eod: + +% Copyright (C) 2011-2013 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 . + +defaultmethod = 1; % For residual based method set this variable equal to 0. + +if defaultmethod + if DynareOptions.particle.resampling.method.kitagawa + resampled_particles = traditional_resampling(particles,weights,rand); + elseif DynareOptions.particle.resampling.method.stratified + resampled_particles = traditional_resampling(particles,weights,rand(size(weights))); + elseif DynareOptions.particle.resampling.method.smooth + resampled_particles = multivariate_smooth_resampling(particles,weights); + else + error('Unknow sampling method!') + end +else + if DynareOptions.particle.resampling.method.kitagawa + resampled_particles = residual_resampling(particles,weights,rand); + elseif DynareOptions.particle.resampling.method.stratified + resampled_particles = residual_resampling(particles,weights,rand(size(weights))); + else + error('Unknown sampling method!') + end +end diff --git a/src/residual_resampling.m b/src/residual_resampling.m new file mode 100644 index 000000000..c2f09e3b8 --- /dev/null +++ b/src/residual_resampling.m @@ -0,0 +1,143 @@ +function return_resample = residual_resampling(particles,weights,noise) +% Resamples particles. + +%@info: +%! @deftypefn {Function File} {@var{indx} =} residual_resampling (@var{weights}) +%! @anchor{particle/residual_resampling} +%! @sp 1 +%! Resamples particles. +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item weights +%! n*1 vector of doubles, particles' weights. +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item indx +%! n*1 vector of intergers, indices. +%! @end table +%! @sp 2 +%! @strong{This function is called by:} +%! @sp 1 +%! @ref{particle/resample} +%! @sp 2 +%! @strong{This function calls:} +%! @sp 2 +%! @end deftypefn +%@eod: + +% Copyright (C) 2011-2013 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 . + +% AUTHOR(S) frederic DOT karame AT univ DASH evry DOT fr +% stephane DOT adjemian AT univ DASH lemans DOT fr + +% What is the number of particles? +number_of_particles = length(weights); + +switch length(noise) + case 1 + kitagawa_resampling = 1; + case number_of_particles + kitagawa_resampling = 0; + otherwise + error(['particle::resampling: Unknown method! The size of the second argument (' inputname(3) ') is wrong.']) +end + +% Set vectors of indices. +jndx = 1:number_of_particles; +indx = zeros(1,number_of_particles); + +% Multiply the weights by the number of particles. +WEIGHTS = number_of_particles*weights; + +% Compute the integer part of the normalized weights. +iWEIGHTS = fix(WEIGHTS); + +% Compute the number of resample +number_of_trials = number_of_particles-sum(iWEIGHTS); + +if number_of_trials + WEIGHTS = (WEIGHTS-iWEIGHTS)/number_of_trials; + EmpiricalCDF = cumsum(WEIGHTS); + if kitagawa_resampling + u = (transpose(1:number_of_trials)-1+noise(:))/number_of_trials; + else + u = fliplr(cumprod(noise(1:number_of_trials).^(1./(number_of_trials:-1:1)))); + end + j=1; + for i=1:number_of_trials + while (u(i)>EmpiricalCDF(j)) + j=j+1; + end + iWEIGHTS(j)=iWEIGHTS(j)+1; + if kitagawa_resampling==0 + j=1; + end + end +end + +k=1; +for i=1:number_of_particles + if (iWEIGHTS(i)>0) + for j=k:k+iWEIGHTS(i)-1 + indx(j) = jndx(i); + end + end + k = k + iWEIGHTS(i); +end + +if particles==0 + return_resample = indx ; +else + return_resample = particles(indx,:) ; +end +%@test:1 +%$ % Define the weights +%$ weights = randn(2000,1).^2; +%$ weights = weights/sum(weights); +%$ % Initialize t. +%$ t = ones(1,1); +%$ +%$ try +%$ indx1 = residual_resampling(weights); +%$ catch +%$ t(1) = 0; +%$ end +%$ +%$ T = all(t); +%@eof:1 + +%@test:2 +%$ % Define the weights +%$ weights = exp(randn(2000,1)); +%$ weights = weights/sum(weights); +%$ % Initialize t. +%$ t = ones(1,1); +%$ +%$ try +%$ indx1 = residual_resampling(weights); +%$ catch +%$ t(1) = 0; +%$ end +%$ +%$ T = all(t); +%@eof:2 \ No newline at end of file diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m new file mode 100644 index 000000000..eadaeba41 --- /dev/null +++ b/src/sequential_importance_particle_filter.m @@ -0,0 +1,178 @@ +function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,DynareOptions) +% Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). +% Standard Sequential Monte Carlo approach with +% - the usual proposal (the state transition distribution) +% - options on resampling: none, adaptive or systematic +%@info: +%! @deftypefn {Function File} {@var{y}, @var{y_} =} sequential_importance_particle_filter (@var{ReducedForm},@var{Y}, @var{start}, @var{DynareOptions}) +%! @anchor{particle/sequential_importance_particle_filter} +%! @sp 1 +%! Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). +%! +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item ReducedForm +%! Structure describing the state space model (built in @ref{non_linear_dsge_likelihood}). +%! @item Y +%! p*smpl matrix of doubles (p is the number of observed variables), the (detrended) data. +%! @item start +%! Integer scalar, likelihood evaluation starts at observation 'start'. +%! @item DynareOptions +%! Structure specifying Dynare's options. +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item LIK +%! double scalar, value of (minus) the logged likelihood. +%! @item lik +%! smpl*1 vector of doubles, density of the observations at each period. +%! @end table +%! @sp 2 +%! @strong{This function is called by:} +%! @ref{non_linear_dsge_likelihood} +%! @sp 2 +%! @strong{This function calls:} +%! +%! @end deftypefn +%@eod: + +% Copyright (C) 2011-2013 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 . + +% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr +% stephane DOT adjemian AT univ DASH lemans DOT fr + +persistent init_flag +persistent mf0 mf1 +persistent number_of_particles number_of_state_variables +persistent sample_size number_of_observed_variables number_of_structural_innovations + +% Set default value for start +if isempty(start) + start = 1; +end + +% Set flag for prunning +pruning = DynareOptions.particle.pruning; + +% Get steady state and mean. +steadystate = ReducedForm.steadystate; +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables (if needed). +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + number_of_particles = DynareOptions.particle.number_of_particles; + init_flag = 1; +end + +% Set local state space model (first order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; + +% Set local state space model (second order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +% Get covariance matrices. +Q = ReducedForm.Q; % Covariance matrix of the structural innovations. +H = ReducedForm.H; % Covariance matrix of the measurement errors. +if isempty(H) + H = 0; +end + +% Initialization of the likelihood. +const_lik = log(2*pi)*number_of_observed_variables; +lik = NaN(sample_size,1); + +% Get initial condition for the state vector. +StateVectorMean = ReducedForm.StateVectorMean; +StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +if pruning + StateVectorMean_ = StateVectorMean; + StateVectorVarianceSquareRoot_ = StateVectorVarianceSquareRoot; +end + +% Get the rank of StateVectorVarianceSquareRoot +state_variance_rank = size(StateVectorVarianceSquareRoot,2); + +% Factorize the covariance matrix of the structural innovations +Q_lower_triangular_cholesky = chol(Q)'; + +% Set seed for randn(). +set_dynare_seed('default'); + +% Initialization of the weights across particles. +weights = ones(1,number_of_particles)/number_of_particles ; +StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); +if pruning + StateVectors_ = StateVectors; +end + +% Loop over observations +for t=1:sample_size + yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); + epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); + if pruning + yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + else + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + end + PredictedObservedMean = tmp(mf1,:)*transpose(weights); + PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); + dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + PredictedObservedVariance = bsxfun(@times,dPredictedObservedMean,weights)*dPredictedObservedMean' + H; + if rcond(PredictedObservedVariance) > 1e-16 + lnw = -.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1)); + else + LIK = NaN; + return + end + dfac = max(lnw); + wtilde = weights.*exp(lnw-dfac); + lik(t) = log(sum(wtilde))+dfac; + weights = wtilde/sum(wtilde); + if (DynareOptions.particle.resampling.status.generic && neff(weights). + +% AUTHOR(S) stephane DOT adjemian AT univ DASH lemans DOT fr +% frederic DOT karame AT univ DASH lemans DOT fr + +%global objective_function_penalty_base +% Declaration of the penalty as a persistent variable. +persistent init_flag +persistent restrict_variables_idx observed_variables_idx state_variables_idx mf0 mf1 +persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations + +% Initialization of the returned arguments. +fval = []; +ys = []; +trend_coeff = []; +exit_flag = 1; + +% Set the number of observed variables +nvobs = DynareDataset.info.nvobs; + +%------------------------------------------------------------------------------ +% 1. Get the structural parameters & define penalties +%------------------------------------------------------------------------------ + +% Return, with endogenous penalty, if some parameters are smaller than the lower bound of the prior domain. +%if (DynareOptions.mode_compute~=1) && any(xparam1BayesInfo.ub) +% k = find(xparam1(:)>BayesInfo.ub); +% fval = objective_function_penalty_base+sum((xparam1(k)-BayesInfo.ub(k)).^2); +% exit_flag = 0; +% info = 42; +% return +%end + +% Get the diagonal elements of the covariance matrices for the structural innovations (Q) and the measurement error (H). +Q = Model.Sigma_e; +H = Model.H; +for i=1:EstimatedParameters.nvx + k =EstimatedParameters.var_exo(i,1); + Q(k,k) = xparam1(i)*xparam1(i); +end +offset = EstimatedParameters.nvx; +if EstimatedParameters.nvn + for i=1:EstimatedParameters.nvn + H(i,i) = xparam1(i+offset)*xparam1(i+offset); + end + offset = offset+EstimatedParameters.nvn; +else + H = zeros(nvobs); +end + +% Get the off-diagonal elements of the covariance matrix for the structural innovations. Test if Q is positive definite. +if EstimatedParameters.ncx + for i=1:EstimatedParameters.ncx + k1 =EstimatedParameters.corrx(i,1); + k2 =EstimatedParameters.corrx(i,2); + Q(k1,k2) = xparam1(i+offset)*sqrt(Q(k1,k1)*Q(k2,k2)); + Q(k2,k1) = Q(k1,k2); + end + % Try to compute the cholesky decomposition of Q (possible iff Q is positive definite) +% [CholQ,testQ] = chol(Q); +% if testQ + % The variance-covariance matrix of the structural innovations is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. +% a = diag(eig(Q)); +% k = find(a < 0); +% if k > 0 +% fval = objective_function_penalty_base+sum(-a(k)); +% exit_flag = 0; +% info = 43; +% return +% end +% end + offset = offset+EstimatedParameters.ncx; +end + +% Get the off-diagonal elements of the covariance matrix for the measurement errors. Test if H is positive definite. +if EstimatedParameters.ncn + corrn_observable_correspondence = EstimatedParameters.corrn_observable_correspondence; + for i=1:EstimatedParameters.ncn + k1 = corrn_observable_correspondence(i,1); + k2 = corrn_observable_correspondence(i,2); + H(k1,k2) = xparam1(i+offset)*sqrt(H(k1,k1)*H(k2,k2)); + H(k2,k1) = H(k1,k2); + end + % Try to compute the cholesky decomposition of H (possible iff H is positive definite) +% [CholH,testH] = chol(H); +% if testH + % The variance-covariance matrix of the measurement errors is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. +% a = diag(eig(H)); +% k = find(a < 0); +% if k > 0 +% fval = objective_function_penalty_base+sum(-a(k)); +% exit_flag = 0; +% info = 44; +% return +% end +% end + offset = offset+EstimatedParameters.ncn; +end + +% Update estimated structural parameters in Mode.params. +if EstimatedParameters.np > 0 + Model.params(EstimatedParameters.param_vals(:,1)) = xparam1(offset+1:end); +end + +% Update Model.Sigma_e and Model.H. +Model.Sigma_e = Q; +Model.H = H; + +%------------------------------------------------------------------------------ +% 2. call model setup & reduction program +%------------------------------------------------------------------------------ + +% Linearize the model around the deterministic sdteadystate and extract the matrices of the state equation (T and R). +[T,R,SteadyState,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict'); + +%if info(1) == 1 || info(1) == 2 || info(1) == 5 +% fval = objective_function_penalty_base+1; +% exit_flag = 0; +% return +%elseif info(1) == 3 || info(1) == 4 || info(1)==6 ||info(1) == 19 || info(1) == 20 || info(1) == 21 +% fval = objective_function_penalty_base+info(2); +% exit_flag = 0; +% return +%end + +% Define a vector of indices for the observed variables. Is this really usefull?... +BayesInfo.mf = BayesInfo.mf1; + +% Define the deterministic linear trend of the measurement equation. +if DynareOptions.noconstant + constant = zeros(nvobs,1); +else + if DynareOptions.loglinear + constant = log(SteadyState(BayesInfo.mfys)); + else + constant = SteadyState(BayesInfo.mfys); + end +end + +% Define the deterministic linear trend of the measurement equation. +if BayesInfo.with_trend + trend_coeff = zeros(DynareDataset.info.nvobs,1); + t = DynareOptions.trend_coeffs; + for i=1:length(t) + if ~isempty(t{i}) + trend_coeff(i) = evalin('base',t{i}); + end + end + trend = repmat(constant,1,DynareDataset.info.ntobs)+trend_coeff*[1:DynareDataset.info.ntobs]; +else + trend = repmat(constant,1,DynareDataset.info.ntobs); +end + +% Get needed informations for kalman filter routines. +start = DynareOptions.presample+1; +np = size(T,1); +mf = BayesInfo.mf; +Y = transpose(DynareDataset.rawdata); + +%------------------------------------------------------------------------------ +% 3. Initial condition of the Kalman filter +%------------------------------------------------------------------------------ + +% Get decision rules and transition equations. +dr = DynareResults.dr; + +% Set persistent variables (first call). +if isempty(init_flag) + mf0 = BayesInfo.mf0; + mf1 = BayesInfo.mf1; + restrict_variables_idx = BayesInfo.restrict_var_list; + observed_variables_idx = restrict_variables_idx(mf1); + state_variables_idx = restrict_variables_idx(mf0); + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(Q); + init_flag = 1; +end + +ReducedForm.ghx = dr.ghx(restrict_variables_idx,:); +ReducedForm.ghu = dr.ghu(restrict_variables_idx,:); +ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); +ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); +ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); +ReducedForm.steadystate = dr.ys(dr.order_var(restrict_variables_idx)); +ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); +ReducedForm.state_variables_steady_state = dr.ys(dr.order_var(state_variables_idx)); +ReducedForm.Q = Q; +ReducedForm.H = H; +ReducedForm.mf0 = mf0; +ReducedForm.mf1 = mf1; + +% Set initial condition for t=1 +if observation_number==1 + switch DynareOptions.particle.initialization + case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. + StateVectorMean = ReducedForm.constant(mf0); + StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',1e-12,1e-12,[],[],DynareOptions.debug); + case 2% Initial state vector covariance is a monte-carlo based estimate of the ergodic variance (consistent with a k-order Taylor-approximation of the model). + StateVectorMean = ReducedForm.constant(mf0); + old_DynareOptionsperiods = DynareOptions.periods; + DynareOptions.periods = 5000; + y_ = simult(oo_.steady_state, dr,Model,DynareOptions,DynareResults); + y_ = y_(state_variables_idx,2001:5000); + StateVectorVariance = cov(y_'); + DynareOptions.periods = old_DynareOptionsperiods; + clear('old_DynareOptionsperiods','y_'); + case 3% Initial state vector covariance is a diagonal matrix. + StateVectorMean = ReducedForm.constant(mf0); + StateVectorVariance = DynareOptions.particle.initial_state_prior_std*eye(number_of_state_variables); + otherwise + error('Unknown initialization option!') + end + ReducedForm.StateVectorMean = StateVectorMean; + ReducedForm.StateVectorVariance = StateVectorVariance; +end diff --git a/src/spherical_radial_sigma_points.m b/src/spherical_radial_sigma_points.m new file mode 100644 index 000000000..754caacfa --- /dev/null +++ b/src/spherical_radial_sigma_points.m @@ -0,0 +1,36 @@ +function [nodes,weights] = spherical_radial_sigma_points(n) +% +% Computes nodes and weigths from a third-degree spherical-radial cubature +% rule. +% INPUTS +% n [integer] scalar, number of variables. +% +% OUTPUTS +% nodes [double] nodes of the cubature +% weigths [double] associated weigths +% +% REFERENCES +% +% Arasaratnam & Haykin 2008,2009. +% +% NOTES +% +% Copyright (C) 2009-2012 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 . + +nodes = (sqrt(n)*([eye(n) -eye(n)]))' ; +weights = (1/(2*n)) ; diff --git a/src/traditional_resampling.m b/src/traditional_resampling.m new file mode 100644 index 000000000..a9d86eb36 --- /dev/null +++ b/src/traditional_resampling.m @@ -0,0 +1,237 @@ +function return_resample = traditional_resampling(particles,weights,noise) +% Resamples particles. + +%@info: +%! @deftypefn {Function File} {@var{indx} =} traditional_resampling (@var{weights},@var{noise}) +%! @anchor{particle/traditional_resampling} +%! @sp 1 +%! Resamples particles (Resampling à la Kitagawa or stratified resampling). +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item weights +%! n*1 vector of doubles, particles' weights. +%! @item noise +%! n*1 vector of doubles sampled from a [0,1] uniform distribution (stratified resampling) or scalar double +%! sampled from a [0,1] uniform distribution (Kitagawa resampling). +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item indx +%! n*1 vector of intergers, indices. +%! @end table +%! @sp 2 +%! @strong{This function is called by:} +%! @sp 1 +%! @ref{particle/resample} +%! @sp 2 +%! @strong{This function calls:} +%! @sp 2 +%! @end deftypefn +%@eod: + +% Copyright (C) 2011-2013 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 . + +% AUTHOR(S) frederic DOT karame AT univ DASH evry DOT fr +% stephane DOT adjemian AT univ DASH lemans DOT fr + +% What is the number of particles? +number_of_particles = length(weights); + +% Initialize the returned argument. +indx = ones(number_of_particles,1); + +% Select method. +switch length(noise) + case 1 + kitagawa_resampling = 1; + case number_of_particles + kitagawa_resampling = 0; + otherwise + error(['particle::resampling: Unknown method! The size of the second argument (' inputname(3) ') is wrong.']) +end + +% Get the empirical CDF. +c = cumsum(weights); + +% Draw a starting point. +if kitagawa_resampling + randvec = (transpose(1:number_of_particles)-1+noise(:))/number_of_particles ; +else + randvec = fliplr(cumprod(noise.^(1./(number_of_particles:-1:1)))); +end + +% Start at the bottom of the CDF +if kitagawa_resampling + j = 1; + for i=1:number_of_particles + while (randvec(i)>c(j)) + j = j+1; + end + indx(i) = j; + end +else + for i=1:number_of_particles + indx(i) = sum(randvec(i)>c); + end + % Matlab's indices start at 1... + indx = indx+1; +end + +if particles==0 + return_resample = indx ; +else + return_resample = particles(indx,:) ; +end + +%@test:1 +%$ % Define the weights +%$ weights = randn(2000,1).^2; +%$ weights = weights/sum(weights); +%$ % Initialize t. +%$ t = ones(2,1); +%$ +%$ % First, try the stratified resampling. +%$ try +%$ indx1 = traditional_resampling(weights,rand(2000,1)); +%$ catch +%$ t(1) = 0; +%$ end +%$ +%$ % Second, try the Kitagawa resampling. +%$ try +%$ indx2 = traditional_resampling(weights,rand); +%$ catch +%$ t(2) = 0; +%$ end +%$ +%$ T = all(t); +%@eof:1 + +%@test:2 +%$ % Define the weights +%$ weights = exp(randn(2000,1)); +%$ weights = weights/sum(weights); +%$ % Initialize t. +%$ t = ones(2,1); +%$ +%$ % First, try the stratified resampling. +%$ try +%$ indx1 = traditional_resampling(weights,rand(2000,1)); +%$ catch +%$ t(1) = 0; +%$ end +%$ +%$ % Second, try the Kitagawa resampling. +%$ try +%$ indx2 = traditional_resampling(weights,rand); +%$ catch +%$ t(2) = 0; +%$ end +%$ +%$ T = all(t); +%@eof:2 + +%@test:3 +%$ % Set the number of particles. +%$ number_of_particles = 20000; +%$ +%$ show_plot = 0; +%$ show_time = 1; +%$ +%$ % Define the weights +%$ weights = randn(number_of_particles,1).^2; +%$ weights = weights/sum(weights); +%$ +%$ % Compute the empirical CDF +%$ c = cumsum(weights); +%$ +%$ % Stratified resampling. +%$ noise = rand(number_of_particles,1); +%$ +%$ if show_time +%$ disp('Stratified resampling timing:') +%$ tic +%$ end +%$ +%$ indx1 = traditional_resampling(weights,noise); +%$ +%$ if show_time +%$ toc +%$ tic +%$ end +%$ +%$ indx1_ = zeros(number_of_particles,1); +%$ randvec = (transpose(1:number_of_particles)-1+noise)/number_of_particles; +%$ for i=1:number_of_particles +%$ j = 1; +%$ while (randvec(i)>c(j)) +%$ j = j + 1; +%$ end +%$ indx1_(i) = j; +%$ end +%$ +%$ if show_time +%$ toc +%$ end +%$ +%$ % Kitagawa's resampling. +%$ noise = rand; +%$ +%$ if show_time +%$ disp('Kitagawa''s resampling timing:') +%$ tic +%$ end +%$ +%$ indx2 = traditional_resampling(weights,noise); +%$ +%$ if show_time +%$ toc +%$ tic +%$ end +%$ +%$ indx2_ = zeros(number_of_particles,1); +%$ randvec = (transpose(1:number_of_particles)-1+noise)/number_of_particles; +%$ j = 1; +%$ for i=1:number_of_particles +%$ while (randvec(i)>c(j)) +%$ j = j + 1; +%$ end +%$ indx2_(i) = j; +%$ end +%$ +%$ if show_time +%$ toc +%$ end +%$ +%$ % REMARK +%$ % Note that the alternative code used in this test is sensibly faster than the code proposed +%$ % in the routine for the resampling scheme à la Kitagawa... +%$ +%$ if show_plot +%$ plot(randvec,c,'-r'), hold on, plot([randvec(1),randvec(end)],[c(1),c(end)],'-k'), hold off, axis tight, box on +%$ end +%$ +%$ % Check results. +%$ t(1) = dassert(indx1,indx1_); +%$ t(2) = dassert(indx2,indx2_); +%$ T = all(t); +%@eof:3 \ No newline at end of file diff --git a/src/univariate_smooth_resampling.m b/src/univariate_smooth_resampling.m new file mode 100644 index 000000000..8238902a1 --- /dev/null +++ b/src/univariate_smooth_resampling.m @@ -0,0 +1,82 @@ +function new_particles = univariate_smooth_resampling(weights,particles,number_of_new_particles) +% Smooth Resampling of the particles. + +%@info: +%! @deftypefn {Function File} {@var{new_particles} =} univariate_smooth_resampling (@var{weights}, @var{number_of_new_particles}) +%! @anchor{particle/univariate_smooth_resampling} +%! @sp 1 +%! Smooth Resampling of the particles (univariate version). +%! @sp 2 +%! @strong{Inputs} +%! @sp 1 +%! @table @ @var +%! @item weights +%! n*1 vector of doubles, particles' weights. +%! @item particles +%! n*1 vector of doubles, particles. +%! @item number_of_new_particles +%! Integer scalar. +%! @end table +%! @sp 2 +%! @strong{Outputs} +%! @sp 1 +%! @table @ @var +%! @item indx +%! number_of_new_particles*1 vector of doubles, new particles. +%! @end table +%! @sp 2 +%! @strong{This function is called by:} +%! @sp 1 +%! @ref{particle/sequantial_importance_particle_filter} +%! @sp 2 +%! @strong{This function calls:} +%! @sp 2 +%! @end deftypefn +%@eod: + +% Copyright (C) 2012 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 . + +% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr +% stephane DOT adjemian AT univ DASH lemans DOT fr + +M = length(particles) ; +lambda_tilde = [ (.5*weights(1)) ; + (.5*(weights(1:M-1)+weights(2:M))) ; + (.5*weights(M)) ] ; +lambda_bar = cumsum(lambda_tilde) ; +u = rand(1,1) ; +new_particles = zeros(number_of_new_particles,1) ; +rj = 0 ; +i = 1 ; +j = 1 ; +while i<=number_of_new_particles + u_j = ( i-1 + u)/number_of_new_particles ; + while u_j>lambda_bar(j) + rj = j ; + j = j+1 ; + end + if rj==0 + new_particles(i) = particles(1) ; + elseif rj==M + new_particles(i) = particles(M) ; + else + u_star = (u_j - lambda_bar(rj))./lambda_tilde(rj+1) ; + new_particles(i) = (particles(rj+1) - particles(rj))*u_star + particles(rj) ; + end + i = i+1 ; +end \ No newline at end of file diff --git a/src/unscented_sigma_points.m b/src/unscented_sigma_points.m new file mode 100644 index 000000000..26fcc4b5c --- /dev/null +++ b/src/unscented_sigma_points.m @@ -0,0 +1,42 @@ +function [nodes,W_m,W_c] = unscented_sigma_points(n,DynareOptions) +% +% Computes nodes and weigths for a scaled unscented transform cubature +% INPUTS +% n [integer] scalar, number of variables. +% +% OUTPUTS +% nodes [double] nodes of the cubature +% weigths [double] associated weigths +% +% REFERENCES +% +% +% +% NOTES +% +% Copyright (C) 2009-2012 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 . + +lambda = (DynareOptions.particle.unscented.alpha^2)*(n+DynareOptions.particle.unscented.kappa) - n ; +nodes = [ zeros(n,1) ( sqrt(n+lambda).*([ eye(n) -eye(n)]) ) ]' ; +W_m = lambda/(n+lambda) ; +W_c = W_m + (1-DynareOptions.particle.unscented.alpha^2+DynareOptions.particle.unscented.beta) ; +temp = ones(2*n,1)/(2*(n+lambda)) ; +W_m = [W_m ; temp] ; +W_c = [W_c ; temp] ; + + From f7b5d53f5baf6cb525e73f64968d7bcebb1bba25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Telemachus=29?= Date: Wed, 12 Nov 2014 17:59:50 +0100 Subject: [PATCH 004/101] Removed notes.org from Git. --- notes.org | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 notes.org diff --git a/notes.org b/notes.org deleted file mode 100644 index 2caf58eed..000000000 --- a/notes.org +++ /dev/null @@ -1,3 +0,0 @@ -#+STARTUP: overview -#+STARTUP: hidestars -#+AUTHOR: Stéphane Adjemian From 0d11f56e06a74045c7bdc10d1610a6736788ea11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Telemachus=29?= Date: Wed, 12 Nov 2014 18:01:31 +0100 Subject: [PATCH 005/101] Do not version Org files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 310406d7e..568b8034b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *~ *.mat +*.org doc/build/* \ No newline at end of file From ddd006ffc365a0eca16ff06a7108c893191c5c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Telemachus=29?= Date: Thu, 13 Nov 2014 15:54:41 +0100 Subject: [PATCH 006/101] Removed local_state_space_iteration_2 routine. --- .../local_state_space_iteration_2.m | 275 ------------------ 1 file changed, 275 deletions(-) delete mode 100644 src/local_state_space_iteration/local_state_space_iteration_2.m diff --git a/src/local_state_space_iteration/local_state_space_iteration_2.m b/src/local_state_space_iteration/local_state_space_iteration_2.m deleted file mode 100644 index 0c6a52d07..000000000 --- a/src/local_state_space_iteration/local_state_space_iteration_2.m +++ /dev/null @@ -1,275 +0,0 @@ -function [y,y_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,a,b,c)%yhat_,ss) - -%@info: -%! @deftypefn {Function File} {@var{y}, @var{y_} =} local_state_equation_2 (@var{yhat},@var{epsilon}, @var{ghx}, @var{ghu}, @var{constant}, @var{ghxx}, @var{ghuu}, @var{ghxu}, @var{yhat_}, @var{ss}) -%! @anchor{particle/local_state_space_iteration_2} -%! @sp 1 -%! Given the states (y) and structural innovations (epsilon), this routine computes the level of selected endogenous variables when the -%! model is approximated by an order two taylor expansion around the deterministic steady state. Depending on the number of input/output -%! argument the pruning algorithm advocated by C. Sims is used or not (this version should not be used if the selected endogenous variables -%! are not the states of the model). -%! -%! @sp 2 -%! @strong{Inputs} -%! @sp 1 -%! @table @ @var -%! @item yhat -%! n*1 vector of doubles, initial condition, where n is the number of state variables. -%! @item epsilon -%! q*1 vector of doubles, structural innovations. -%! @item ghx -%! m*n matrix of doubles, restricted dr.ghx where we only consider the lines corresponding to a subset of endogenous variables. -%! @item ghu -%! m*q matrix of doubles, restricted dr.ghu where we only consider the lines corresponding to a subset of endogenous variables. -%! @item constant -%! m*1 vector of doubles, deterministic steady state plus second order correction for a subset of endogenous variables. -%! @item ghxx -%! m*n² matrix of doubles, restricted dr.ghxx where we only consider the lines corresponding to a subset of endogenous variables. -%! @item ghuu -%! m*q² matrix of doubles, restricted dr.ghuu where we only consider the lines corresponding to a subset of endogenous variables. -%! @item ghxu -%! m*(nq) matrix of doubles, subset of dr.ghxu where we only consider the lines corresponding to a subset of endogenous variables. -%! @item yhat_ -%! n*1 vector of doubles, spurious states for the pruning version. -%! @item ss -%! n*1 vector of doubles, steady state for the states. -%! @end table -%! @sp 2 -%! @strong{Outputs} -%! @sp 1 -%! @table @ @var -%! @item y -%! m*1 vector of doubles, selected endogenous variables. -%! @item y_ -%! m*1 vector of doubles, update of the latent variables needed for the pruning version (first order update). -%! @end table -%! @sp 2 -%! @strong{Remarks} -%! @sp 1 -%! [1] If the function has 10 input arguments then it must have 2 output arguments (pruning version). -%! @sp 1 -%! [2] If the function has 08 input arguments then it must have 1 output argument. -%! @sp 2 -%! @strong{This function is called by:} -%! @sp 2 -%! @strong{This function calls:} -%! -%! -%! @end deftypefn -%@eod: - -% Copyright (C) 2011-2012 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 . - -% AUTHOR(S) stephane DOT adjemian AT univ DASH lemans DOT fr -% frederic DOT karame AT univ DASH evry DOT fr - -if nargin==9 - pruning = 0; numthreads = a; - if nargout>1 - error('local_state_space_iteration_2:: Numbers of input and output argument are inconsistent!') - end -elseif nargin==11 - pruning = 1; numthreads = c; yhat_ = a; ss = b; - if nargout~=2 - error('local_state_space_iteration_2:: Numbers of input and output argument are inconsistent!') - end -else - error('local_state_space_iteration_2:: Wrong number of input arguments!') -end - -number_of_threads = numthreads; - -switch pruning - case 0 - for i =1:size(yhat,2) - y(:,i) = constant + ghx*yhat(:,i) + ghu*epsilon(:,i) ... - + A_times_B_kronecker_C(.5*ghxx,yhat(:,i),number_of_threads) ... - + A_times_B_kronecker_C(.5*ghuu,epsilon(:,i),number_of_threads) ... - + A_times_B_kronecker_C(ghxu,yhat(:,i),epsilon(:,i),number_of_threads); - end - case 1 - for i =1:size(yhat,2) - y(:,i) = constant + ghx*yhat(:,i) + ghu*epsilon(:,i) ... - + A_times_B_kronecker_C(.5*ghxx,yhat_(:,i),number_of_threads) ... - + A_times_B_kronecker_C(.5*ghuu,epsilon(:,i),number_of_threads) ... - + A_times_B_kronecker_C(ghxu,yhat_(:,i),epsilon(:,i),number_of_threads); - end - y_ = ghx*yhat_+ghu*epsilon; - y_ = bsxfun(@plus,y_,ss); -end - -%@test:1 -%$ n = 2; -%$ q = 3; -%$ -%$ yhat = zeros(n,1); -%$ epsilon = zeros(q,1); -%$ ghx = rand(n,n); -%$ ghu = rand(n,q); -%$ constant = ones(n,1); -%$ ghxx = rand(n,n*n); -%$ ghuu = rand(n,q*q); -%$ ghxu = rand(n,n*q); -%$ yhat_ = zeros(n,1); -%$ ss = ones(n,1); -%$ -%$ % Call the tested routine. -%$ for i=1:10 -%$ y1 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); -%$ [y2,y2_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); -%$ end -%$ -%$ % Check the results. -%$ t(1) = dassert(y1,ones(n,1)); -%$ t(2) = dassert(y2,ones(n,1)); -%$ t(3) = dassert(y2_,ones(n,1)); -%$ T = all(t); -%@eof:1 - -%@test:2 -%$ old_path = pwd; -%$ cd([fileparts(which('dynare')) '/../tests/']); -%$ dynare('dsge_base2'); -%$ load dsge_base2; -%$ cd(old_path); -%$ dr = oo_.dr; -%$ clear('oo_','options_','M_'); -%$ delete([fileparts(which('dynare')) '/../tests/dsge_base2.mat']); -%$ istates = dr.nstatic+(1:dr.npred); -%$ n = dr.npred; -%$ q = size(dr.ghu,2); -%$ yhat = zeros(n,1); -%$ epsilon = zeros(q,1); -%$ ghx = dr.ghx(istates,:); -%$ ghu = dr.ghu(istates,:); -%$ constant = dr.ys(istates,:)+dr.ghs2(istates,:); -%$ ghxx = dr.ghxx(istates,:); -%$ ghuu = dr.ghuu(istates,:); -%$ ghxu = dr.ghxu(istates,:); -%$ yhat_ = zeros(n,1); -%$ ss = dr.ys(istates,:); -%$ -%$ t = ones(2,1); -%$ -%$ % Call the tested routine. -%$ try -%$ y1 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); -%$ catch -%$ t(1) = 0; -%$ end -%$ try -%$ [y2,y2_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); -%$ catch -%$ t(2) = 0; -%$ end -%$ -%$ % Check the results. -%$ T = all(t); -%@eof:2 - -%@test:3 -%$ Bohrbug = 1; % A bug that manifests reliably under a possibly unknown but well-defined set of conditions. -%$ if ~Bohrbug -%$ n = 2; -%$ q = 3; -%$ -%$ yhat = .01*randn(n,1); -%$ epsilon = .001*randn(q,1); -%$ ghx = rand(n,n); -%$ ghu = rand(n,q); -%$ constant = ones(n,1); -%$ ghxx = rand(n,n*n); -%$ ghuu = rand(n,q*q); -%$ ghxu = rand(n,n*q); -%$ yhat_ = zeros(n,1); -%$ ss = ones(n,1); -%$ -%$ % Call the tested routine (mex version). -%$ y1a = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); -%$ [y2a,y2a_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); -%$ -%$ % Call the tested routine (matlab version) -%$ path_to_mex = fileparts(which(['qmc_sequence.' mexext])); -%$ where_am_i_coming_from = pwd; -%$ cd(path_to_mex); -%$ tar('local_state_space_iteration_2.tar',['local_state_space_iteration_2.' mexext]); -%$ cd(where_am_i_coming_from); -%$ dynare_config([],0); -%$ y1b = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); -%$ [y2b,y2b_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,ss,1); -%$ cd(path_to_mex); -%$ untar('local_state_space_iteration_2.tar'); -%$ delete('local_state_space_iteration_2.tar'); -%$ cd(where_am_i_coming_from); -%$ dynare_config([],0); -%$ % Check the results. -%$ t(1) = dassert(y1a,y1b); -%$ t(2) = dassert(y2a,y2b); -%$ t(3) = dassert(y2a_,y2b_); -%$ T = all(t); -%$ else -%$ t(1) = 1; -%$ T = all(t); -%$ end -%@eof:3 - - -%@test:4 -%$ % TIMING TEST (parallelization with openmp) -%$ old_path = pwd; -%$ cd([fileparts(which('dynare')) '/../tests/']); -%$ dynare('dsge_base2'); -%$ load dsge_base2; -%$ cd(old_path); -%$ dr = oo_.dr; -%$ clear('oo_','options_','M_'); -%$ delete([fileparts(which('dynare')) '/../tests/dsge_base2.mat']); -%$ istates = dr.nstatic+(1:dr.npred); -%$ n = dr.npred; -%$ q = size(dr.ghu,2); -%$ yhat = zeros(n,10000000); -%$ epsilon = zeros(q,10000000); -%$ ghx = dr.ghx(istates,:); -%$ ghu = dr.ghu(istates,:); -%$ constant = dr.ys(istates,:)+dr.ghs2(istates,:); -%$ ghxx = dr.ghxx(istates,:); -%$ ghuu = dr.ghuu(istates,:); -%$ ghxu = dr.ghxu(istates,:); -%$ yhat_ = zeros(n,10000000); -%$ ss = dr.ys(istates,:); -%$ -%$ t = NaN(4,1); -%$ tic, for i=1:10, y1 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,1); end -%$ t1 = toc; -%$ tic, for i=1:10, y2 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,2); end -%$ t2 = toc; -%$ t(1) = dassert(y1,y2,1e-15); clear('y1'); -%$ tic, for i=1:10, y3 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,3); end -%$ t3 = toc; -%$ t(2) = dassert(y2,y3,1e-15); clear('y2'); -%$ tic, for i=1:10, y4 = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,4); end -%$ t4 = toc; -%$ t(3) = dassert(y4,y3,1e-15); clear('y3','y4'); -%$ t(4) = (t1>t2) && (t2>t3) && (t3>t4); -%$ if ~t(4) -%$ disp('Timmings:') -%$ [t1, t2, t3, t4] -%$ end -%$ % Check the results. -%$ T = all(t); -%@eof:4 From bf9e0490aeb3cbf0bf48557a9e3605e8acd3ea1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 14 Nov 2014 17:12:45 +0100 Subject: [PATCH 007/101] Fixed definition of neff (resampling threshold). --- src/neff.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neff.m b/src/neff.m index 5251b9f17..9e02b679e 100644 --- a/src/neff.m +++ b/src/neff.m @@ -18,4 +18,4 @@ function n = neff(w) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -n = dot(w,w); +n = 1/dot(w,w); \ No newline at end of file From e55f3fd272888dc59d2ac5f44cbdb3b54c08b172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 14 Nov 2014 18:16:11 +0100 Subject: [PATCH 008/101] Adds a modification to work with order 1 too. --- src/solve_model_for_online_filter.m | 62 ++++++++++++++++------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index a9cefe407..0d8f191c1 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -134,7 +134,8 @@ trend_coeff = []; exit_flag = 1; % Set the number of observed variables -nvobs = DynareDataset.info.nvobs; +%nvobs = DynareDataset.info.nvobs; +nvobs = size(DynareDataset.data,1) ; %------------------------------------------------------------------------------ % 1. Get the structural parameters & define penalties @@ -240,15 +241,13 @@ Model.H = H; % Linearize the model around the deterministic sdteadystate and extract the matrices of the state equation (T and R). [T,R,SteadyState,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict'); -%if info(1) == 1 || info(1) == 2 || info(1) == 5 -% fval = objective_function_penalty_base+1; -% exit_flag = 0; -% return -%elseif info(1) == 3 || info(1) == 4 || info(1)==6 ||info(1) == 19 || info(1) == 20 || info(1) == 21 -% fval = objective_function_penalty_base+info(2); -% exit_flag = 0; -% return -%end +%disp(info) + +if info(1) ~= 0 + ReducedForm = 0 ; + exit_flag = 55; + return +end % Define a vector of indices for the observed variables. Is this really usefull?... BayesInfo.mf = BayesInfo.mf1; @@ -265,24 +264,24 @@ else end % Define the deterministic linear trend of the measurement equation. -if BayesInfo.with_trend - trend_coeff = zeros(DynareDataset.info.nvobs,1); - t = DynareOptions.trend_coeffs; - for i=1:length(t) - if ~isempty(t{i}) - trend_coeff(i) = evalin('base',t{i}); - end - end - trend = repmat(constant,1,DynareDataset.info.ntobs)+trend_coeff*[1:DynareDataset.info.ntobs]; -else - trend = repmat(constant,1,DynareDataset.info.ntobs); -end +%if BayesInfo.with_trend +% trend_coeff = zeros(DynareDataset.info.nvobs,1); +% t = DynareOptions.trend_coeffs; +% for i=1:length(t) +% if ~isempty(t{i}) +% trend_coeff(i) = evalin('base',t{i}); +% end +% end +% trend = repmat(constant,1,DynareDataset.info.ntobs)+trend_coeff*[1:DynareDataset.info.ntobs]; +%else +% trend = repmat(constant,1,DynareDataset.info.ntobs); +%end % Get needed informations for kalman filter routines. start = DynareOptions.presample+1; np = size(T,1); mf = BayesInfo.mf; -Y = transpose(DynareDataset.rawdata); +Y = transpose(DynareDataset.data); %------------------------------------------------------------------------------ % 3. Initial condition of the Kalman filter @@ -307,11 +306,18 @@ end ReducedForm.ghx = dr.ghx(restrict_variables_idx,:); ReducedForm.ghu = dr.ghu(restrict_variables_idx,:); -ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); -ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); -ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); ReducedForm.steadystate = dr.ys(dr.order_var(restrict_variables_idx)); -ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); +if DynareOptions.order>1 + ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); + ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); + ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); + ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); +else + ReducedForm.ghxx = zeros(size(restrict_variables_idx,1),size(dr.kstate,2)); + ReducedForm.ghuu = zeros(size(restrict_variables_idx,1),size(dr.ghu,2)); + ReducedForm.ghxu = zeros(size(restrict_variables_idx,1),size(dr.ghx,2)); + ReducedForm.constant = ReducedForm.steadystate ; +end ReducedForm.state_variables_steady_state = dr.ys(dr.order_var(state_variables_idx)); ReducedForm.Q = Q; ReducedForm.H = H; @@ -323,7 +329,7 @@ if observation_number==1 switch DynareOptions.particle.initialization case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. StateVectorMean = ReducedForm.constant(mf0); - StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',1e-12,1e-12,[],[],DynareOptions.debug); + StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',1e-12,1e-12); case 2% Initial state vector covariance is a monte-carlo based estimate of the ergodic variance (consistent with a k-order Taylor-approximation of the model). StateVectorMean = ReducedForm.constant(mf0); old_DynareOptionsperiods = DynareOptions.periods; From f187c3d41485820a2152f4c4de6c2198a34eab00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 12 Dec 2014 16:35:14 +0100 Subject: [PATCH 009/101] Rewrote doc header. --- src/sequential_importance_particle_filter.m | 47 ++------------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index eadaeba41..8099a2f6c 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -1,55 +1,17 @@ function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,DynareOptions) + % Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). -% Standard Sequential Monte Carlo approach with -% - the usual proposal (the state transition distribution) -% - options on resampling: none, adaptive or systematic -%@info: -%! @deftypefn {Function File} {@var{y}, @var{y_} =} sequential_importance_particle_filter (@var{ReducedForm},@var{Y}, @var{start}, @var{DynareOptions}) -%! @anchor{particle/sequential_importance_particle_filter} -%! @sp 1 -%! Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). -%! -%! @sp 2 -%! @strong{Inputs} -%! @sp 1 -%! @table @ @var -%! @item ReducedForm -%! Structure describing the state space model (built in @ref{non_linear_dsge_likelihood}). -%! @item Y -%! p*smpl matrix of doubles (p is the number of observed variables), the (detrended) data. -%! @item start -%! Integer scalar, likelihood evaluation starts at observation 'start'. -%! @item DynareOptions -%! Structure specifying Dynare's options. -%! @end table -%! @sp 2 -%! @strong{Outputs} -%! @sp 1 -%! @table @ @var -%! @item LIK -%! double scalar, value of (minus) the logged likelihood. -%! @item lik -%! smpl*1 vector of doubles, density of the observations at each period. -%! @end table -%! @sp 2 -%! @strong{This function is called by:} -%! @ref{non_linear_dsge_likelihood} -%! @sp 2 -%! @strong{This function calls:} -%! -%! @end deftypefn -%@eod: % Copyright (C) 2011-2013 Dynare Team % -% This file is part of Dynare. +% This file is part of Dynare (particles module). % % 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, +% Dynare particles module 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. @@ -57,9 +19,6 @@ function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,D % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr -% stephane DOT adjemian AT univ DASH lemans DOT fr - persistent init_flag persistent mf0 mf1 persistent number_of_particles number_of_state_variables From f82afdf8aa81729fffb23aaa0eb9ece7456054f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 12 Dec 2014 17:25:11 +0100 Subject: [PATCH 010/101] Replaced DynareOptions by ParticleOptions and ThreadsOptions. ParticleOptions is DynareOptions.particles ThreadsOptions is DynareOptions.threads --- src/resample.m | 12 ++++++------ src/sequential_importance_particle_filter.m | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/resample.m b/src/resample.m index a72894428..d49abf12e 100644 --- a/src/resample.m +++ b/src/resample.m @@ -1,4 +1,4 @@ -function resampled_particles = resample(particles,weights,DynareOptions) +function resampled_particles = resample(particles,weights,ParticleOptions) % Resamples particles. %@info: @@ -54,19 +54,19 @@ function resampled_particles = resample(particles,weights,DynareOptions) defaultmethod = 1; % For residual based method set this variable equal to 0. if defaultmethod - if DynareOptions.particle.resampling.method.kitagawa + if ParticleOptions.resampling.method.kitagawa resampled_particles = traditional_resampling(particles,weights,rand); - elseif DynareOptions.particle.resampling.method.stratified + elseif ParticleOptions.resampling.method.stratified resampled_particles = traditional_resampling(particles,weights,rand(size(weights))); - elseif DynareOptions.particle.resampling.method.smooth + elseif ParticleOptions.resampling.method.smooth resampled_particles = multivariate_smooth_resampling(particles,weights); else error('Unknow sampling method!') end else - if DynareOptions.particle.resampling.method.kitagawa + if ParticleOptions.resampling.method.kitagawa resampled_particles = residual_resampling(particles,weights,rand); - elseif DynareOptions.particle.resampling.method.stratified + elseif ParticleOptions.resampling.method.stratified resampled_particles = residual_resampling(particles,weights,rand(size(weights))); else error('Unknown sampling method!') diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 8099a2f6c..19241382c 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -1,4 +1,4 @@ -function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,DynareOptions) +function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) % Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). @@ -30,7 +30,7 @@ if isempty(start) end % Set flag for prunning -pruning = DynareOptions.particle.pruning; +pruning = ParticleOptions.pruning; % Get steady state and mean. steadystate = ReducedForm.steadystate; @@ -45,7 +45,7 @@ if isempty(init_flag) number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); - number_of_particles = DynareOptions.particle.number_of_particles; + number_of_particles = ParticleOptions.number_of_particles; init_flag = 1; end @@ -99,9 +99,9 @@ for t=1:sample_size epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end PredictedObservedMean = tmp(mf1,:)*transpose(weights); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); @@ -117,16 +117,16 @@ for t=1:sample_size wtilde = weights.*exp(lnw-dfac); lik(t) = log(sum(wtilde))+dfac; weights = wtilde/sum(wtilde); - if (DynareOptions.particle.resampling.status.generic && neff(weights) Date: Fri, 12 Dec 2014 18:09:04 +0100 Subject: [PATCH 011/101] Fixed headers. --- src/auxiliary_particle_filter.m | 29 +++++---------------- src/sequential_importance_particle_filter.m | 2 +- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index e869484fe..7fb7dce69 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -1,41 +1,24 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,DynareOptions) -% Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. -% -% INPUTS -% ReducedForm [structure] Matlab's structure describing the reduced form model. -% ReducedForm.measurement.H [double] (pp x pp) variance matrix of measurement errors. -% ReducedForm.state.Q [double] (qq x qq) variance matrix of state errors. -% ReducedForm.state.dr [structure] output of resol.m. -% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. -% start [integer] scalar, likelihood evaluation starts at 'start'. -% mf [integer] pp*1 vector of indices. -% number_of_particles [integer] scalar. -% -% OUTPUTS -% LIK [double] scalar, likelihood -% lik [double] vector, density of observations in each period. -% -% REFERENCES -% -% NOTES -% The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2011-2013 Dynare Team +% Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. + +% Copyright (C) 2011-2014 Dynare Team % -% This file is part of Dynare. +% This file is part of Dynare (particles module). % % 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, +% Dynare particles module is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . + persistent init_flag mf0 mf1 number_of_particles persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 19241382c..24b0798fe 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -2,7 +2,7 @@ function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,P % Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). -% Copyright (C) 2011-2013 Dynare Team +% Copyright (C) 2011-2014 Dynare Team % % This file is part of Dynare (particles module). % From f4a1f065efdca403e6285c4273c2300ba7461124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 12 Dec 2014 19:14:35 +0100 Subject: [PATCH 012/101] Replaced DynareOptions by ParticleOptions and ThreadsOptions. --- src/auxiliary_particle_filter.m | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 7fb7dce69..f9cbf948c 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -1,4 +1,4 @@ -function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,DynareOptions) +function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) % Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. @@ -28,7 +28,7 @@ if isempty(start) end % Set flag for prunning -pruning = DynareOptions.particle.pruning; +pruning = ParticleOptions.pruning; % Get steady state and mean. steadystate = ReducedForm.steadystate; @@ -43,7 +43,7 @@ if isempty(init_flag) number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); - number_of_particles = DynareOptions.particle.number_of_particles; + number_of_particles = ParticleOptions.number_of_particles; init_flag = 1; end @@ -90,9 +90,9 @@ for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); if pruning yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); @@ -106,16 +106,16 @@ for t=1:sample_size lik(t) = log(sum_tau_tilde) ; %+ .5*var_wtilde/(number_of_particles*(sum_tau_tilde*sum_tau_tilde)) ; tau_tilde = tau_tilde/sum_tau_tilde; if pruning - temp = resample([yhat' yhat_'],tau_tilde',DynareOptions); + temp = resample([yhat' yhat_'],tau_tilde',ParticleOptions); yhat = temp(:,1:number_of_state_variables)' ; yhat_ = temp(:,number_of_state_variables+1:2*number_of_state_variables)' ; else - yhat = resample(yhat',tau_tilde',DynareOptions)' ; + yhat = resample(yhat',tau_tilde',ParticleOptions)' ; end if pruning - [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); @@ -124,10 +124,10 @@ for t=1:sample_size wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning - [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); StateVectors_ = tmp_(mf0,:); else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end StateVectors = tmp(mf0,:); PredictedObservedMean = mean(tmp(mf1,:),2); From 80af764efc618d8bdebc4d7876882b1a99b85171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 12 Dec 2014 22:37:49 +0100 Subject: [PATCH 013/101] Replaced DynareOptions by ParticleOptions and ThreadsOptions. --- src/auxiliary_initialization.m | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index 784550000..5d4bde948 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -1,4 +1,4 @@ -function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,DynareOptions) +function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) % Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. % % INPUTS @@ -45,7 +45,7 @@ if isempty(start) end % Set flag for prunning -%pruning = DynareOptions.particle.pruning; +%pruning = ParticleOptions.pruning; % Get steady state and mean. %steadystate = ReducedForm.steadystate; @@ -58,7 +58,7 @@ if isempty(init_flag) mf1 = ReducedForm.mf1; number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); - number_of_particles = DynareOptions.particle.number_of_particles; + number_of_particles = ParticleOptions.number_of_particles; init_flag = 1; end @@ -102,9 +102,9 @@ StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_r yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); %if pruning % yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); -% [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); +% [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); %else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); %end PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); @@ -113,4 +113,4 @@ PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredi wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; tau_tilde = weights.*wtilde ; tau_tilde = tau_tilde/sum(tau_tilde); -initial_distribution = resample(StateVectors',tau_tilde',DynareOptions)' ; \ No newline at end of file +initial_distribution = resample(StateVectors',tau_tilde',ParticleOptions)' ; \ No newline at end of file From 7ad84f3f2ed42712a198c6dd9078bb2fb6f077bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 12 Dec 2014 22:38:59 +0100 Subject: [PATCH 014/101] Fixed header. --- src/auxiliary_initialization.m | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index 5d4bde948..7034882b7 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -1,41 +1,24 @@ function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) -% Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. -% -% INPUTS -% ReducedForm [structure] Matlab's structure describing the reduced form model. -% ReducedForm.measurement.H [double] (pp x pp) variance matrix of measurement errors. -% ReducedForm.state.Q [double] (qq x qq) variance matrix of state errors. -% ReducedForm.state.dr [structure] output of resol.m. -% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. -% start [integer] scalar, likelihood evaluation starts at 'start'. -% mf [integer] pp*1 vector of indices. -% number_of_particles [integer] scalar. -% -% OUTPUTS -% LIK [double] scalar, likelihood -% lik [double] vector, density of observations in each period. -% -% REFERENCES -% -% NOTES -% The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2013 Dynare Team +% Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. + +% Copyright (C) 2011-2014 Dynare Team % -% This file is part of Dynare. +% This file is part of Dynare (particles module). % % 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, +% Dynare particles module is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . + persistent init_flag mf0 mf1 number_of_particles persistent number_of_observed_variables number_of_structural_innovations From f66b6b6e8c55236ee7e44b6a77e1f85800fb5604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Mon, 15 Dec 2014 14:30:19 +0100 Subject: [PATCH 015/101] Replaced DynareOptions by ParticleOptions and ThreadsOptions. --- src/conditional_filter_proposal.m | 14 +++++++------- src/conditional_particle_filter.m | 10 +++++----- src/measurement_equations.m | 4 ++-- src/unscented_sigma_points.m | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index aa82a449a..0ef5aedab 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -1,4 +1,4 @@ -function [ProposalStateVector,Weights] = conditional_filter_proposal(ReducedForm,obs,StateVectors,SampleWeights,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions,normconst2) +function [ProposalStateVector,Weights] = conditional_filter_proposal(ReducedForm,obs,StateVectors,SampleWeights,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) % % Computes the proposal for each past particle using Gaussian approximations % for the state errors and the Kalman filter @@ -73,11 +73,11 @@ if isempty(init_flag2) init_flag2 = 1; end -if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo +if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo [nodes,weights] = spherical_radial_sigma_points(number_of_structural_innovations); weights_c = weights ; -elseif DynareOptions.particle.proposal_approximation.unscented - [nodes,weights,weights_c] = unscented_sigma_points(number_of_structural_innovations,DynareOptions); +elseif ParticleOptions.proposal_approximation.unscented + [nodes,weights,weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); else error('Estimation: This approximation for the proposal is not implemented or unknown!') end @@ -85,12 +85,12 @@ end epsilon = Q_lower_triangular_cholesky*(nodes') ; yhat = repmat(StateVectors-state_variables_steady_state,1,size(epsilon,2)) ; -tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); +tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); PredictedStateMean = tmp(mf0,:)*weights ; PredictedObservedMean = tmp(mf1,:)*weights; -if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo +if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo PredictedStateMean = sum(PredictedStateMean,2) ; PredictedObservedMean = sum(PredictedObservedMean,2) ; dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights) ; @@ -117,7 +117,7 @@ else end ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; -ypred = measurement_equations(ProposalStateVector,ReducedForm,DynareOptions) ; +ypred = measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions) ; foo = H_lower_triangular_cholesky \ (obs - ypred) ; likelihood = exp(-0.5*(foo)'*foo)/normconst2 + 1e-99 ; Weights = SampleWeights.*likelihood; diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 3f365f85c..4aef9f392 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -1,4 +1,4 @@ -function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,DynareOptions) +function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) % % Evaluates the likelihood of a non-linear model with a particle filter % - the proposal is built using the Kalman updating step for each particle. @@ -74,7 +74,7 @@ if isempty(init_flag) number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); init_flag = 1; - number_of_particles = DynareOptions.particle.number_of_particles ; + number_of_particles = ParticleOptions.number_of_particles ; end % Get covariance matrices @@ -108,14 +108,14 @@ SampleWeights = ones(1,number_of_particles)/number_of_particles ; for t=1:sample_size for i=1:number_of_particles [StateParticles(:,i),SampleWeights(i)] = ... - conditional_filter_proposal(ReducedForm,Y(:,t),StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions,normconst2) ; + conditional_filter_proposal(ReducedForm,Y(:,t),StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) ; end SumSampleWeights = sum(SampleWeights) ; lik(t) = log(SumSampleWeights) ; SampleWeights = SampleWeights./SumSampleWeights ; - if (DynareOptions.particle.resampling.status.generic && neff(SampleWeights). -lambda = (DynareOptions.particle.unscented.alpha^2)*(n+DynareOptions.particle.unscented.kappa) - n ; +lambda = (ParticleOptions.unscented.alpha^2)*(n+ParticleOptions.unscented.kappa) - n ; nodes = [ zeros(n,1) ( sqrt(n+lambda).*([ eye(n) -eye(n)]) ) ]' ; W_m = lambda/(n+lambda) ; -W_c = W_m + (1-DynareOptions.particle.unscented.alpha^2+DynareOptions.particle.unscented.beta) ; +W_c = W_m + (1-ParticleOptions.unscented.alpha^2+ParticleOptions.unscented.beta) ; temp = ones(2*n,1)/(2*(n+lambda)) ; W_m = [W_m ; temp] ; W_c = [W_c ; temp] ; From f512e394532045784ec92e719ad77fb2ebffae81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Mon, 15 Dec 2014 15:27:28 +0100 Subject: [PATCH 016/101] Replaced DynareOptions by ParticleOptions and ThreadsOptions. --- src/gaussian_densities.m | 4 ++-- src/gaussian_filter.m | 28 +++++++++++------------ src/gaussian_filter_bank.m | 12 +++++----- src/gaussian_mixture_densities.m | 5 ++--- src/gaussian_mixture_filter.m | 36 +++++++++++++++--------------- src/gaussian_mixture_filter_bank.m | 12 +++++----- src/index_resample.m | 10 ++++----- 7 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 3a770118d..ae3afb130 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -1,4 +1,4 @@ -function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,DynareOptions) +function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) % % Elements to calculate the importance sampling ratio % @@ -41,7 +41,7 @@ proposal = probability2(mut_t,sqr_Pss_t_t,particles) ; % prior density prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; % likelihood -yt_t_1_i = measurement_equations(particles,ReducedForm,DynareOptions) ; +yt_t_1_i = measurement_equations(particles,ReducedForm,ThreadsOptions) ; eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; yt_t_1 = sum(yt_t_1_i*weigths1,2) ; tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index da3840c74..7a000e7b5 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -1,4 +1,4 @@ -function [LIK,lik] = gaussian_filter(ReducedForm,Y,start,DynareOptions) +function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions) % Evaluates the likelihood of a non-linear model approximating the % predictive (prior) and filtered (posterior) densities for state variables % by gaussian distributions. @@ -67,25 +67,25 @@ if isempty(init_flag) sample_size = size(Y,2); number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); - number_of_particles = DynareOptions.particle.number_of_particles; + number_of_particles = ParticleOptions.number_of_particles; init_flag = 1; end % compute gaussian quadrature nodes and weights on states and shocks if isempty(nodes2) - if DynareOptions.particle.distribution_approximation.cubature + if ParticleOptions.distribution_approximation.cubature [nodes2,weights2] = spherical_radial_sigma_points(number_of_state_variables); weights_c2 = weights2; - elseif DynareOptions.particle.distribution_approximation.unscented - [nodes2,weights2,weights_c2] = unscented_sigma_points(number_of_state_variables,DynareOptions); + elseif ParticleOptions.distribution_approximation.unscented + [nodes2,weights2,weights_c2] = unscented_sigma_points(number_of_state_variables,ParticleOptions); else - if ~DynareOptions.particle.distribution_approximation.montecarlo + if ~ParticleOptions.distribution_approximation.montecarlo error('Estimation: This approximation for the proposal is not implemented or unknown!') end end end -if DynareOptions.particle.distribution_approximation.montecarlo +if ParticleOptions.distribution_approximation.montecarlo set_dynare_seed('default'); end @@ -117,16 +117,16 @@ ks = 0 ; for t=1:sample_size % build the proposal [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = ... - gaussian_filter_bank(ReducedForm,Y(:,t),StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions) ; + gaussian_filter_bank(ReducedForm,Y(:,t),StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions) ; %Estimate(:,t) = PredictedStateMean ; %V_Estimate(:,:,t) = PredictedStateVarianceSquareRoot ; - if DynareOptions.particle.distribution_approximation.cubature || DynareOptions.particle.distribution_approximation.unscented + if ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented StateParticles = bsxfun(@plus,StateVectorMean,StateVectorVarianceSquareRoot*nodes2') ; IncrementalWeights = ... gaussian_densities(Y(:,t),StateVectorMean,... StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - weights2,weights_c2,ReducedForm,DynareOptions) ; + weights2,weights_c2,ReducedForm,ThreadsOptions) ; SampleWeights = weights2.*IncrementalWeights ; SumSampleWeights = sum(SampleWeights) ; lik(t) = log(SumSampleWeights) ; @@ -137,7 +137,7 @@ for t=1:sample_size gaussian_densities(Y(:,t),StateVectorMean,... StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - 1/number_of_particles,1/number_of_particles,ReducedForm,DynareOptions) ; + 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; SampleWeights = SampleWeights.*IncrementalWeights ; SumSampleWeights = sum(SampleWeights) ; %VarSampleWeights = IncrementalWeights-SumSampleWeights ; @@ -145,13 +145,13 @@ for t=1:sample_size lik(t) = log(SumSampleWeights) ; %+ .5*VarSampleWeights/(number_of_particles*(SumSampleWeights*SumSampleWeights)) ; SampleWeights = SampleWeights./SumSampleWeights ; Neff = 1/sum(bsxfun(@power,SampleWeights,2)) ; - if (Neff<.5*sample_size && DynareOptions.particle.resampling.status.generic) || DynareOptions.particle.resampling.status.systematic + if (Neff<.5*sample_size && ParticleOptions.resampling.status.generic) || ParticleOptions.resampling.status.systematic ks = ks + 1 ; - StateParticles = resample(StateParticles',SampleWeights,DynareOptions)' ; + StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; StateVectorMean = mean(StateParticles,2) ; StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/(number_of_particles-1) - StateVectorMean*(StateVectorMean') )'; SampleWeights = 1/number_of_particles ; - elseif DynareOptions.particle.resampling.status.none + elseif ParticleOptions.resampling.status.none StateVectorMean = (sampleWeights*StateParticles)' ; temp = sqrt(SampleWeights').*StateParticles ; StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp'*temp - StateVectorMean*(StateVectorMean') )'; diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index 6094dbcf1..4f45f7e38 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -1,4 +1,4 @@ -function [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = gaussian_filter_bank(ReducedForm,obs,StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,DynareOptions) +function [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = gaussian_filter_bank(ReducedForm,obs,StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions) % % Computes the proposal with a gaussian approximation for importance % sampling @@ -71,11 +71,11 @@ if isempty(init_flag2) init_flag2 = 1; end -if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo +if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations) ; weights_c = weights ; -elseif DynareOptions.particle.proposal_approximation.unscented - [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables+number_of_structural_innovations,DynareOptions); +elseif ParticleOptions.proposal_approximation.unscented + [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables+number_of_structural_innovations,ParticleOptions); else error('Estimation: This approximation for the proposal is not implemented or unknown!') end @@ -87,11 +87,11 @@ sigma_points = bsxfun(@plus,xbar,sqr_Px*(nodes')); StateVectors = sigma_points(1:number_of_state_variables,:); epsilon = sigma_points(number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations,:); yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); -tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); +tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); PredictedStateMean = tmp(mf0,:)*weights ; PredictedObservedMean = tmp(mf1,:)*weights; -if DynareOptions.particle.proposal_approximation.cubature || DynareOptions.particle.proposal_approximation.montecarlo +if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo PredictedStateMean = sum(PredictedStateMean,2); PredictedObservedMean = sum(PredictedObservedMean,2); dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights); diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m index 9a5b28e05..06c3eec1e 100644 --- a/src/gaussian_mixture_densities.m +++ b/src/gaussian_mixture_densities.m @@ -1,7 +1,6 @@ function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,normconst,weigths1,weigths2,ReducedForm,DynareOptions) - + StateParticles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) % % Elements to calculate the importance sampling ratio % @@ -46,7 +45,7 @@ prior = prior' ; [ras,ras,proposal] = probability(StateMuPost,StateSqrtPPost,StateWeightsPost,StateParticles) ; proposal = proposal' ; % Compute the density of the current observation conditionally to each particle -yt_t_1_i = measurement_equations(StateParticles,ReducedForm,DynareOptions) ; +yt_t_1_i = measurement_equations(StateParticles,ReducedForm,ThreadsOptions) ; eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; yt_t_1 = sum(yt_t_1_i*weigths1,2) ; tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index 5c60a81fb..d319fece0 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -1,4 +1,4 @@ -function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,DynareOptions) +function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) % Evaluates the likelihood of a non-linear model approximating the state % variables distributions with gaussian mixtures. Gaussian Mixture allows reproducing % a wide variety of generalized distributions (when multimodal for instance). @@ -71,12 +71,12 @@ if isempty(init_flag) number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); - G = DynareOptions.particle.mixture_state_variables; % number of GM components in state - I = DynareOptions.particle.mixture_structural_shocks ; % number of GM components in structural noise - J = DynareOptions.particle.mixture_measurement_shocks ; % number of GM components in observation noise + G = ParticleOptions.mixture_state_variables; % number of GM components in state + I = ParticleOptions.mixture_structural_shocks ; % number of GM components in structural noise + J = ParticleOptions.mixture_measurement_shocks ; % number of GM components in observation noise Gprime = G*I ; Gsecond = G*I*J ; - number_of_particles = DynareOptions.particle.number_of_particles; + number_of_particles = ParticleOptions.number_of_particles; init_flag = 1; end @@ -84,19 +84,19 @@ SampleWeights = ones(Gsecond,1)/Gsecond ; % compute gaussian quadrature nodes and weights on states and shocks if isempty(nodes) - if DynareOptions.particle.distribution_approximation.cubature + if ParticleOptions.distribution_approximation.cubature [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables); weights_c = weights; - elseif DynareOptions.particle.distribution_approximation.unscented - [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables,DynareOptions); + elseif ParticleOptions.distribution_approximation.unscented + [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables,ParticleOptions); else - if ~DynareOptions.particle.distribution_approximation.montecarlo + if ~ParticleOptions.distribution_approximation.montecarlo error('Estimation: This approximation for the proposal is not implemented or unknown!') end end end -if DynareOptions.particle.distribution_approximation.montecarlo +if ParticleOptions.distribution_approximation.montecarlo set_dynare_seed('default'); SampleWeights = 1/number_of_particles ; end @@ -161,7 +161,7 @@ for t=1:sample_size gaussian_mixture_filter_bank(ReducedForm,Y(:,t),StateMu(:,g),StateSqrtP(:,:,g),StateWeights(1,g),... StructuralShocksMu(:,i),StructuralShocksSqrtP(:,:,i),StructuralShocksWeights(1,i),... ObservationShocksMu(:,j),ObservationShocksSqrtP(:,:,j),ObservationShocksWeights(1,j),... - H,H_lower_triangular_cholesky,const_lik,DynareOptions) ; + H,H_lower_triangular_cholesky,const_lik,ParticleOptions,ThreadsOptions) ; end end end @@ -170,12 +170,12 @@ for t=1:sample_size StateWeightsPrior = StateWeightsPrior/sum(StateWeightsPrior,2) ; StateWeightsPost = StateWeightsPost/sum(StateWeightsPost,2) ; - if DynareOptions.particle.distribution_approximation.cubature || DynareOptions.particle.distribution_approximation.unscented + if ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented for i=1:Gsecond StateParticles = bsxfun(@plus,StateMuPost(:,i),StateSqrtPPost(:,:,i)*nodes') ; IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,weights,weights_c,ReducedForm,DynareOptions) ; + StateParticles,H,const_lik,weights,weights_c,ReducedForm,ThreadsOptions) ; SampleWeights(i) = sum(StateWeightsPost(i)*weights.*IncrementalWeights) ; end SumSampleWeights = sum(SampleWeights) ; @@ -183,7 +183,7 @@ for t=1:sample_size SampleWeights = SampleWeights./SumSampleWeights ; [ras,SortedRandomIndx] = sort(rand(1,Gsecond)); SortedRandomIndx = SortedRandomIndx(1:G); - indx = index_resample(0,SampleWeights,DynareOptions) ; + indx = index_resample(0,SampleWeights,ParticleOptions) ; indx = indx(SortedRandomIndx) ; StateMu = StateMuPost(:,indx); StateSqrtP = StateSqrtPPost(:,:,indx); @@ -195,7 +195,7 @@ for t=1:sample_size IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... StateParticles,H,const_lik,1/number_of_particles,... - 1/number_of_particles,ReducedForm,DynareOptions) ; + 1/number_of_particles,ReducedForm,ThreadsOptions) ; % calculate importance weights of particles SampleWeights = SampleWeights.*IncrementalWeights ; SumSampleWeights = sum(SampleWeights,1) ; @@ -205,13 +205,13 @@ for t=1:sample_size %estimate(t,:,1) = SampleWeights*StateParticles' ; % Resampling if needed of required Neff = 1/sum(bsxfun(@power,SampleWeights,2)) ; - if (DynareOptions.particle.resampling.status.generic && Neff<.5*sample_size) || DynareOptions.particle.resampling.status.systematic + if (ParticleOptions.resampling.status.generic && Neff<.5*sample_size) || ParticleOptions.resampling.status.systematic ks = ks + 1 ; - StateParticles = resample(StateParticles',SampleWeights,DynareOptions)' ; + StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; StateVectorMean = mean(StateParticles,2) ; StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/number_of_particles - StateVectorMean*(StateVectorMean') )'; SampleWeights = 1/number_of_particles ; - elseif DynareOptions.particle.resampling.status.none + elseif ParticleOptions.resampling.status.none StateVectorMean = StateParticles*sampleWeights ; temp = sqrt(SampleWeights').*StateParticles ; StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp*temp' - StateVectorMean*(StateVectorMean') )'; diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index 3a3caa776..5bcf702cb 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -2,7 +2,7 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP gaussian_mixture_filter_bank(ReducedForm,obs,StateMu,StateSqrtP,StateWeights,... StructuralShocksMu,StructuralShocksSqrtP,StructuralShocksWeights,... ObservationShocksMu,ObservationShocksSqrtP,ObservationShocksWeights,... - H,H_lower_triangular_cholesky,normfactO,DynareOptions) + H,H_lower_triangular_cholesky,normfactO,ParticleOptions,ThreadsOptions) % % Computes the proposal with a gaussian approximation for importance % sampling @@ -79,11 +79,11 @@ end numb = number_of_state_variables+number_of_structural_innovations ; -if DynareOptions.particle.proposal_approximation.cubature +if ParticleOptions.proposal_approximation.cubature [nodes3,weights3] = spherical_radial_sigma_points(numb); weights_c3 = weights3; -elseif DynareOptions.particle.proposal_approximation.unscented - [nodes3,weights3,weights_c3] = unscented_sigma_points(numb,DynareOptions); +elseif ParticleOptions.proposal_approximation.unscented + [nodes3,weights3,weights_c3] = unscented_sigma_points(numb,ParticleOptions); else error('Estimation: This approximation for the proposal is not implemented or unknown!') end @@ -91,11 +91,11 @@ end epsilon = bsxfun(@plus,StructuralShocksSqrtP*nodes3(:,number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations)',StructuralShocksMu) ; StateVectors = bsxfun(@plus,StateSqrtP*nodes3(:,1:number_of_state_variables)',StateMu); yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); -tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); +tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); PredictedStateMean = tmp(mf0,:)*weights3; PredictedObservedMean = tmp(mf1,:)*weights3; -if DynareOptions.particle.proposal_approximation.cubature +if ParticleOptions.proposal_approximation.cubature PredictedStateMean = sum(PredictedStateMean,2); PredictedObservedMean = sum(PredictedObservedMean,2); dState = (bsxfun(@minus,tmp(mf0,:),PredictedStateMean)').*sqrt(weights3); diff --git a/src/index_resample.m b/src/index_resample.m index e91645605..da4d3377d 100644 --- a/src/index_resample.m +++ b/src/index_resample.m @@ -1,4 +1,4 @@ -function resampling_index = index_resample(particles,weights,DynareOptions) +function resampling_index = index_resample(particles,weights,ParticleOptions) % Resamples particles. %@info: @@ -54,17 +54,17 @@ function resampling_index = index_resample(particles,weights,DynareOptions) defaultmethod = 1; % For residual based method set this variable equal to 0. if defaultmethod - if DynareOptions.particle.resampling.method.kitagawa + if ParticleOptions.resampling.method.kitagawa resampling_index = traditional_resampling(particles,weights,rand); - elseif DynareOptions.particle.resampling.method.stratified + elseif ParticleOptions.resampling.method.stratified resampling_index = traditional_resampling(particles,weights,rand(size(weights))); else error('Unknow sampling method!') end else - if DynareOptions.particle.resampling.method.kitagawa + if ParticleOptions.resampling.method.kitagawa resampled_particles = residual_resampling(particles,weights,rand); - elseif DynareOptions.particle.resampling.method.stratified + elseif ParticleOptions.resampling.method.stratified resampled_particles = residual_resampling(particles,weights,rand(size(weights))); else error('Unknown sampling method!') From 7a418a60b8df35a98a5541bbfd32d2fdbe74a214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian?= Date: Thu, 18 Dec 2014 11:31:29 +0100 Subject: [PATCH 017/101] Update README.md Fixed typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21f08a958..73b04f7dc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # particless Dynare module This package, used in [Dynare](http://www.dynare.org), provides -nonlinear filtering algorithmss. The documentation is available in the +nonlinear filtering algorithms. The documentation is available in the [doc](https://github.com/DynareTeam/particles/tree/master/doc) -subfolder. \ No newline at end of file +subfolder. From 25abaf2f146db2afa04dc6f5208d6b5e26719040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Thu, 18 Dec 2014 14:29:00 +0100 Subject: [PATCH 018/101] modification of the auxiliary particle filter and of the resample routine that can return either the resampled particles or the resampling index depending on the input (particles = 0 or not) --- src/auxiliary_particle_filter.m | 35 ++++++++++++++++----------------- src/resample.m | 19 +++++++++++------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index f9cbf948c..cba5410aa 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -86,6 +86,18 @@ StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_r if pruning StateVectors_ = StateVectors; end + +epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); +yhat = zeros(2,number_of_particles) ; +if pruning + yhat_ = zeros(2,number_of_particles) ; + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + StateVectors_ = tmp_(mf0,:); +else + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +end +StateVectors = tmp(mf0,:) ; + for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); if pruning @@ -101,27 +113,14 @@ for t=1:sample_size wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; tau_tilde = weights.*wtilde ; sum_tau_tilde = sum(tau_tilde) ; - %var_wtilde = wtilde-sum_tau_tilde ; - %var_wtilde = var_wtilde'*var_wtilde/(number_of_particles-1) ; - lik(t) = log(sum_tau_tilde) ; %+ .5*var_wtilde/(number_of_particles*(sum_tau_tilde*sum_tau_tilde)) ; + lik(t) = log(sum_tau_tilde) ; tau_tilde = tau_tilde/sum_tau_tilde; + indx = resample(0,tau_tilde',ParticleOptions); if pruning - temp = resample([yhat' yhat_'],tau_tilde',ParticleOptions); - yhat = temp(:,1:number_of_state_variables)' ; - yhat_ = temp(:,number_of_state_variables+1:2*number_of_state_variables)' ; - else - yhat = resample(yhat',tau_tilde',ParticleOptions)' ; + yhat_ = yhat_(:,indx) ; end - if pruning - [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); - else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); - end - PredictedObservedMean = weights*(tmp(mf1,:)'); - PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); - dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean'); - PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' +H; - wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; + yhat = yhat(:,indx) ; + wtilde = wtilde(indx) ; epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); diff --git a/src/resample.m b/src/resample.m index d49abf12e..3fee0c355 100644 --- a/src/resample.m +++ b/src/resample.m @@ -1,5 +1,7 @@ -function resampled_particles = resample(particles,weights,ParticleOptions) +function resampled_output = resample(particles,weights,ParticleOptions) % Resamples particles. +% if particles = 0, returns the resampling index (except for smooth resampling) +% Otherwise, returns the resampled particles set. %@info: %! @deftypefn {Function File} {@var{indx} =} resample (@var{weights}, @var{method}) @@ -55,19 +57,22 @@ defaultmethod = 1; % For residual based method set this variable equal to 0. if defaultmethod if ParticleOptions.resampling.method.kitagawa - resampled_particles = traditional_resampling(particles,weights,rand); + resampled_output = traditional_resampling(particles,weights,rand); elseif ParticleOptions.resampling.method.stratified - resampled_particles = traditional_resampling(particles,weights,rand(size(weights))); + resampled_output = traditional_resampling(particles,weights,rand(size(weights))); elseif ParticleOptions.resampling.method.smooth - resampled_particles = multivariate_smooth_resampling(particles,weights); + if particles==0 + error('Particle = 0 is incompatible with this resampling method!') + end + resampled_output = multivariate_smooth_resampling(particles,weights); else - error('Unknow sampling method!') + error('Unknown sampling method!') end else if ParticleOptions.resampling.method.kitagawa - resampled_particles = residual_resampling(particles,weights,rand); + resampled_output = residual_resampling(particles,weights,rand); elseif ParticleOptions.resampling.method.stratified - resampled_particles = residual_resampling(particles,weights,rand(size(weights))); + resampled_output = residual_resampling(particles,weights,rand(size(weights))); else error('Unknown sampling method!') end From 3b04e5266798c71faad4430261fa764a46b7b46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 7 Jan 2015 11:26:30 +0100 Subject: [PATCH 019/101] correction of weights calculation in the auxiliary particle filter --- src/auxiliary_particle_filter.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index cba5410aa..cfd459fe8 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -120,7 +120,8 @@ for t=1:sample_size yhat_ = yhat_(:,indx) ; end yhat = yhat(:,indx) ; - wtilde = wtilde(indx) ; + %wtilde = wtilde(indx) ; + factor = weights(indx)./tau_tilde(indx) ; epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); @@ -134,7 +135,8 @@ for t=1:sample_size dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); PredictedObservedVariance = (dPredictedObservedMean*dPredictedObservedMean')/number_of_particles + H; lnw = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))); - wtilde = lnw./wtilde; + %wtilde = lnw./wtilde; + wtilde = lnw.*factor ; weights = wtilde/sum(wtilde); end From 473b2b8bb1f895a1448f76c1c9c3631e957361ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 7 Jan 2015 13:49:33 +0100 Subject: [PATCH 020/101] modification of the sufficient statistics in the auxiliary particle filter --- src/auxiliary_particle_filter.m | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index cfd459fe8..5ab2b8013 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -98,13 +98,21 @@ else end StateVectors = tmp(mf0,:) ; +%[nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; +[nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); +nodes = Q_lower_triangular_cholesky*nodes ; + for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); - if pruning - yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); - else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +% if pruning +% yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); +% [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); +% else +% tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +% end + tmp = 0 ; + for i=1:size(nodes) + tmp = tmp + nodes_weights*local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); From aad6c297fed8144f34dc47fce2eb7a0203962934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 7 Jan 2015 14:22:12 +0100 Subject: [PATCH 021/101] Reintroduction of pruning and of options to build the sufficient statistics in the auxiliary particle filter --- src/auxiliary_particle_filter.m | 35 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 5ab2b8013..92826137a 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -98,21 +98,32 @@ else end StateVectors = tmp(mf0,:) ; -%[nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; -[nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); +if ParticleOptions.proposal_approximation.cubature + [nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; + nodes_weights = ones(size(nodes,1),1)*nodes_weights ; +elseif ParticleOptions.proposal_approximation.unscented + [nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); +else + error('Estimation: This approximation for the proposal is not implemented or unknown!') +end nodes = Q_lower_triangular_cholesky*nodes ; for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); -% if pruning -% yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); -% [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); -% else -% tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); -% end - tmp = 0 ; - for i=1:size(nodes) - tmp = tmp + nodes_weights*local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + if pruning + yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); + tmp = 0 ; + tmp_ = 0 ; + for i=1:size(nodes) + [tmp1, tmp1_] = local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + tmp = tmp + nodes_weights(i)*tmp1 ; + tmp_ = tmp_ + nodes_weights(i)*tmp1_ ; + end + else + tmp = 0 ; + for i=1:size(nodes) + tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + end end PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); @@ -128,7 +139,6 @@ for t=1:sample_size yhat_ = yhat_(:,indx) ; end yhat = yhat(:,indx) ; - %wtilde = wtilde(indx) ; factor = weights(indx)./tau_tilde(indx) ; epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning @@ -143,7 +153,6 @@ for t=1:sample_size dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); PredictedObservedVariance = (dPredictedObservedMean*dPredictedObservedMean')/number_of_particles + H; lnw = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))); - %wtilde = lnw./wtilde; wtilde = lnw.*factor ; weights = wtilde/sum(wtilde); end From d974c77df92e974c1e1abb1e9ce226661a6ae2d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 7 Jan 2015 14:25:56 +0100 Subject: [PATCH 022/101] Remove de index_resample.m file used in the auxiliary particle filter and replaced by reample.m --- src/index_resample.m | 72 -------------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 src/index_resample.m diff --git a/src/index_resample.m b/src/index_resample.m deleted file mode 100644 index da4d3377d..000000000 --- a/src/index_resample.m +++ /dev/null @@ -1,72 +0,0 @@ -function resampling_index = index_resample(particles,weights,ParticleOptions) -% Resamples particles. - -%@info: -%! @deftypefn {Function File} {@var{indx} =} resample (@var{weights}, @var{method}) -%! @anchor{particle/resample} -%! @sp 1 -%! Resamples particles. -%! @sp 2 -%! @strong{Inputs} -%! @sp 1 -%! @table @ @var -%! @item weights -%! n*1 vector of doubles, particles' weights. -%! @item method -%! string equal to 'residual' or 'traditional'. -%! @end table -%! @sp 2 -%! @strong{Outputs} -%! @sp 1 -%! @table @ @var -%! @item indx -%! n*1 vector of intergers, indices. -%! @end table -%! @sp 2 -%! @strong{This function is called by:} -%! @sp 1 -%! @ref{particle/sequantial_importance_particle_filter} -%! @sp 2 -%! @strong{This function calls:} -%! @sp 1 -%! @ref{residual_resampling}, @ref{traditional_resampling} -%! @sp 2 -%! @end deftypefn -%@eod: - -% Copyright (C) 2013 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 . - -defaultmethod = 1; % For residual based method set this variable equal to 0. - -if defaultmethod - if ParticleOptions.resampling.method.kitagawa - resampling_index = traditional_resampling(particles,weights,rand); - elseif ParticleOptions.resampling.method.stratified - resampling_index = traditional_resampling(particles,weights,rand(size(weights))); - else - error('Unknow sampling method!') - end -else - if ParticleOptions.resampling.method.kitagawa - resampled_particles = residual_resampling(particles,weights,rand); - elseif ParticleOptions.resampling.method.stratified - resampled_particles = residual_resampling(particles,weights,rand(size(weights))); - else - error('Unknown sampling method!') - end -end \ No newline at end of file From 5880db75375b75adad449497f0fe298ac38099d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 14 Jan 2015 14:56:10 +0100 Subject: [PATCH 023/101] Fix bug on gaussian filter for the option distribution_approximation=montecarlo --- src/gaussian_filter.m | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index 7a000e7b5..4fa412835 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -118,8 +118,6 @@ for t=1:sample_size % build the proposal [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = ... gaussian_filter_bank(ReducedForm,Y(:,t),StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions) ; - %Estimate(:,t) = PredictedStateMean ; - %V_Estimate(:,:,t) = PredictedStateVarianceSquareRoot ; if ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented StateParticles = bsxfun(@plus,StateVectorMean,StateVectorVarianceSquareRoot*nodes2') ; IncrementalWeights = ... @@ -131,6 +129,9 @@ for t=1:sample_size SumSampleWeights = sum(SampleWeights) ; lik(t) = log(SumSampleWeights) ; SampleWeights = SampleWeights./SumSampleWeights ; + StateVectorMean = StateParticles*SampleWeights ; + temp = bsxfun(@minus,StateParticles,StateVectorMean) ; + StateVectorVarianceSquareRoot = reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; else % Monte-Carlo draws StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean) ; IncrementalWeights = ... @@ -138,23 +139,25 @@ for t=1:sample_size StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; - SampleWeights = SampleWeights.*IncrementalWeights ; + %SampleWeights = SampleWeights.*IncrementalWeights ; + SampleWeights = IncrementalWeights/number_of_particles ; SumSampleWeights = sum(SampleWeights) ; %VarSampleWeights = IncrementalWeights-SumSampleWeights ; %VarSampleWeights = VarSampleWeights*VarSampleWeights'/(number_of_particles-1) ; lik(t) = log(SumSampleWeights) ; %+ .5*VarSampleWeights/(number_of_particles*(SumSampleWeights*SumSampleWeights)) ; SampleWeights = SampleWeights./SumSampleWeights ; - Neff = 1/sum(bsxfun(@power,SampleWeights,2)) ; - if (Neff<.5*sample_size && ParticleOptions.resampling.status.generic) || ParticleOptions.resampling.status.systematic + Neff = neff(SampleWeights) ; + if (Neff<0.5*sample_size && ParticleOptions.resampling.status.generic) || ParticleOptions.resampling.status.systematic ks = ks + 1 ; StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; StateVectorMean = mean(StateParticles,2) ; StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/(number_of_particles-1) - StateVectorMean*(StateVectorMean') )'; SampleWeights = 1/number_of_particles ; elseif ParticleOptions.resampling.status.none - StateVectorMean = (sampleWeights*StateParticles)' ; - temp = sqrt(SampleWeights').*StateParticles ; - StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp'*temp - StateVectorMean*(StateVectorMean') )'; + StateVectorMean = StateParticles*SampleWeights ; + temp = bsxfun(@minus,StateParticles,StateVectorMean) ; + StateVectorVarianceSquareRoot = reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; + %disp(StateVectorVarianceSquareRoot) end end end From 2995562e68cbb79ece5c0311575cb5d60fe2a146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 14 Jan 2015 16:13:21 +0100 Subject: [PATCH 024/101] Delete resampling possibility in gaussian particle filter --- src/gaussian_filter.m | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index 4fa412835..f4f692654 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -146,19 +146,19 @@ for t=1:sample_size %VarSampleWeights = VarSampleWeights*VarSampleWeights'/(number_of_particles-1) ; lik(t) = log(SumSampleWeights) ; %+ .5*VarSampleWeights/(number_of_particles*(SumSampleWeights*SumSampleWeights)) ; SampleWeights = SampleWeights./SumSampleWeights ; - Neff = neff(SampleWeights) ; - if (Neff<0.5*sample_size && ParticleOptions.resampling.status.generic) || ParticleOptions.resampling.status.systematic - ks = ks + 1 ; - StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; - StateVectorMean = mean(StateParticles,2) ; - StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/(number_of_particles-1) - StateVectorMean*(StateVectorMean') )'; - SampleWeights = 1/number_of_particles ; - elseif ParticleOptions.resampling.status.none +% Neff = neff(SampleWeights) ; +% if (Neff<0.5*sample_size && ParticleOptions.resampling.status.generic) || ParticleOptions.resampling.status.systematic +% ks = ks + 1 ; +% StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; +% StateVectorMean = mean(StateParticles,2) ; +% StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/(number_of_particles-1) - StateVectorMean*(StateVectorMean') )'; +% SampleWeights = 1/number_of_particles ; +% elseif ParticleOptions.resampling.status.none StateVectorMean = StateParticles*SampleWeights ; temp = bsxfun(@minus,StateParticles,StateVectorMean) ; StateVectorVarianceSquareRoot = reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; %disp(StateVectorVarianceSquareRoot) - end +% end end end From 6e7090f1f5d921d1f0e54078fd07b70a87646708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 23 Jan 2015 10:05:16 +0100 Subject: [PATCH 025/101] factorize some codes across options. --- src/gaussian_mixture_filter.m | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index d319fece0..4b8e52491 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -3,7 +3,6 @@ function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,ParticleOptions % variables distributions with gaussian mixtures. Gaussian Mixture allows reproducing % a wide variety of generalized distributions (when multimodal for instance). % Each gaussian distribution is obtained whether -% - with a Smolyak quadrature à la Kronrod & Paterson (Heiss & Winschel 2010, Winschel & Kratzig 2010). % - with a radial-spherical cubature % - with scaled unscented sigma-points % A Sparse grid Kalman Filter is implemented on each component of the mixture, @@ -72,8 +71,8 @@ if isempty(init_flag) number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); G = ParticleOptions.mixture_state_variables; % number of GM components in state - I = ParticleOptions.mixture_structural_shocks ; % number of GM components in structural noise - J = ParticleOptions.mixture_measurement_shocks ; % number of GM components in observation noise + I = 1 ; %ParticleOptions.mixture_structural_shocks ; % number of GM components in structural noise + J = 1 ; %ParticleOptions.mixture_measurement_shocks ; % number of GM components in observation noise Gprime = G*I ; Gsecond = G*I*J ; number_of_particles = ParticleOptions.number_of_particles; @@ -116,8 +115,9 @@ Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; StateWeights = ones(1,G)/G ; StateMu = ReducedForm.StateVectorMean*ones(1,G) ; StateSqrtP = zeros(number_of_state_variables,number_of_state_variables,G) ; +temp = reduced_rank_cholesky(ReducedForm.StateVectorVariance)' ; for g=1:G - StateSqrtP(:,:,g) = reduced_rank_cholesky(ReducedForm.StateVectorVariance)' ; + StateSqrtP(:,:,g) = temp ; end StructuralShocksWeights = ones(1,I)/I ; @@ -197,25 +197,26 @@ for t=1:sample_size StateParticles,H,const_lik,1/number_of_particles,... 1/number_of_particles,ReducedForm,ThreadsOptions) ; % calculate importance weights of particles - SampleWeights = SampleWeights.*IncrementalWeights ; +% SampleWeights = SampleWeights.*IncrementalWeights ; + SampleWeights = IncrementalWeights/number_of_particles ; SumSampleWeights = sum(SampleWeights,1) ; SampleWeights = SampleWeights./SumSampleWeights ; lik(t) = log(SumSampleWeights) ; % First possible state point estimates %estimate(t,:,1) = SampleWeights*StateParticles' ; % Resampling if needed of required - Neff = 1/sum(bsxfun(@power,SampleWeights,2)) ; - if (ParticleOptions.resampling.status.generic && Neff<.5*sample_size) || ParticleOptions.resampling.status.systematic - ks = ks + 1 ; - StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; - StateVectorMean = mean(StateParticles,2) ; - StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/number_of_particles - StateVectorMean*(StateVectorMean') )'; - SampleWeights = 1/number_of_particles ; - elseif ParticleOptions.resampling.status.none - StateVectorMean = StateParticles*sampleWeights ; - temp = sqrt(SampleWeights').*StateParticles ; - StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp*temp' - StateVectorMean*(StateVectorMean') )'; - end +% Neff = neff(SampleWeights) ; +% if (ParticleOptions.resampling.status.generic && Neff<.5*sample_size) || ParticleOptions.resampling.status.systematic +% ks = ks + 1 ; +% StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; +% StateVectorMean = mean(StateParticles,2) ; +% StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/number_of_particles - StateVectorMean*(StateVectorMean') )'; +% SampleWeights = 1/number_of_particles ; +% elseif ParticleOptions.resampling.status.none +% StateVectorMean = StateParticles*sampleWeights ; +% temp = sqrt(SampleWeights').*StateParticles ; +% StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp*temp' - StateVectorMean*(StateVectorMean') )'; +% end % Use the information from particles to update the gaussian mixture on state variables [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(StateParticles,StateMu,StateSqrtP,StateWeights,0.001,10,1) ; %estimate(t,:,3) = StateWeights*StateMu' ; From ec4f2da2fd5604744d3b7ebe028cc7f57c1d8859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 23 Jan 2015 14:40:55 +0100 Subject: [PATCH 026/101] factorize some codes across options and modify the definition of mixtures. --- src/gaussian_filter.m | 64 ++++++++-------------------- src/gaussian_mixture_filter.m | 80 +++++++++++++++++------------------ 2 files changed, 57 insertions(+), 87 deletions(-) diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index f4f692654..5500ea8c1 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -3,28 +3,24 @@ function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, Thr % predictive (prior) and filtered (posterior) densities for state variables % by gaussian distributions. % Gaussian approximation is done by: -% - a Kronrod-Paterson gaussian quadrature with a limited number of nodes. -% Multidimensional quadrature is obtained by the Smolyak operator (ref: Winschel & Kratzig, 2010). -% - a spherical-radial cubature (ref: Arasaratnam & Haykin, 2008,2009). -% - a scaled unscented transform cubature (ref: ) +% - a spherical-radial cubature (ref: Arasaratnam & Haykin, 2009). +% - a scaled unscented transform cubature (ref: Julier & Uhlmann 1995) % - Monte-Carlo draws from a multivariate gaussian distribution. % First and second moments of prior and posterior state densities are computed % from the resulting nodes/particles and allows to generate new distributions at the % following observation. -% => The use of nodes is much faster than Monte-Carlo Gaussian particle and standard particles -% filters since it treats a lesser number of particles and there is no need +% Pros: The use of nodes is much faster than Monte-Carlo Gaussian particle and standard particles +% filters since it treats a lesser number of particles. Furthermore, in all cases, there is no need % of resampling. -% However, estimations may reveal biaised if the model is truly non-gaussian +% Cons: estimations may be biaised if the model is truly non-gaussian % since predictive and filtered densities are unimodal. % % INPUTS -% reduced_form_model [structure] Matlab's structure describing the reduced form model. -% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. -% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. -% reduced_form_model.state.dr [structure] output of resol.m. -% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. -% start [integer] scalar, likelihood evaluation starts at 'start'. -% smolyak_accuracy [integer] scalar. +% Reduced_Form [structure] Matlab's structure describing the reduced form model. +% Y [double] matrix of original observed variables. +% start [double] structural parameters. +% ParticleOptions [structure] Matlab's structure describing options concerning particle filtering. +% ThreadsOptions [structure] Matlab's structure. % % OUTPUTS % LIK [double] scalar, likelihood @@ -34,7 +30,7 @@ function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, Thr % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2013 Dynare Team +% Copyright (C) 2009-2015 Dynare Team % % This file is part of Dynare. % @@ -110,12 +106,7 @@ const_lik = (2*pi)^(number_of_observed_variables/2) ; lik = NaN(sample_size,1); LIK = NaN; -SampleWeights = 1/number_of_particles ; -ks = 0 ; -%Estimate = zeros(number_of_state_variables,sample_size) ; -%V_Estimate = zeros(number_of_state_variables,number_of_state_variables,sample_size) ; for t=1:sample_size - % build the proposal [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = ... gaussian_filter_bank(ReducedForm,Y(:,t),StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions) ; if ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented @@ -126,40 +117,21 @@ for t=1:sample_size PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... weights2,weights_c2,ReducedForm,ThreadsOptions) ; SampleWeights = weights2.*IncrementalWeights ; - SumSampleWeights = sum(SampleWeights) ; - lik(t) = log(SumSampleWeights) ; - SampleWeights = SampleWeights./SumSampleWeights ; - StateVectorMean = StateParticles*SampleWeights ; - temp = bsxfun(@minus,StateParticles,StateVectorMean) ; - StateVectorVarianceSquareRoot = reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; - else % Monte-Carlo draws + else StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean) ; IncrementalWeights = ... gaussian_densities(Y(:,t),StateVectorMean,... StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; - %SampleWeights = SampleWeights.*IncrementalWeights ; SampleWeights = IncrementalWeights/number_of_particles ; - SumSampleWeights = sum(SampleWeights) ; - %VarSampleWeights = IncrementalWeights-SumSampleWeights ; - %VarSampleWeights = VarSampleWeights*VarSampleWeights'/(number_of_particles-1) ; - lik(t) = log(SumSampleWeights) ; %+ .5*VarSampleWeights/(number_of_particles*(SumSampleWeights*SumSampleWeights)) ; - SampleWeights = SampleWeights./SumSampleWeights ; -% Neff = neff(SampleWeights) ; -% if (Neff<0.5*sample_size && ParticleOptions.resampling.status.generic) || ParticleOptions.resampling.status.systematic -% ks = ks + 1 ; -% StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; -% StateVectorMean = mean(StateParticles,2) ; -% StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/(number_of_particles-1) - StateVectorMean*(StateVectorMean') )'; -% SampleWeights = 1/number_of_particles ; -% elseif ParticleOptions.resampling.status.none - StateVectorMean = StateParticles*SampleWeights ; - temp = bsxfun(@minus,StateParticles,StateVectorMean) ; - StateVectorVarianceSquareRoot = reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; - %disp(StateVectorVarianceSquareRoot) -% end end + SumSampleWeights = sum(SampleWeights) ; + lik(t) = log(SumSampleWeights) ; + SampleWeights = SampleWeights./SumSampleWeights ; + StateVectorMean = StateParticles*SampleWeights ; + temp = bsxfun(@minus,StateParticles,StateVectorMean) ; + StateVectorVarianceSquareRoot = reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; end LIK = -sum(lik(start:end)); diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index 4b8e52491..f2aeebdf5 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -52,8 +52,7 @@ function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,ParticleOptions % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . - -persistent init_flag mf0 mf1 Gprime Gsecond +persistent init_flag mf0 mf1 persistent nodes weights weights_c I J G number_of_particles persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations @@ -71,16 +70,10 @@ if isempty(init_flag) number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); G = ParticleOptions.mixture_state_variables; % number of GM components in state - I = 1 ; %ParticleOptions.mixture_structural_shocks ; % number of GM components in structural noise - J = 1 ; %ParticleOptions.mixture_measurement_shocks ; % number of GM components in observation noise - Gprime = G*I ; - Gsecond = G*I*J ; number_of_particles = ParticleOptions.number_of_particles; init_flag = 1; end -SampleWeights = ones(Gsecond,1)/Gsecond ; - % compute gaussian quadrature nodes and weights on states and shocks if isempty(nodes) if ParticleOptions.distribution_approximation.cubature @@ -111,29 +104,54 @@ else end Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; -% Initialize all matrices +% Initialize mixtures StateWeights = ones(1,G)/G ; -StateMu = ReducedForm.StateVectorMean*ones(1,G) ; +StateMu = ReducedForm.StateVectorMean ; StateSqrtP = zeros(number_of_state_variables,number_of_state_variables,G) ; temp = reduced_rank_cholesky(ReducedForm.StateVectorVariance)' ; +StateMu = bsxfun(@plus,StateMu,bsxfun(@times,diag(temp),(-(G-1)/2:1:(G-1)/2))/10) ; for g=1:G StateSqrtP(:,:,g) = temp ; end -StructuralShocksWeights = ones(1,I)/I ; -StructuralShocksMu = zeros(number_of_structural_innovations,I) ; +if ParticleOptions.proposal_approximation.cubature + [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); + StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; +elseif ParticleOptions.proposal_approximation.unscented + [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); +else + if ~ParticleOptions.distribution_approximation.montecarlo + error('Estimation: This approximation for the proposal is not implemented or unknown!') + end +end +I = size(StructuralShocksWeights,1) ; +StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; for i=1:I StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky ; end -ObservationShocksWeights = ones(1,J)/J ; -ObservationShocksMu = zeros(number_of_observed_variables,J) ; +if ParticleOptions.proposal_approximation.cubature + [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); + ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; +elseif ParticleOptions.proposal_approximation.unscented + [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); +else + if ~ParticleOptions.distribution_approximation.montecarlo + error('Estimation: This approximation for the proposal is not implemented or unknown!') + end +end +J = size(ObservationShocksWeights,1) ; +ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; for j=1:J ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky ; end +Gprime = G*I ; +Gsecond = G*I*J ; +SampleWeights = ones(Gsecond,1)/Gsecond ; + StateWeightsPrior = zeros(1,Gprime) ; StateMuPrior = zeros(number_of_state_variables,Gprime) ; StateSqrtPPrior = zeros(number_of_state_variables,number_of_state_variables,Gprime) ; @@ -142,10 +160,8 @@ StateWeightsPost = zeros(1,Gsecond) ; StateMuPost = zeros(number_of_state_variables,Gsecond) ; StateSqrtPPost = zeros(number_of_state_variables,number_of_state_variables,Gsecond) ; -%estimate = zeros(sample_size,number_of_state_variables,3) ; const_lik = (2*pi)^(.5*number_of_observed_variables) ; -ks = 0 ; lik = NaN(sample_size,1); LIK = NaN; for t=1:sample_size @@ -154,13 +170,13 @@ for t=1:sample_size for i=1:I for j=1:J for g=1:G ; - a = g + (j-1)*G ; - b = a + (i-1)*Gprime ; - [StateMuPrior(:,a),StateSqrtPPrior(:,:,a),StateWeightsPrior(1,a),... - StateMuPost(:,b),StateSqrtPPost(:,:,b),StateWeightsPost(1,b)] =... - gaussian_mixture_filter_bank(ReducedForm,Y(:,t),StateMu(:,g),StateSqrtP(:,:,g),StateWeights(1,g),... - StructuralShocksMu(:,i),StructuralShocksSqrtP(:,:,i),StructuralShocksWeights(1,i),... - ObservationShocksMu(:,j),ObservationShocksSqrtP(:,:,j),ObservationShocksWeights(1,j),... + gprime = g + (i-1)*G ; + gsecond = gprime + (j-1)*Gprime ; + [StateMuPrior(:,gprime),StateSqrtPPrior(:,:,gprime),StateWeightsPrior(1,gprime),... + StateMuPost(:,gsecond),StateSqrtPPost(:,:,gsecond),StateWeightsPost(1,gsecond)] =... + gaussian_mixture_filter_bank(ReducedForm,Y(:,t),StateMu(:,g),StateSqrtP(:,:,g),StateWeights(g),... + StructuralShocksMu(:,i),StructuralShocksSqrtP(:,:,i),StructuralShocksWeights(i),... + ObservationShocksMu(:,j),ObservationShocksSqrtP(:,:,j),ObservationShocksWeights(j),... H,H_lower_triangular_cholesky,const_lik,ParticleOptions,ThreadsOptions) ; end end @@ -197,29 +213,11 @@ for t=1:sample_size StateParticles,H,const_lik,1/number_of_particles,... 1/number_of_particles,ReducedForm,ThreadsOptions) ; % calculate importance weights of particles -% SampleWeights = SampleWeights.*IncrementalWeights ; SampleWeights = IncrementalWeights/number_of_particles ; SumSampleWeights = sum(SampleWeights,1) ; SampleWeights = SampleWeights./SumSampleWeights ; lik(t) = log(SumSampleWeights) ; - % First possible state point estimates - %estimate(t,:,1) = SampleWeights*StateParticles' ; - % Resampling if needed of required -% Neff = neff(SampleWeights) ; -% if (ParticleOptions.resampling.status.generic && Neff<.5*sample_size) || ParticleOptions.resampling.status.systematic -% ks = ks + 1 ; -% StateParticles = resample(StateParticles',SampleWeights,ParticleOptions)' ; -% StateVectorMean = mean(StateParticles,2) ; -% StateVectorVarianceSquareRoot = reduced_rank_cholesky( (StateParticles*StateParticles')/number_of_particles - StateVectorMean*(StateVectorMean') )'; -% SampleWeights = 1/number_of_particles ; -% elseif ParticleOptions.resampling.status.none -% StateVectorMean = StateParticles*sampleWeights ; -% temp = sqrt(SampleWeights').*StateParticles ; -% StateVectorVarianceSquareRoot = reduced_rank_cholesky( temp*temp' - StateVectorMean*(StateVectorMean') )'; -% end - % Use the information from particles to update the gaussian mixture on state variables [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(StateParticles,StateMu,StateSqrtP,StateWeights,0.001,10,1) ; - %estimate(t,:,3) = StateWeights*StateMu' ; end end From 5cd887b048884270ad3ba58ec2eaf7a2db51dbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 28 Jan 2015 15:23:09 +0100 Subject: [PATCH 027/101] fix a bug in the indices of the proposal calculations. --- src/gaussian_mixture_filter.m | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index f2aeebdf5..803211bc9 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -111,7 +111,7 @@ StateSqrtP = zeros(number_of_state_variables,number_of_state_variables,G) ; temp = reduced_rank_cholesky(ReducedForm.StateVectorVariance)' ; StateMu = bsxfun(@plus,StateMu,bsxfun(@times,diag(temp),(-(G-1)/2:1:(G-1)/2))/10) ; for g=1:G - StateSqrtP(:,:,g) = temp ; + StateSqrtP(:,:,g) = temp/sqrt(G) ; end if ParticleOptions.proposal_approximation.cubature @@ -128,7 +128,7 @@ I = size(StructuralShocksWeights,1) ; StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; for i=1:I - StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky ; + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; end if ParticleOptions.proposal_approximation.cubature @@ -145,7 +145,7 @@ J = size(ObservationShocksWeights,1) ; ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; for j=1:J - ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky ; + ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky/sqrt(ObservationShocksWeights(j)) ; end Gprime = G*I ; @@ -199,7 +199,7 @@ for t=1:sample_size SampleWeights = SampleWeights./SumSampleWeights ; [ras,SortedRandomIndx] = sort(rand(1,Gsecond)); SortedRandomIndx = SortedRandomIndx(1:G); - indx = index_resample(0,SampleWeights,ParticleOptions) ; + indx = resample(0,SampleWeights,ParticleOptions) ; indx = indx(SortedRandomIndx) ; StateMu = StateMuPost(:,indx); StateSqrtP = StateSqrtPPost(:,:,indx); @@ -207,12 +207,10 @@ for t=1:sample_size else % Sample particle in the proposal distribution, ie the posterior state GM StateParticles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost',number_of_particles) ; - % Compute prior, proposal and likelihood of particles IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... StateParticles,H,const_lik,1/number_of_particles,... 1/number_of_particles,ReducedForm,ThreadsOptions) ; - % calculate importance weights of particles SampleWeights = IncrementalWeights/number_of_particles ; SumSampleWeights = sum(SampleWeights,1) ; SampleWeights = SampleWeights./SumSampleWeights ; From ef042694864bf7a60c3704152d5c45c82b4044be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 15 Apr 2015 10:40:27 +0200 Subject: [PATCH 028/101] adapt the code to dynare evolutions --- src/online_auxiliary_filter.m | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 4a8243a2d..3e0b146ac 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -1,4 +1,4 @@ -function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) +function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,bounds,DynareResults) % Carvalho & Lopes particle filter = auxiliary particle filter including Liu & West filter on parameters. % @@ -37,7 +37,7 @@ function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(x % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -persistent Y init_flag mf0 mf1 bounds number_of_particles number_of_parameters liu_west_delta liu_west_chol_sigma_bar +persistent Y init_flag mf0 mf1 number_of_particles number_of_parameters liu_west_delta liu_west_chol_sigma_bar persistent start_param sample_size number_of_observed_variables number_of_structural_innovations % Set seed for randn(). @@ -57,15 +57,11 @@ if isempty(init_flag) number_of_particles = DynareOptions.particle.number_of_particles; number_of_parameters = size(xparam1,1) ; Y = DynareDataset.data ; - sample_size = size(Y,2); + sample_size = size(Y,1); number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); liu_west_delta = DynareOptions.particle.liu_west_delta ; - %liu_west_chol_sigma_bar = DynareOptions.particle.liu_west_chol_sigma_bar*eye(number_of_parameters) ; start_param = xparam1 ; - %liu_west_chol_sigma_bar = sqrt(bsxfun(@times,eye(number_of_parameters),BayesInfo.p2)) ; - %start_param = BayesInfo.p1 ; - bounds = [BayesInfo.lb BayesInfo.ub] ; init_flag = 1; end @@ -85,13 +81,14 @@ small_a = sqrt(1-h_square) ; % Initialization of parameter particles xparam = zeros(number_of_parameters,number_of_particles) ; -stderr = sqrt(bsxfun(@power,bounds(:,2)+bounds(:,1),2)/12)/100 ; -stderr = sqrt(bsxfun(@power,bounds(:,2)+bounds(:,1),2)/12)/50 ; +stderr = sqrt(bsxfun(@power,bounds.ub+bounds.lb,2)/12)/100 ; +stderr = sqrt(bsxfun(@power,bounds.ub+bounds.lb,2)/12)/50 ; +stderr = sqrt(bsxfun(@power,bounds.ub+bounds.lb,2)/12)/20 ; i = 1 ; while i<=number_of_particles %candidate = start_param + .001*liu_west_chol_sigma_bar*randn(number_of_parameters,1) ; candidate = start_param + bsxfun(@times,stderr,randn(number_of_parameters,1)) ; - if all(candidate(:) >= bounds(:,1)) && all(candidate(:) <= bounds(:,2)) + if all(candidate(:) >= bounds.lb) && all(candidate(:) <= bounds.ub) xparam(:,i) = candidate(:) ; i = i+1 ; end @@ -146,7 +143,7 @@ for t=1:sample_size ObservedVariables(:,i) = tmp(mf1,:) ; end PredictedObservedMean = sum(bsxfun(@times,weights,ObservedVariables),2) ; - PredictionError = bsxfun(@minus,Y(:,t),ObservedVariables); + PredictionError = bsxfun(@minus,Y(t,:)',ObservedVariables); dPredictedObservedMean = bsxfun(@minus,ObservedVariables,PredictedObservedMean); PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' + ReducedForm.H ; wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; @@ -155,7 +152,7 @@ for t=1:sample_size sum_tau_tilde = sum(tau_tilde) ; % particles selection tau_tilde = tau_tilde/sum_tau_tilde ; - indx = index_resample(0,tau_tilde',DynareOptions); + indx = resample(0,tau_tilde',DynareOptions.particle); StateVectors = StateVectors(:,indx) ; if pruning StateVectors_ = StateVectors_(:,indx) ; @@ -167,7 +164,7 @@ for t=1:sample_size i = 1 ; while i<=number_of_particles candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters,1) ; - if all(candidate >= bounds(:,1)) && all(candidate <= bounds(:,2)) + if all(candidate >= bounds.lb) && all(candidate <= bounds.ub) xparam(:,i) = candidate ; % model resolution for new parameters particles [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... @@ -198,7 +195,7 @@ for t=1:sample_size end end PredictedObservedMean = sum(bsxfun(@times,weights,ObservedVariables),2) ; - PredictionError = bsxfun(@minus,Y(:,t),ObservedVariables); + PredictionError = bsxfun(@minus,Y(t,:)',ObservedVariables); dPredictedObservedMean = bsxfun(@minus,ObservedVariables,PredictedObservedMean); PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' + ReducedForm.H ; lnw = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))); @@ -211,7 +208,7 @@ for t=1:sample_size end % final resampling (advised) if second_resample==1 - indx = index_resample(0,weights,DynareOptions); + indx = resample(0,weights,DynareOptions.particle); StateVectors = StateVectors(:,indx) ; if pruning StateVectors_ = StateVectors_(:,indx) ; From c89801b2dfdf1c19b4acf69d0c21d5f7a489e723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 27 May 2015 11:48:06 +0200 Subject: [PATCH 029/101] simplification of gaussian mixtures --- src/gaussian_mixture_filter.m | 159 ++++++++++++++++++++++++++++------ 1 file changed, 131 insertions(+), 28 deletions(-) diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index 803211bc9..77577d04c 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -114,39 +114,142 @@ for g=1:G StateSqrtP(:,:,g) = temp/sqrt(G) ; end -if ParticleOptions.proposal_approximation.cubature - [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); - StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; -elseif ParticleOptions.proposal_approximation.unscented - [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); -else - if ~ParticleOptions.distribution_approximation.montecarlo - error('Estimation: This approximation for the proposal is not implemented or unknown!') +% if ParticleOptions.mixture_structural_shocks==1 +% StructuralShocksMu = zeros(1,number_of_structural_innovations) ; +% StructuralShocksWeights = 1 ; +% else +% if ParticleOptions.proposal_approximation.cubature +% [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); +% StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; +% elseif ParticleOptions.proposal_approximation.unscented +% [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); +% else +% if ~ParticleOptions.distribution_approximation.montecarlo +% error('Estimation: This approximation for the proposal is not implemented or unknown!') +% end +% end +% end +% I = size(StructuralShocksWeights,1) ; +% StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; +% StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; +% for i=1:I +% StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; +% end +% +% if ParticleOptions.mixture_measurement_shocks==1 +% ObservationShocksMu = zeros(1,number_of_observed_variables) ; +% ObservationShocksWeights = 1 ; +% else +% if ParticleOptions.proposal_approximation.cubature +% [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); +% ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; +% elseif ParticleOptions.proposal_approximation.unscented +% [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); +% else +% if ~ParticleOptions.distribution_approximation.montecarlo +% error('Estimation: This approximation for the proposal is not implemented or unknown!') +% end +% end +% end +% J = size(ObservationShocksWeights,1) ; +% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; +% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; +% for j=1:J +% ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky/sqrt(ObservationShocksWeights(j)) ; +% end + +if ParticleOptions.mixture_structural_shocks==0 + StructuralShocksMu = zeros(1,number_of_structural_innovations) ; + StructuralShocksWeights = 1 ; + I = 1 ; + StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; + StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; + StructuralShocksSqrtP(:,:,1) = Q_lower_triangular_cholesky ; +elseif ParticleOptions.mixture_structural_shocks==1 + if ParticleOptions.proposal_approximation.cubature + [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); + StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; + elseif ParticleOptions.proposal_approximation.unscented + [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); + else + if ~ParticleOptions.distribution_approximation.montecarlo + error('Estimation: This approximation for the proposal is not implemented or unknown!') + end + end + I = size(StructuralShocksWeights,1) ; + StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; + StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; + for i=1:I + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky ; + end +else + if ParticleOptions.proposal_approximation.cubature + [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); + StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; + elseif ParticleOptions.proposal_approximation.unscented + [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); + else + if ~ParticleOptions.distribution_approximation.montecarlo + error('Estimation: This approximation for the proposal is not implemented or unknown!') + end + end + I = size(StructuralShocksWeights,1) ; + StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; + StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; + for i=1:I + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; end -end -I = size(StructuralShocksWeights,1) ; -StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; -StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; -for i=1:I - StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; end -if ParticleOptions.proposal_approximation.cubature - [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); - ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; -elseif ParticleOptions.proposal_approximation.unscented - [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); -else - if ~ParticleOptions.distribution_approximation.montecarlo - error('Estimation: This approximation for the proposal is not implemented or unknown!') - end -end -J = size(ObservationShocksWeights,1) ; +ObservationShocksMu = zeros(1,number_of_observed_variables) ; +ObservationShocksWeights = 1 ; +J = 1 ; ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; -for j=1:J - ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky/sqrt(ObservationShocksWeights(j)) ; -end +ObservationShocksSqrtP(:,:,1) = H_lower_triangular_cholesky ; + +% if ParticleOptions.mixture_measurement_shocks==0 +% ObservationShocksMu = zeros(1,number_of_observed_variables) ; +% ObservationShocksWeights = 1 ; +% J = 1 ; +% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; +% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; +% ObservationShocksSqrtP(:,:,1) = H_lower_triangular_cholesky ; +% elseif ParticleOptions.mixture_measurement_shocks==1 +% if ParticleOptions.proposal_approximation.cubature +% [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); +% ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; +% elseif ParticleOptions.proposal_approximation.unscented +% [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); +% else +% if ~ParticleOptions.distribution_approximation.montecarlo +% error('Estimation: This approximation for the proposal is not implemented or unknown!') +% end +% end +% J = size(ObservationShocksWeights,1) ; +% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; +% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; +% for j=1:J +% ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky ; +% end +% else +% if ParticleOptions.proposal_approximation.cubature +% [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); +% ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; +% elseif ParticleOptions.proposal_approximation.unscented +% [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); +% else +% if ~ParticleOptions.distribution_approximation.montecarlo +% error('Estimation: This approximation for the proposal is not implemented or unknown!') +% end +% end +% J = size(ObservationShocksWeights,1) ; +% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; +% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; +% for j=1:J +% ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky/sqrt(ObservationShocksWeights(j)) ; +% end +% end Gprime = G*I ; Gsecond = G*I*J ; From 3e22ed1bc2cf27be257b7ecd7d56b0e48d09ea4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 27 May 2015 15:26:59 +0200 Subject: [PATCH 030/101] update the function to the recent modifications in dynare_estimation. --- src/online_auxiliary_filter.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 3e0b146ac..d68166bbe 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -1,6 +1,6 @@ -function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,bounds,DynareResults) - -% Carvalho & Lopes particle filter = auxiliary particle filter including Liu & West filter on parameters. +function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(xparam1,DynareDataset,dataset_info,DynareOptions,Model,EstimatedParameters,BayesInfo,bounds,DynareResults) + +% Liu & West particle filter = auxiliary particle filter including Liu & West filter on parameters. % % INPUTS % ReducedForm [structure] Matlab's structure describing the reduced form model. From 12a5e664f4fa84f0c7d1145cf2fe1dd60dbbee0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Hermes=29?= Date: Thu, 28 May 2015 15:25:18 +0200 Subject: [PATCH 031/101] Cosmetic change (display of online approach progress). --- src/online_auxiliary_filter.m | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index d68166bbe..61112dff7 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -109,7 +109,11 @@ ub95_xparam = zeros(number_of_parameters,sample_size) ; %% The Online filter for t=1:sample_size - disp(t) + if t>1 + fprintf('\nSubsample with %s first observations.\n\n', int2str(t)) + else + fprintf('\nSubsample with only the first observation.\n\n', int2str(t)) + end % Moments of parameters particles distribution m_bar = xparam*(weights') ; temp = bsxfun(@minus,xparam,m_bar) ; @@ -253,7 +257,12 @@ for t=1:sample_size end end end - disp([lb95_xparam(:,t) mean_xparam(:,t) ub95_xparam(:,t)]) + str = sprintf(' Lower Bound (95%%) \t Mean \t\t\t Upper Bound (95%%)'); + for l=1:size(xparam,1) + str = sprintf('%s\n %5.4f \t\t %7.5f \t\t %5.4f', str, lb95_xparam(l,t), mean_xparam(l,t), ub95_xparam(l,t)); + end + disp([str]) + disp('') end distrib_param = xparam ; xparam = mean_xparam(:,sample_size) ; From 5220ec2a1a70654c16255e327cd7b8a7e6e94235 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Fri, 24 Jul 2015 12:57:17 +0200 Subject: [PATCH 032/101] Reflect new input argument of lyapunov_symm.m of Dynare Related to https://github.com/DynareTeam/dynare/pull/983 --- src/solve_model_for_online_filter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 0d8f191c1..7ef12bbe9 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -329,7 +329,7 @@ if observation_number==1 switch DynareOptions.particle.initialization case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. StateVectorMean = ReducedForm.constant(mf0); - StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',1e-12,1e-12); + StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',DynareOptions.lyapunov_fixed_point_tol,DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold); case 2% Initial state vector covariance is a monte-carlo based estimate of the ergodic variance (consistent with a k-order Taylor-approximation of the model). StateVectorMean = ReducedForm.constant(mf0); old_DynareOptionsperiods = DynareOptions.periods; From cdc7f6ddf9e3c69a0c01215724cf370b9f81d176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 2 Oct 2015 16:02:49 +0200 Subject: [PATCH 033/101] Modify the weights to prevent crash in the cholesky of the covariance. --- src/gaussian_filter.m | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index 5500ea8c1..9ec83a0d4 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -92,14 +92,14 @@ if isempty(H) H = 0; H_lower_triangular_cholesky = 0; else - H_lower_triangular_cholesky = reduced_rank_cholesky(H)'; + H_lower_triangular_cholesky = chol(H)' ; %reduced_rank_cholesky(H)'; end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; -StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)';%reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); -Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; +Q_lower_triangular_cholesky = chol(Q)'; %reduced_rank_cholesky(Q)'; % Initialization of the likelihood. const_lik = (2*pi)^(number_of_observed_variables/2) ; @@ -126,12 +126,16 @@ for t=1:sample_size 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; SampleWeights = IncrementalWeights/number_of_particles ; end + SampleWeights = SampleWeights + 1e-6*ones(size(SampleWeights,1),1) ; SumSampleWeights = sum(SampleWeights) ; lik(t) = log(SumSampleWeights) ; SampleWeights = SampleWeights./SumSampleWeights ; StateVectorMean = StateParticles*SampleWeights ; temp = bsxfun(@minus,StateParticles,StateVectorMean) ; - StateVectorVarianceSquareRoot = reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; + %disp(SampleWeights) + %disp(StateParticles) + %disp(StateVectorMean) + StateVectorVarianceSquareRoot = chol( bsxfun(@times,SampleWeights',temp)*temp' )';%reduced_rank_cholesky( bsxfun(@times,SampleWeights',temp)*temp' )'; end LIK = -sum(lik(start:end)); From 04ad104bfb4649a9f339524f32732f451b38406c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 2 Oct 2015 16:05:26 +0200 Subject: [PATCH 034/101] Fix a bug in likelihood calculation. --- src/auxiliary_particle_filter.m | 20 ++++++++++---------- src/conditional_filter_proposal.m | 2 +- src/conditional_particle_filter.m | 12 ++++++------ src/gaussian_densities.m | 7 ++++--- src/gaussian_filter_bank.m | 2 +- src/sequential_importance_particle_filter.m | 15 ++++++++------- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 92826137a..78c0bdd81 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -64,7 +64,7 @@ end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; -StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)';%reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); Q_lower_triangular_cholesky = chol(Q)'; if pruning @@ -76,7 +76,7 @@ end set_dynare_seed('default'); % Initialization of the likelihood. -const_lik = log(2*pi)*number_of_observed_variables; +const_lik = log(2*pi)*number_of_observed_variables +log(det(H)); lik = NaN(sample_size,1); LIK = NaN; @@ -125,11 +125,11 @@ for t=1:sample_size tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end end - PredictedObservedMean = weights*(tmp(mf1,:)'); + %PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); - dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean'); - PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' +H; - wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; + %dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean'); + %PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' +H; + wtilde = exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))) ; tau_tilde = weights.*wtilde ; sum_tau_tilde = sum(tau_tilde) ; lik(t) = log(sum_tau_tilde) ; @@ -148,11 +148,11 @@ for t=1:sample_size tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end StateVectors = tmp(mf0,:); - PredictedObservedMean = mean(tmp(mf1,:),2); + %PredictedObservedMean = mean(tmp(mf1,:),2); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); - dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); - PredictedObservedVariance = (dPredictedObservedMean*dPredictedObservedMean')/number_of_particles + H; - lnw = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))); + %dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + %PredictedObservedVariance = (dPredictedObservedMean*dPredictedObservedMean')/number_of_particles + H; + lnw = exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))); wtilde = lnw.*factor ; weights = wtilde/sum(wtilde); end diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 0ef5aedab..f593ad863 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -113,7 +113,7 @@ else StateVectorMean = PredictedStateMean + KalmanFilterGain*(obs - PredictedObservedMean); StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); - StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; + StateVectorVarianceSquareRoot = chol(StateVectorVariance)';%reduced_rank_cholesky(StateVectorVariance)'; end ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 4aef9f392..57ee0f1e9 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -57,9 +57,9 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOpt % AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr % stephane DOT adjemian AT univ DASH lemans DOT fr -persistent init_flag mf0 mf1 +persistent init_flag mf1 persistent number_of_particles -persistent sample_size number_of_state_variables number_of_observed_variables +persistent sample_size number_of_observed_variables % Set default if isempty(start) @@ -68,10 +68,10 @@ end % Set persistent variables. if isempty(init_flag) - mf0 = ReducedForm.mf0; + %mf0 = ReducedForm.mf0; mf1 = ReducedForm.mf1; sample_size = size(Y,2); - number_of_state_variables = length(mf0); + %number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); init_flag = 1; number_of_particles = ParticleOptions.number_of_particles ; @@ -84,14 +84,14 @@ if isempty(H) H = 0; H_lower_triangular_cholesky = 0; else - H_lower_triangular_cholesky = reduced_rank_cholesky(H)'; + H_lower_triangular_cholesky = chol(H)'; %reduced_rank_cholesky(H)'; end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); -Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; +Q_lower_triangular_cholesky = chol(Q)'; %reduced_rank_cholesky(Q)'; % Set seed for randn(). set_dynare_seed('default'); diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index ae3afb130..591b4d40b 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -43,9 +43,10 @@ prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; % likelihood yt_t_1_i = measurement_equations(particles,ReducedForm,ThreadsOptions) ; eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; -yt_t_1 = sum(yt_t_1_i*weigths1,2) ; -tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; -Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; +%yt_t_1 = sum(yt_t_1_i*weigths1,2) ; +%tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; +%Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; +Pyy = H ; sqr_det = sqrt(det(Pyy)) ; foo = (eta_t_i/Pyy).*eta_t_i ; likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index 4f45f7e38..f7589735b 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -118,5 +118,5 @@ else StateVectorMean = PredictedStateMean + KalmanFilterGain*PredictionError; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); - StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; + StateVectorVarianceSquareRoot = chol(StateVectorVariance)'; %reduced_rank_cholesky(StateVectorVariance)'; end \ No newline at end of file diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 24b0798fe..51e0bd7a1 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -66,12 +66,12 @@ if isempty(H) end % Initialization of the likelihood. -const_lik = log(2*pi)*number_of_observed_variables; +const_lik = log(2*pi)*number_of_observed_variables +log(det(H)) ; lik = NaN(sample_size,1); % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; -StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)';%reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; if pruning StateVectorMean_ = StateVectorMean; StateVectorVarianceSquareRoot_ = StateVectorVarianceSquareRoot; @@ -103,12 +103,13 @@ for t=1:sample_size else tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end - PredictedObservedMean = tmp(mf1,:)*transpose(weights); + %PredictedObservedMean = tmp(mf1,:)*transpose(weights); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); - dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); - PredictedObservedVariance = bsxfun(@times,dPredictedObservedMean,weights)*dPredictedObservedMean' + H; - if rcond(PredictedObservedVariance) > 1e-16 - lnw = -.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1)); + %dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + %PredictedObservedVariance = bsxfun(@times,dPredictedObservedMean,weights)*dPredictedObservedMean' + H; + %PredictedObservedVariance = H; + if rcond(H) > 1e-16 + lnw = -.5*(const_lik+sum(PredictionError.*(H\PredictionError),1)); else LIK = NaN; return From 93039cd92e040e3a2090a28831ced68ac4cb67c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Tue, 6 Oct 2015 17:18:09 +0200 Subject: [PATCH 035/101] fix a bug on format matrix. --- src/online_auxiliary_filter.m | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 61112dff7..9319b896e 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -67,7 +67,7 @@ end % Get initial conditions for the state particles StateVectorMean = ReducedForm.StateVectorMean; -StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); if pruning @@ -81,9 +81,9 @@ small_a = sqrt(1-h_square) ; % Initialization of parameter particles xparam = zeros(number_of_parameters,number_of_particles) ; -stderr = sqrt(bsxfun(@power,bounds.ub+bounds.lb,2)/12)/100 ; -stderr = sqrt(bsxfun(@power,bounds.ub+bounds.lb,2)/12)/50 ; -stderr = sqrt(bsxfun(@power,bounds.ub+bounds.lb,2)/12)/20 ; +stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/100 ; +stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/50 ; +%stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/20 ; i = 1 ; while i<=number_of_particles %candidate = start_param + .001*liu_west_chol_sigma_bar*randn(number_of_parameters,1) ; @@ -122,7 +122,7 @@ for t=1:sample_size chol_sigma_bar = chol(h_square*sigma_bar)' ; end % Prediction (without shocks) - ObservedVariables = zeros(number_of_observed_variables,number_of_particles) ; + wtilde = zeros(1,number_of_particles) ; for i=1:number_of_particles % model resolution [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... @@ -144,13 +144,9 @@ for t=1:sample_size else tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); end - ObservedVariables(:,i) = tmp(mf1,:) ; + PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); + wtilde(i) = exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))) ; end - PredictedObservedMean = sum(bsxfun(@times,weights,ObservedVariables),2) ; - PredictionError = bsxfun(@minus,Y(t,:)',ObservedVariables); - dPredictedObservedMean = bsxfun(@minus,ObservedVariables,PredictedObservedMean); - PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' + ReducedForm.H ; - wtilde = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))) ; % unormalized weights and observation likelihood contribution tau_tilde = weights.*wtilde ; sum_tau_tilde = sum(tau_tilde) ; @@ -161,10 +157,10 @@ for t=1:sample_size if pruning StateVectors_ = StateVectors_(:,indx) ; end - xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam) ; - xparam = xparam(:,indx) ; + xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam(:,indx)) ; wtilde = wtilde(indx) ; % draw in the new distributions + lnw = zeros(1,number_of_particles) ; i = 1 ; while i<=number_of_particles candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters,1) ; @@ -194,15 +190,11 @@ for t=1:sample_size tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); end StateVectors(:,i) = tmp(mf0,:) ; - ObservedVariables(:,i) = tmp(mf1,:) ; + PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); + lnw(i) = exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))); i = i+1 ; end end - PredictedObservedMean = sum(bsxfun(@times,weights,ObservedVariables),2) ; - PredictionError = bsxfun(@minus,Y(t,:)',ObservedVariables); - dPredictedObservedMean = bsxfun(@minus,ObservedVariables,PredictedObservedMean); - PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' + ReducedForm.H ; - lnw = exp(-.5*(const_lik+log(det(PredictedObservedVariance))+sum(PredictionError.*(PredictedObservedVariance\PredictionError),1))); % importance ratio wtilde = lnw./wtilde ; % normalization From 5b5e88b50dc428096d39ff9725fbce93771db923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Tue, 6 Oct 2015 17:21:02 +0200 Subject: [PATCH 036/101] Modify the inputs of gaussian_density. --- src/gaussian_densities.m | 2 +- src/gaussian_filter.m | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 591b4d40b..4f2b21438 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -1,4 +1,4 @@ -function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) +function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,ReducedForm,ThreadsOptions) % % Elements to calculate the importance sampling ratio % diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index 9ec83a0d4..b1cf3d6c1 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -115,7 +115,7 @@ for t=1:sample_size gaussian_densities(Y(:,t),StateVectorMean,... StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - weights2,weights_c2,ReducedForm,ThreadsOptions) ; + ReducedForm,ThreadsOptions) ; SampleWeights = weights2.*IncrementalWeights ; else StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean) ; @@ -123,7 +123,7 @@ for t=1:sample_size gaussian_densities(Y(:,t),StateVectorMean,... StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; + ReducedForm,ThreadsOptions) ; SampleWeights = IncrementalWeights/number_of_particles ; end SampleWeights = SampleWeights + 1e-6*ones(size(SampleWeights,1),1) ; From 18059c01a640ac2e85317dcd3931e9e43f908a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 7 Oct 2015 15:23:42 +0200 Subject: [PATCH 037/101] Correction on a bug and extension of the original paper for the calculation of incremental weights. --- src/conditional_filter_proposal.m | 14 ++++++++------ src/conditional_particle_filter.m | 16 +++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index f593ad863..e692c66b5 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -95,6 +95,7 @@ if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_a PredictedObservedMean = sum(PredictedObservedMean,2) ; dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights) ; dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)'.*sqrt(weights); + PredictedStateVariance = dState*dState'; big_mat = [dObserved dState; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; [mat1,mat] = qr2(big_mat,0); mat = mat'; @@ -112,12 +113,13 @@ else KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance ; StateVectorMean = PredictedStateMean + KalmanFilterGain*(obs - PredictedObservedMean); StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; - StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); - StateVectorVarianceSquareRoot = chol(StateVectorVariance)';%reduced_rank_cholesky(StateVectorVariance)'; + %StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); + StateVectorVarianceSquareRoot = chol(StateVectorVariance + 1e-6)' ; end +PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + 1e-6)' ; ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; -ypred = measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions) ; -foo = H_lower_triangular_cholesky \ (obs - ypred) ; -likelihood = exp(-0.5*(foo)'*foo)/normconst2 + 1e-99 ; -Weights = SampleWeights.*likelihood; +Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; +Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; +Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; +Weights = SampleWeights.*Likelihood.*(Prior./Posterior) ; diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 57ee0f1e9..89c37b954 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -68,10 +68,8 @@ end % Set persistent variables. if isempty(init_flag) - %mf0 = ReducedForm.mf0; mf1 = ReducedForm.mf1; sample_size = size(Y,2); - %number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); init_flag = 1; number_of_particles = ParticleOptions.number_of_particles ; @@ -84,25 +82,23 @@ if isempty(H) H = 0; H_lower_triangular_cholesky = 0; else - H_lower_triangular_cholesky = chol(H)'; %reduced_rank_cholesky(H)'; + H_lower_triangular_cholesky = chol(H)'; end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; -StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); -Q_lower_triangular_cholesky = chol(Q)'; %reduced_rank_cholesky(Q)'; +Q_lower_triangular_cholesky = chol(Q)'; % Set seed for randn(). set_dynare_seed('default'); % Initialization of the likelihood. -normconst2 = log(2*pi)*number_of_observed_variables*prod(diag(H_lower_triangular_cholesky)) ; +normconst2 = sqrt( ((2*pi)^number_of_observed_variables)*prod(det(H)) ) ; lik = NaN(sample_size,1); LIK = NaN; - ks = 0 ; - StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); SampleWeights = ones(1,number_of_particles)/number_of_particles ; for t=1:sample_size @@ -120,6 +116,4 @@ for t=1:sample_size end end -LIK = -sum(lik(start:end)); - - +LIK = -sum(lik(start:end)); \ No newline at end of file From f37094b20a574706a1c75620e3364d08aaf8d7e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 7 Oct 2015 15:25:16 +0200 Subject: [PATCH 038/101] Minor modifications in the inputs of the function. --- src/gaussian_densities.m | 3 --- src/probability2.m | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 4f2b21438..73a731403 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -43,9 +43,6 @@ prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; % likelihood yt_t_1_i = measurement_equations(particles,ReducedForm,ThreadsOptions) ; eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; -%yt_t_1 = sum(yt_t_1_i*weigths1,2) ; -%tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; -%Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; Pyy = H ; sqr_det = sqrt(det(Pyy)) ; foo = (eta_t_i/Pyy).*eta_t_i ; diff --git a/src/probability2.m b/src/probability2.m index 57ab65f8f..a7486d1b8 100644 --- a/src/probability2.m +++ b/src/probability2.m @@ -34,5 +34,4 @@ function [density] = probability2(mu,S,X) dim = size(X,1) ; normfact = bsxfun(@power,(2*pi),(dim/2)) ; foo = S\(bsxfun(@minus,X,mu)) ; -density = exp(-0.5*sum(foo.*foo)')./abs((normfact*prod(diag(S)))) + 1e-99 ; - +density = exp(-0.5*sum(foo.*foo)')./abs((normfact*prod(diag(S)))) + 1e-99 ; \ No newline at end of file From 5922f88182f3cf94fbf15878d569976f24ab37d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 9 Oct 2015 14:42:53 +0200 Subject: [PATCH 039/101] Add the possibility to use an sparse-grid Kalman filter with approximation at order 2. --- src/Kalman_filter.m | 161 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 src/Kalman_filter.m diff --git a/src/Kalman_filter.m b/src/Kalman_filter.m new file mode 100644 index 000000000..e5d36ee5e --- /dev/null +++ b/src/Kalman_filter.m @@ -0,0 +1,161 @@ +function [LIK,lik] = Kalman_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions) +% Evaluates the likelihood of a non-linear model approximating the +% predictive (prior) and filtered (posterior) densities for state variables +% by a Kalman filter. +% Gaussian distribution approximation is done by: +% - a spherical-radial cubature (ref: Arasaratnam & Haykin, 2009). +% - a scaled unscented transform cubature (ref: Julier & Uhlmann 1995) +% - Monte-Carlo draws from a multivariate gaussian distribution. +% First and second moments of prior and posterior state densities are computed +% from the resulting nodes/particles and allows to generate new distributions at the +% following observation. +% Pros: The use of nodes is much faster than Monte-Carlo Gaussian particle and standard particles +% filters since it treats a lesser number of particles. +% Cons: 1. Application a linear projection formulae in a nonlinear context. +% 2. Parameter estimations may be biaised if the model is truly non-gaussian since predictive and +% filtered densities are unimodal. +% +% INPUTS +% Reduced_Form [structure] Matlab's structure describing the reduced form model. +% Y [double] matrix of original observed variables. +% start [double] structural parameters. +% ParticleOptions [structure] Matlab's structure describing options concerning particle filtering. +% ThreadsOptions [structure] Matlab's structure. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2015 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +persistent init_flag mf0 mf1 nodes weights weights_c +persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations + +% Set default +if isempty(start) + start = 1; +end + +% Set local state space model (first-order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; +% Set local state space model (second-order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + ghx + ghu + ghxx + ghuu + ghxu +end + +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables. +if isempty(init_flag) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + init_flag = 1; +end + +% compute gaussian quadrature nodes and weights on states and shocks + +if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo + [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations) ; + weights_c = weights ; +elseif ParticleOptions.proposal_approximation.unscented + [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables+number_of_structural_innovations,ParticleOptions); +else + error('Estimation: This approximation for the proposal is not implemented or unknown!') +end + +if ParticleOptions.distribution_approximation.montecarlo + set_dynare_seed('default'); +end + +% Get covariance matrices +H = ReducedForm.H; +H_lower_triangular_cholesky = chol(H)' ; +Q_lower_triangular_cholesky = chol(ReducedForm.Q)'; + +% Get initial condition for the state vector. +StateVectorMean = ReducedForm.StateVectorMean; +StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; + +% Initialization of the likelihood. +lik = NaN(sample_size,1); +LIK = NaN; + +for t=1:sample_size + + xbar = [StateVectorMean ; zeros(number_of_structural_innovations,1) ] ; + sqr_Px = [ [ StateVectorVarianceSquareRoot zeros(number_of_state_variables,number_of_structural_innovations) ] ; + [ zeros(number_of_structural_innovations,number_of_state_variables) Q_lower_triangular_cholesky ] ]; + sigma_points = bsxfun(@plus,xbar,sqr_Px*(nodes')); + StateVectors = sigma_points(1:number_of_state_variables,:); + epsilon = sigma_points(number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations,:); + yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + PredictedStateMean = tmp(mf0,:)*weights ; + PredictedObservedMean = tmp(mf1,:)*weights; + + if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo + PredictedStateMean = sum(PredictedStateMean,2); + PredictedObservedMean = sum(PredictedObservedMean,2); + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights); + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)'.*sqrt(weights); + big_mat = [dObserved dState ; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; + [mat1,mat] = qr2(big_mat,0); + mat = mat'; + clear('mat1'); + PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); + CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); + StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); + PredictionError = Y(:,t) - PredictedObservedMean; + StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*PredictionError; + else + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + PredictedStateVariance = dState*diag(weights_c)*dState'; + PredictedObservedVariance = dObserved*diag(weights_c)*dObserved' + H; + PredictedStateAndObservedCovariance = dState*diag(weights_c)*dObserved'; + PredictionError = Y(:,t) - PredictedObservedMean; + KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance; + StateVectorMean = PredictedStateMean + KalmanFilterGain*PredictionError; + StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; + StateVectorVarianceSquareRoot = chol(StateVectorVariance)'; + PredictedObservedVarianceSquareRoot = chol(PredictedObservedVariance)' ; + end + lik(t) = log( probability2(0,PredictedObservedVarianceSquareRoot,PredictionError) ) ; +end + +LIK = -sum(lik(start:end)); From 8d401a22f5138773f7092456c9553ebbb11dd3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Tue, 20 Oct 2015 15:12:56 +0200 Subject: [PATCH 040/101] Fix the calculation of the likelihood on the APF. --- src/auxiliary_particle_filter.m | 91 ++++++++++++++++----------------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 78c0bdd81..a48973b8a 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -1,8 +1,9 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) -% Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. - -% Copyright (C) 2011-2014 Dynare Team +% Evaluates the likelihood of a nonlinear model with the auxiliary particle filter +% allowing eventually resampling. +% +% Copyright (C) 2011-2015 Dynare Team % % This file is part of Dynare (particles module). % @@ -20,7 +21,7 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptio % along with Dynare. If not, see . persistent init_flag mf0 mf1 number_of_particles -persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations +persistent sample_size number_of_observed_variables number_of_structural_innovations % Set default if isempty(start) @@ -40,7 +41,6 @@ if isempty(init_flag) mf0 = ReducedForm.mf0; mf1 = ReducedForm.mf1; sample_size = size(Y,2); - number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); number_of_particles = ParticleOptions.number_of_particles; @@ -58,55 +58,44 @@ ghxu = ReducedForm.ghxu; % Get covariance matrices Q = ReducedForm.Q; H = ReducedForm.H; -if isempty(H) - H = 0; -end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; -StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)';%reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); Q_lower_triangular_cholesky = chol(Q)'; -if pruning - StateVectorMean_ = StateVectorMean; - StateVectorVarianceSquareRoot_ = StateVectorVarianceSquareRoot; -end % Set seed for randn(). set_dynare_seed('default'); % Initialization of the likelihood. -const_lik = log(2*pi)*number_of_observed_variables +log(det(H)); +const_lik = log(2*pi)*number_of_observed_variables+log(det(H)); lik = NaN(sample_size,1); LIK = NaN; % Initialization of the weights across particles. weights = ones(1,number_of_particles)/number_of_particles ; StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); +%StateVectors = bsxfun(@plus,zeros(state_variance_rank,number_of_particles),StateVectorMean); if pruning StateVectors_ = StateVectors; end -epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); -yhat = zeros(2,number_of_particles) ; -if pruning - yhat_ = zeros(2,number_of_particles) ; - [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); - StateVectors_ = tmp_(mf0,:); -else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); -end -StateVectors = tmp(mf0,:) ; +% Uncomment for building the mean average predictions based on a sparse +% grids of structural shocks. Otherwise, all shocks are set to 0 in the +% prediction. +%if ParticleOptions.proposal_approximation.cubature +% [nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; +% nodes_weights = ones(size(nodes,1),1)*nodes_weights ; +%elseif ParticleOptions.proposal_approximation.unscented +% [nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); +%else +% error('Estimation: This approximation for the proposal is not implemented or unknown!') +%end +%nodes = Q_lower_triangular_cholesky*nodes ; -if ParticleOptions.proposal_approximation.cubature - [nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; - nodes_weights = ones(size(nodes,1),1)*nodes_weights ; -elseif ParticleOptions.proposal_approximation.unscented - [nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); -else - error('Estimation: This approximation for the proposal is not implemented or unknown!') -end -nodes = Q_lower_triangular_cholesky*nodes ; +nodes = zeros(1,number_of_structural_innovations) ; +nodes_weights = 1 ; for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); @@ -125,21 +114,19 @@ for t=1:sample_size tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end end - %PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); - %dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean'); - %PredictedObservedVariance = bsxfun(@times,weights,dPredictedObservedMean)*dPredictedObservedMean' +H; - wtilde = exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))) ; - tau_tilde = weights.*wtilde ; - sum_tau_tilde = sum(tau_tilde) ; - lik(t) = log(sum_tau_tilde) ; - tau_tilde = tau_tilde/sum_tau_tilde; + %tau_tilde = weights.*(exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))) + 1e-99) ; + % Replace Gaussian density with a Student density with 3 degrees of + % freedom for fat tails. + z = sum(PredictionError.*(H\PredictionError),1) ; + tau_tilde = weights.*(tpdf(z,3*ones(size(z)))+1e-99) ; + tau_tilde = tau_tilde/sum(tau_tilde) ; indx = resample(0,tau_tilde',ParticleOptions); if pruning yhat_ = yhat_(:,indx) ; end yhat = yhat(:,indx) ; - factor = weights(indx)./tau_tilde(indx) ; + weights_stage_1 = weights(indx)./tau_tilde(indx) ; epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); @@ -148,13 +135,21 @@ for t=1:sample_size tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end StateVectors = tmp(mf0,:); - %PredictedObservedMean = mean(tmp(mf1,:),2); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); - %dPredictedObservedMean = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); - %PredictedObservedVariance = (dPredictedObservedMean*dPredictedObservedMean')/number_of_particles + H; - lnw = exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))); - wtilde = lnw.*factor ; - weights = wtilde/sum(wtilde); + weights_stage_2 = weights_stage_1.*(exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))) + 1e-99) ; + lik(t) = log(mean(weights_stage_2)) ; + weights = weights_stage_2/sum(weights_stage_2); + if (ParticleOptions.resampling.status.generic && neff(weights) Date: Fri, 4 Dec 2015 11:44:45 +0100 Subject: [PATCH 041/101] Fix a bug in the gaussian density calculation. --- src/gaussian_densities.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 73a731403..ae3afb130 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -1,4 +1,4 @@ -function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,ReducedForm,ThreadsOptions) +function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) % % Elements to calculate the importance sampling ratio % @@ -43,7 +43,9 @@ prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; % likelihood yt_t_1_i = measurement_equations(particles,ReducedForm,ThreadsOptions) ; eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; -Pyy = H ; +yt_t_1 = sum(yt_t_1_i*weigths1,2) ; +tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; +Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; sqr_det = sqrt(det(Pyy)) ; foo = (eta_t_i/Pyy).*eta_t_i ; likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; From c50392de4b7784bd43a9bb407dd5018029ee7de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 4 Dec 2015 12:42:42 +0100 Subject: [PATCH 042/101] Correct the auxiliary filter part. --- src/online_auxiliary_filter.m | 39 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 9319b896e..fef41652b 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -43,7 +43,7 @@ persistent start_param sample_size number_of_observed_variables number_of_struct % Set seed for randn(). set_dynare_seed('default') ; pruning = DynareOptions.particle.pruning; -second_resample = 1 ; +second_resample = 0 ; variance_update = 1 ; % initialization of state particles @@ -122,7 +122,7 @@ for t=1:sample_size chol_sigma_bar = chol(h_square*sigma_bar)' ; end % Prediction (without shocks) - wtilde = zeros(1,number_of_particles) ; + tau_tilde = zeros(1,number_of_particles) ; for i=1:number_of_particles % model resolution [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... @@ -145,22 +145,23 @@ for t=1:sample_size tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); end PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); - wtilde(i) = exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))) ; + % Replace Gaussian density with a Student density with 3 degrees of + % freedom for fat tails. + z = sum(PredictionError.*(ReducedForm.H\PredictionError),1) ; + tau_tilde(i) = weights(i).*(tpdf(z,3*ones(size(z)))+1e-99) ; + %tau_tilde(i) = weights(i).*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))) ; end - % unormalized weights and observation likelihood contribution - tau_tilde = weights.*wtilde ; - sum_tau_tilde = sum(tau_tilde) ; % particles selection - tau_tilde = tau_tilde/sum_tau_tilde ; + tau_tilde = tau_tilde/sum(tau_tilde) ; indx = resample(0,tau_tilde',DynareOptions.particle); StateVectors = StateVectors(:,indx) ; if pruning StateVectors_ = StateVectors_(:,indx) ; end xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam(:,indx)) ; - wtilde = wtilde(indx) ; + w_stage1 = weights(indx)./tau_tilde(indx) ; % draw in the new distributions - lnw = zeros(1,number_of_particles) ; + wtilde = zeros(1,number_of_particles) ; i = 1 ; while i<=number_of_particles candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters,1) ; @@ -191,18 +192,16 @@ for t=1:sample_size end StateVectors(:,i) = tmp(mf0,:) ; PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); - lnw(i) = exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))); + wtilde(i) = w_stage1(i)*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))); i = i+1 ; end end - % importance ratio - wtilde = lnw./wtilde ; % normalization weights = wtilde/sum(wtilde); if (variance_update==1) && (neff(weights)0.025 && pass1==1 - lb95_xparam(i,t) = (temp(j-1,1)+temp(j,1))/2 ; + if cumulated_weights(j)>=0.025 && pass1==1 + lb95_xparam(i,t) = temp(j,1) ; pass1 = 2 ; end - if cumulated_weights(j)>0.5 && pass2==1 - median_xparam(i,t) = (temp(j-1,1)+temp(j,1))/2 ; + if cumulated_weights(j)>=0.5 && pass2==1 + median_xparam(i,t) = temp(j,1) ; pass2 = 2 ; end - if cumulated_weights(j)>0.975 && pass3==1 - ub95_xparam(i,t) = (temp(j-1,1)+temp(j,1))/2 ; + if cumulated_weights(j)>=0.975 && pass3==1 + ub95_xparam(i,t) = temp(j,1) ; pass3 = 2 ; end end @@ -368,4 +367,4 @@ for plt = 1:nbplt, fprintf(fidTeX,' \n'); end end - \ No newline at end of file + From c8c14f426be1e560dc1309485d1740712e6eae42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 4 Dec 2015 14:48:26 +0100 Subject: [PATCH 043/101] Re-activate the option of resampling in Gaussian Particle Filter. --- src/gaussian_filter.m | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index b1cf3d6c1..2cee18ee7 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -92,14 +92,14 @@ if isempty(H) H = 0; H_lower_triangular_cholesky = 0; else - H_lower_triangular_cholesky = chol(H)' ; %reduced_rank_cholesky(H)'; + H_lower_triangular_cholesky = reduced_rank_cholesky(H)'; end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; -StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)';%reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateVectorVarianceSquareRoot = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); -Q_lower_triangular_cholesky = chol(Q)'; %reduced_rank_cholesky(Q)'; +Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; % Initialization of the likelihood. const_lik = (2*pi)^(number_of_observed_variables/2) ; @@ -115,7 +115,7 @@ for t=1:sample_size gaussian_densities(Y(:,t),StateVectorMean,... StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - ReducedForm,ThreadsOptions) ; + weights2,weights_c2,ReducedForm,ThreadsOptions) ; SampleWeights = weights2.*IncrementalWeights ; else StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean) ; @@ -123,19 +123,22 @@ for t=1:sample_size gaussian_densities(Y(:,t),StateVectorMean,... StateVectorVarianceSquareRoot,PredictedStateMean,... PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - ReducedForm,ThreadsOptions) ; + 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; SampleWeights = IncrementalWeights/number_of_particles ; end SampleWeights = SampleWeights + 1e-6*ones(size(SampleWeights,1),1) ; SumSampleWeights = sum(SampleWeights) ; lik(t) = log(SumSampleWeights) ; SampleWeights = SampleWeights./SumSampleWeights ; + if not(ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented) + if (ParticleOptions.resampling.status.generic && neff(SampleWeights) Date: Fri, 4 Dec 2015 15:29:25 +0100 Subject: [PATCH 044/101] Make the distinction between original Amisano and Tristani's way to calculate particles weights and the likelihood (CPF1) and Murray's way (CPF2). --- src/conditional_filter_proposal.m | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index e692c66b5..5eda6b9b1 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -103,7 +103,11 @@ if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_a PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); - StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*(obs - PredictedObservedMean); + Error = obs - PredictedObservedMean ; + StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*Error ; + if strcmpi(options_.particle.filter_algorithm, 'cpf1') + Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),PredictedObservedVarianceSquareRoot,Error) ; + end else dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); @@ -111,15 +115,20 @@ else PredictedObservedVariance = dObserved*diag(weights_c)*dObserved' + H; PredictedStateAndObservedCovariance = dState*diag(weights_c)*dObserved'; KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance ; - StateVectorMean = PredictedStateMean + KalmanFilterGain*(obs - PredictedObservedMean); + Error = obs - PredictedObservedMean ; + StateVectorMean = PredictedStateMean + KalmanFilterGain*Error ; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; - %StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); StateVectorVarianceSquareRoot = chol(StateVectorVariance + 1e-6)' ; + if strcmpi(options_.particle.filter_algorithm, 'cpf1') + Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; + end end PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + 1e-6)' ; ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; -Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; -Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; -Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; -Weights = SampleWeights.*Likelihood.*(Prior./Posterior) ; +if strcmpi(options_.particle.filter_algorithm, 'cpf2') + Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; + Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; + Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; + Weights = SampleWeights.*Likelihood.*(Prior./Posterior) ; +end \ No newline at end of file From a73e4d94cb792f439a449b54cd5493a386c7bb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 4 Dec 2015 16:00:04 +0100 Subject: [PATCH 045/101] Add the possibility of Gaussian-Mixture Particle Filter without resampling. --- src/fit_gaussian_mixture.m | 4 ++-- src/gaussian_mixture_filter.m | 11 ++++++---- src/probability3.m | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 src/probability3.m diff --git a/src/fit_gaussian_mixture.m b/src/fit_gaussian_mixture.m index e4c8e4c5d..43f2302bb 100644 --- a/src/fit_gaussian_mixture.m +++ b/src/fit_gaussian_mixture.m @@ -1,4 +1,4 @@ -function [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(X,StateMu,StateSqrtP,StateWeights,crit,niters,check) +function [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(X,X_weights,StateMu,StateSqrtP,StateWeights,crit,niters,check) % Copyright (C) 2013 Dynare Team % @@ -26,7 +26,7 @@ end eold = -Inf; for n=1:niters % Calculate posteriors based on old parameters - [prior,likelihood,marginal,posterior] = probability(StateMu,StateSqrtP,StateWeights,X); + [prior,likelihood,marginal,posterior] = probability3(StateMu,StateSqrtP,StateWeights,X,X_weights); e = sum(log(marginal)); if (n > 1 && abs((e - eold)/eold) < crit) return; diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index 77577d04c..c3116fb9a 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -294,7 +294,7 @@ for t=1:sample_size StateParticles = bsxfun(@plus,StateMuPost(:,i),StateSqrtPPost(:,:,i)*nodes') ; IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,weights,weights_c,ReducedForm,ThreadsOptions) ; + StateParticles,H,const_lik,ReducedForm,ThreadsOptions) ; SampleWeights(i) = sum(StateWeightsPost(i)*weights.*IncrementalWeights) ; end SumSampleWeights = sum(SampleWeights) ; @@ -312,13 +312,16 @@ for t=1:sample_size StateParticles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost',number_of_particles) ; IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,1/number_of_particles,... - 1/number_of_particles,ReducedForm,ThreadsOptions) ; + StateParticles,H,const_lik,ReducedForm,ThreadsOptions) ; SampleWeights = IncrementalWeights/number_of_particles ; SumSampleWeights = sum(SampleWeights,1) ; SampleWeights = SampleWeights./SumSampleWeights ; lik(t) = log(SumSampleWeights) ; - [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(StateParticles,StateMu,StateSqrtP,StateWeights,0.001,10,1) ; + if (ParticleOptions.resampling.status.generic && neff(SampleWeights). + +[dim,nov] = size(X); +M = size(mu,2) ; +if nargout>1 + likelihood = zeros(M,nov); + normfact = (2*pi)^(dim/2); + for k=1:M + XX = bsxfun(@minus,X,mu(:,k)); + S = sqrtP(:,:,k); + foo = S \ XX; + likelihood(k,:) = exp(-0.5*sum(foo.*foo, 1))/abs((normfact*prod(diag(S)))); + end +end +wlikelihood = bsxfun(@times,X_weights,likelihood) + 1e-99; +if nargout>2 + C = prior*wlikelihood + 1e-99; +end +if nargout>3 + posterior = bsxfun(@rdivide,bsxfun(@times,prior',wlikelihood),C) + 1e-99 ; + posterior = bsxfun(@rdivide,posterior,sum(posterior,1)); +end From 8c656316453b96f1ebd108a6b1584d3b5a9f82bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Wed, 1 Jun 2016 14:12:02 +0200 Subject: [PATCH 046/101] Renamed matlab routine. --- src/{Kalman_filter.m => nonlinear_kalman_filter.m} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/{Kalman_filter.m => nonlinear_kalman_filter.m} (98%) diff --git a/src/Kalman_filter.m b/src/nonlinear_kalman_filter.m similarity index 98% rename from src/Kalman_filter.m rename to src/nonlinear_kalman_filter.m index e5d36ee5e..f74a120c8 100644 --- a/src/Kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -1,4 +1,4 @@ -function [LIK,lik] = Kalman_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions) +function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions) % Evaluates the likelihood of a non-linear model approximating the % predictive (prior) and filtered (posterior) densities for state variables % by a Kalman filter. From af66ea9c287d84302783d464f348f787d08d3f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Wed, 1 Jun 2016 16:07:07 +0200 Subject: [PATCH 047/101] Changed logic for setting weights method in CPF. --- src/conditional_filter_proposal.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 5eda6b9b1..655928715 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -105,7 +105,7 @@ if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_a StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); Error = obs - PredictedObservedMean ; StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*Error ; - if strcmpi(options_.particle.filter_algorithm, 'cpf1') + if options_.particle.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),PredictedObservedVarianceSquareRoot,Error) ; end else @@ -119,14 +119,14 @@ else StateVectorMean = PredictedStateMean + KalmanFilterGain*Error ; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVarianceSquareRoot = chol(StateVectorVariance + 1e-6)' ; - if strcmpi(options_.particle.filter_algorithm, 'cpf1') + if options_.particle.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; end end PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + 1e-6)' ; ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; -if strcmpi(options_.particle.filter_algorithm, 'cpf2') +if options_.particle.cpf_weights_method.murrayjonesparslow Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; From a9800bef4d266e509e0a0a9c954c4f938b157c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 1 Jun 2016 17:11:28 +0200 Subject: [PATCH 048/101] Fixed bug on structure name. --- src/conditional_filter_proposal.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 655928715..3a019c6a4 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -105,7 +105,7 @@ if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_a StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); Error = obs - PredictedObservedMean ; StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*Error ; - if options_.particle.cpf_weights_method.amisanotristani + if ParticleOptions.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),PredictedObservedVarianceSquareRoot,Error) ; end else @@ -119,14 +119,14 @@ else StateVectorMean = PredictedStateMean + KalmanFilterGain*Error ; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVarianceSquareRoot = chol(StateVectorVariance + 1e-6)' ; - if options_.particle.cpf_weights_method.amisanotristani + if ParticleOptions.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; end end PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + 1e-6)' ; ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; -if options_.particle.cpf_weights_method.murrayjonesparslow +if ParticleOptions.cpf_weights_method.murrayjonesparslow Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; From 30540e39407d9f1ffbd8a7dbc37671020276941c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 1 Jun 2016 18:19:26 +0200 Subject: [PATCH 049/101] Modification of a structure name when calling incremental_weights. --- src/gaussian_mixture_filter.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index c3116fb9a..0dc257c8c 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -294,7 +294,7 @@ for t=1:sample_size StateParticles = bsxfun(@plus,StateMuPost(:,i),StateSqrtPPost(:,:,i)*nodes') ; IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,ReducedForm,ThreadsOptions) ; + StateParticles,H,const_lik,weights,weights_c,ReducedForm,ThreadsOptions) ; SampleWeights(i) = sum(StateWeightsPost(i)*weights.*IncrementalWeights) ; end SumSampleWeights = sum(SampleWeights) ; @@ -312,7 +312,8 @@ for t=1:sample_size StateParticles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost',number_of_particles) ; IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,ReducedForm,ThreadsOptions) ; + StateParticles,H,const_lik,1/number_of_particles,... + 1/number_of_particles,ReducedForm,ThreadsOptions) ; SampleWeights = IncrementalWeights/number_of_particles ; SumSampleWeights = sum(SampleWeights,1) ; SampleWeights = SampleWeights./SumSampleWeights ; From 81c606abb2280ac440b6d978225212cd069febbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 1 Jun 2016 18:24:27 +0200 Subject: [PATCH 050/101] Fixed bug on a structure name. --- src/solve_model_for_online_filter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 7ef12bbe9..62ed99cb5 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -294,7 +294,7 @@ dr = DynareResults.dr; if isempty(init_flag) mf0 = BayesInfo.mf0; mf1 = BayesInfo.mf1; - restrict_variables_idx = BayesInfo.restrict_var_list; + restrict_variables_idx = dr.restrict_var_list; observed_variables_idx = restrict_variables_idx(mf1); state_variables_idx = restrict_variables_idx(mf0); sample_size = size(Y,2); From 0fbab3d40120c0845e2ec48b1ffb1900102ad76c Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 14 Jun 2016 11:48:35 +0200 Subject: [PATCH 051/101] fix latex file ending for linux compilation --- src/online_auxiliary_filter.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index fef41652b..450d7be6a 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -21,7 +21,7 @@ function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(x % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2016 Dynare Team % % This file is part of Dynare. % @@ -268,7 +268,7 @@ TeX = DynareOptions.TeX; [nbplt,nr,nc,lr,lc,nstar] = pltorg(number_of_parameters); if TeX - fidTeX = fopen([Model.fname '_param_traj.TeX'],'w'); + fidTeX = fopen([Model.fname '_param_traj.tex'],'w'); fprintf(fidTeX,'%% TeX eps-loader file generated by online_auxiliary_filter.m (Dynare).\n'); fprintf(fidTeX,['%% ' datestr(now,0) '\n']); fprintf(fidTeX,' \n'); From 6d1036b73865a681eb2d6b578c198cf4463ef34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Thu, 30 Jun 2016 11:42:45 +0200 Subject: [PATCH 052/101] Modifications to facilitate Cholesky of states variances. --- src/conditional_filter_proposal.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 3a019c6a4..e90efa189 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -118,17 +118,17 @@ else Error = obs - PredictedObservedMean ; StateVectorMean = PredictedStateMean + KalmanFilterGain*Error ; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; - StateVectorVarianceSquareRoot = chol(StateVectorVariance + 1e-6)' ; + StateVectorVarianceSquareRoot = chol(StateVectorVariance + eye(number_of_state_variables)*1e-6)' ; if ParticleOptions.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; end end -PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + 1e-6)' ; +PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + eye(number_of_state_variables)*1e-6)' ; ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; if ParticleOptions.cpf_weights_method.murrayjonesparslow Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; Weights = SampleWeights.*Likelihood.*(Prior./Posterior) ; -end \ No newline at end of file +end From 285d5c171104e44e1a5d2fe30f062be08dbab8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Thu, 30 Jun 2016 12:12:58 +0200 Subject: [PATCH 053/101] Fix a bug in the predictive density calculation. --- src/auxiliary_particle_filter.m | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index a48973b8a..a7934115c 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -84,18 +84,18 @@ end % Uncomment for building the mean average predictions based on a sparse % grids of structural shocks. Otherwise, all shocks are set to 0 in the % prediction. -%if ParticleOptions.proposal_approximation.cubature -% [nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; -% nodes_weights = ones(size(nodes,1),1)*nodes_weights ; -%elseif ParticleOptions.proposal_approximation.unscented -% [nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); -%else -% error('Estimation: This approximation for the proposal is not implemented or unknown!') -%end -%nodes = Q_lower_triangular_cholesky*nodes ; +% if ParticleOptions.proposal_approximation.cubature +% [nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; +% nodes_weights = ones(size(nodes,1),1)*nodes_weights ; +% elseif ParticleOptions.proposal_approximation.unscented +% [nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); +% else +% error('Estimation: This approximation for the proposal is not implemented or unknown!') +% end +% nodes = (Q_lower_triangular_cholesky*(nodes'))' ; nodes = zeros(1,number_of_structural_innovations) ; -nodes_weights = 1 ; +nodes_weights = ones(number_of_structural_innovations,1) ; for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); @@ -104,14 +104,14 @@ for t=1:sample_size tmp = 0 ; tmp_ = 0 ; for i=1:size(nodes) - [tmp1, tmp1_] = local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + [tmp1, tmp1_] = local_state_space_iteration_2(yhat,nodes(i,:)'*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); tmp = tmp + nodes_weights(i)*tmp1 ; tmp_ = tmp_ + nodes_weights(i)*tmp1_ ; end else tmp = 0 ; for i=1:size(nodes) - tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)'*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end end PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); @@ -152,4 +152,4 @@ for t=1:sample_size end %plot(lik) ; -LIK = -sum(lik(start:end)); \ No newline at end of file +LIK = -sum(lik(start:end)); From ddc5b5b6650a32d9cc1f204b7c927a5bfbc74a59 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Mon, 23 Jan 2017 12:20:24 +0100 Subject: [PATCH 054/101] Properly terminate nonlinear_kalman_filter if non-positive definite matrices are encountered Otherwise, crashes can happen during mode-finding --- src/nonlinear_kalman_filter.m | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index f74a120c8..dd61a5e50 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -152,8 +152,18 @@ for t=1:sample_size KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance; StateVectorMean = PredictedStateMean + KalmanFilterGain*PredictionError; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; - StateVectorVarianceSquareRoot = chol(StateVectorVariance)'; - PredictedObservedVarianceSquareRoot = chol(PredictedObservedVariance)' ; + [StateVectorVarianceSquareRoot, p]= chol(StateVectorVariance,'lower'); + if p + LIK=-Inf; + lik(t)=-Inf; + return + end + [PredictedObservedVarianceSquareRoot, p]= chol(PredictedObservedVariance,'lower'); + if p + LIK=-Inf; + lik(t)=-Inf; + return + end end lik(t) = log( probability2(0,PredictedObservedVarianceSquareRoot,PredictionError) ) ; end From 20978ce117597f2ce83afb2fbcd92347ee1642d1 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 22 Mar 2017 17:08:02 +0100 Subject: [PATCH 055/101] update call to dyn_figure --- src/online_auxiliary_filter.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 450d7be6a..fde257455 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -21,7 +21,7 @@ function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(x % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2013-2016 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % @@ -281,7 +281,7 @@ for plt = 1:nbplt, NAMES = []; TeXNAMES = []; end - hh = dyn_figure(DynareOptions,'Name','Parameters Trajectories'); + hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Trajectories'); for k=1:min(nstar,length(xparam)-(plt-1)*nstar) subplot(nr,nc,k) kk = (plt-1)*nstar+k; @@ -328,7 +328,7 @@ for plt = 1:nbplt, NAMES = []; TeXNAMES = []; end - hh = dyn_figure(DynareOptions,'Name','Parameters Densities'); + hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Densities'); for k=1:min(nstar,length(xparam)-(plt-1)*nstar) subplot(nr,nc,k) kk = (plt-1)*nstar+k; From 823d947484675c8d409a4eb2377a57dc59bdf713 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 23 Mar 2017 17:57:17 +0100 Subject: [PATCH 056/101] update call to dyn_saveas --- src/online_auxiliary_filter.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index fde257455..8018ca69c 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -303,7 +303,7 @@ for plt = 1:nbplt, axis tight drawnow end - dyn_saveas(hh,[ Model.fname '_param_traj' int2str(plt) ],DynareOptions); + dyn_saveas(hh,[ Model.fname '_param_traj' int2str(plt) ],DynareOptions.nodisplay,DynareOptions.graph_format); if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); @@ -352,7 +352,7 @@ for plt = 1:nbplt, axis tight drawnow end - dyn_saveas(hh,[ Model.fname '_param_density' int2str(plt) ],DynareOptions); + dyn_saveas(hh,[ Model.fname '_param_density' int2str(plt) ],DynareOptions.nodisplay,DynareOptions.graph_format); if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); From 4921000f0ac66280fd39d577d81532b9b43f986d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 18 May 2017 23:59:10 +0200 Subject: [PATCH 057/101] Fixed indentation. --- src/auxiliary_initialization.m | 2 +- src/auxiliary_particle_filter.m | 10 +-- src/conditional_filter_proposal.m | 14 ++--- src/conditional_particle_filter.m | 50 +++++++-------- src/fit_gaussian_mixture.m | 55 ++++++++-------- src/gaussian_densities.m | 14 ++--- src/gaussian_filter.m | 22 +++---- src/gaussian_filter_bank.m | 4 +- src/gaussian_mixture_densities.m | 17 +++-- src/gaussian_mixture_filter.m | 58 ++++++++--------- src/gaussian_mixture_filter_bank.m | 20 +++--- src/importance_sampling.m | 11 ++-- src/measurement_equations.m | 5 +- src/multivariate_smooth_resampling.m | 6 +- src/mykmeans.m | 56 ++++++++--------- src/nonlinear_kalman_filter.m | 18 +++--- src/online_auxiliary_filter.m | 93 ++++++++++++++-------------- src/probability.m | 24 +++---- src/probability2.m | 12 ++-- src/probability3.m | 24 +++---- src/residual_resampling.m | 40 ++++++------ src/solve_model_for_online_filter.m | 54 ++++++++-------- src/spherical_radial_sigma_points.m | 10 +-- src/traditional_resampling.m | 2 +- src/univariate_smooth_resampling.m | 6 +- src/unscented_sigma_points.m | 16 +++-- 26 files changed, 317 insertions(+), 326 deletions(-) diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index 7034882b7..98f79aecb 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -87,7 +87,7 @@ yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); % yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); % [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); %else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); %end PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index a7934115c..42d57ca45 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -1,6 +1,6 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) -% Evaluates the likelihood of a nonlinear model with the auxiliary particle filter +% Evaluates the likelihood of a nonlinear model with the auxiliary particle filter % allowing eventually resampling. % % Copyright (C) 2011-2015 Dynare Team @@ -91,11 +91,11 @@ end % [nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); % else % error('Estimation: This approximation for the proposal is not implemented or unknown!') -% end +% end % nodes = (Q_lower_triangular_cholesky*(nodes'))' ; nodes = zeros(1,number_of_structural_innovations) ; -nodes_weights = ones(number_of_structural_innovations,1) ; +nodes_weights = ones(number_of_structural_innovations,1) ; for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); @@ -126,7 +126,7 @@ for t=1:sample_size yhat_ = yhat_(:,indx) ; end yhat = yhat(:,indx) ; - weights_stage_1 = weights(indx)./tau_tilde(indx) ; + weights_stage_1 = weights(indx)./tau_tilde(indx) ; epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); @@ -137,7 +137,7 @@ for t=1:sample_size StateVectors = tmp(mf0,:); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); weights_stage_2 = weights_stage_1.*(exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))) + 1e-99) ; - lik(t) = log(mean(weights_stage_2)) ; + lik(t) = log(mean(weights_stage_2)) ; weights = weights_stage_2/sum(weights_stage_2); if (ParticleOptions.resampling.status.generic && neff(weights)1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) ghx ghu ghxx @@ -106,7 +106,7 @@ if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_a Error = obs - PredictedObservedMean ; StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*Error ; if ParticleOptions.cpf_weights_method.amisanotristani - Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),PredictedObservedVarianceSquareRoot,Error) ; + Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),PredictedObservedVarianceSquareRoot,Error) ; end else dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); @@ -120,15 +120,15 @@ else StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVarianceSquareRoot = chol(StateVectorVariance + eye(number_of_state_variables)*1e-6)' ; if ParticleOptions.cpf_weights_method.amisanotristani - Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; + Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; end end PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + eye(number_of_state_variables)*1e-6)' ; ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; if ParticleOptions.cpf_weights_method.murrayjonesparslow - Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; - Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; - Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; + Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; + Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; + Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; Weights = SampleWeights.*Likelihood.*(Prior./Posterior) ; end diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 89c37b954..01437773e 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -1,24 +1,24 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) -% +% % Evaluates the likelihood of a non-linear model with a particle filter -% - the proposal is built using the Kalman updating step for each particle. -% - we need draws in the errors distributions -% Whether we use Monte-Carlo draws from a multivariate gaussian distribution -% as in Amisano & Tristani (JEDC 2010). -% Whether we use multidimensional Gaussian sparse grids approximations: -% - a univariate Kronrod-Paterson Gaussian quadrature combined by the Smolyak -% operator (ref: Winschel & Kratzig, 2010). +% - the proposal is built using the Kalman updating step for each particle. +% - we need draws in the errors distributions +% Whether we use Monte-Carlo draws from a multivariate gaussian distribution +% as in Amisano & Tristani (JEDC 2010). +% Whether we use multidimensional Gaussian sparse grids approximations: +% - a univariate Kronrod-Paterson Gaussian quadrature combined by the Smolyak +% operator (ref: Winschel & Kratzig, 2010). % - a spherical-radial cubature (ref: Arasaratnam & Haykin, 2009a,2009b). -% - a scaled unscented transform cubature (ref: Julier & Uhlmann 1997, van der +% - a scaled unscented transform cubature (ref: Julier & Uhlmann 1997, van der % Merwe & Wan 2003). -% -% Pros: -% - Allows using current observable information in the proposal -% - The use of sparse grids Gaussian approximation is much faster than the Monte-Carlo approach -% Cons: -% - The use of the Kalman updating step may biais the proposal distribution since +% +% Pros: +% - Allows using current observable information in the proposal +% - The use of sparse grids Gaussian approximation is much faster than the Monte-Carlo approach +% Cons: +% - The use of the Kalman updating step may biais the proposal distribution since % it has been derived in a linear context and is implemented in a nonlinear -% context. That is why particle resampling is performed. +% context. That is why particle resampling is performed. % % INPUTS % reduced_form_model [structure] Matlab's structure describing the reduced form model. @@ -58,8 +58,8 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOpt % stephane DOT adjemian AT univ DASH lemans DOT fr persistent init_flag mf1 -persistent number_of_particles -persistent sample_size number_of_observed_variables +persistent number_of_particles +persistent sample_size number_of_observed_variables % Set default if isempty(start) @@ -82,14 +82,14 @@ if isempty(H) H = 0; H_lower_triangular_cholesky = 0; else - H_lower_triangular_cholesky = chol(H)'; + H_lower_triangular_cholesky = chol(H)'; end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); -Q_lower_triangular_cholesky = chol(Q)'; +Q_lower_triangular_cholesky = chol(Q)'; % Set seed for randn(). set_dynare_seed('default'); @@ -102,13 +102,13 @@ ks = 0 ; StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); SampleWeights = ones(1,number_of_particles)/number_of_particles ; for t=1:sample_size - for i=1:number_of_particles - [StateParticles(:,i),SampleWeights(i)] = ... - conditional_filter_proposal(ReducedForm,Y(:,t),StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) ; + for i=1:number_of_particles + [StateParticles(:,i),SampleWeights(i)] = ... + conditional_filter_proposal(ReducedForm,Y(:,t),StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) ; end SumSampleWeights = sum(SampleWeights) ; - lik(t) = log(SumSampleWeights) ; - SampleWeights = SampleWeights./SumSampleWeights ; + lik(t) = log(SumSampleWeights) ; + SampleWeights = SampleWeights./SumSampleWeights ; if (ParticleOptions.resampling.status.generic && neff(SampleWeights). -[dim,Ndata] = size(X); +[dim,Ndata] = size(X); M = size(StateMu,2) ; if check % Ensure that covariances don't collapse - MIN_COVAR_SQRT = sqrt(eps); - init_covars = StateSqrtP; + MIN_COVAR_SQRT = sqrt(eps); + init_covars = StateSqrtP; end eold = -Inf; for n=1:niters - % Calculate posteriors based on old parameters - [prior,likelihood,marginal,posterior] = probability3(StateMu,StateSqrtP,StateWeights,X,X_weights); - e = sum(log(marginal)); - if (n > 1 && abs((e - eold)/eold) < crit) - return; - else - eold = e; - end - new_pr = (sum(posterior,2))'; - StateWeights = new_pr/Ndata; - StateMu = bsxfun(@rdivide,(posterior*X')',new_pr); - for j=1:M - diffs = bsxfun(@minus,X,StateMu(:,j)); - tpost = (1/sqrt(new_pr(j)))*sqrt(posterior(j,:)); - diffs = bsxfun(@times,diffs,tpost); - [foo,tcov] = qr2(diffs',0); - StateSqrtP(:,:,j) = tcov'; - if check - if min(abs(diag(StateSqrtP(:,:,j)))) < MIN_COVAR_SQRT - StateSqrtP(:,:,j) = init_covars(:,:,j); - end + % Calculate posteriors based on old parameters + [prior,likelihood,marginal,posterior] = probability3(StateMu,StateSqrtP,StateWeights,X,X_weights); + e = sum(log(marginal)); + if (n > 1 && abs((e - eold)/eold) < crit) + return; + else + eold = e; end - end -end - + new_pr = (sum(posterior,2))'; + StateWeights = new_pr/Ndata; + StateMu = bsxfun(@rdivide,(posterior*X')',new_pr); + for j=1:M + diffs = bsxfun(@minus,X,StateMu(:,j)); + tpost = (1/sqrt(new_pr(j)))*sqrt(posterior(j,:)); + diffs = bsxfun(@times,diffs,tpost); + [foo,tcov] = qr2(diffs',0); + StateSqrtP(:,:,j) = tcov'; + if check + if min(abs(diag(StateSqrtP(:,:,j)))) < MIN_COVAR_SQRT + StateSqrtP(:,:,j) = init_covars(:,:,j); + end + end + end +end diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index ae3afb130..2246e45e1 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -1,6 +1,6 @@ function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) % -% Elements to calculate the importance sampling ratio +% Elements to calculate the importance sampling ratio % % INPUTS % reduced_form_model [structure] Matlab's structure describing the reduced form model. @@ -36,11 +36,11 @@ function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sq % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% proposal density -proposal = probability2(mut_t,sqr_Pss_t_t,particles) ; -% prior density -prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; -% likelihood +% proposal density +proposal = probability2(mut_t,sqr_Pss_t_t,particles) ; +% prior density +prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; +% likelihood yt_t_1_i = measurement_equations(particles,ReducedForm,ThreadsOptions) ; eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; yt_t_1 = sum(yt_t_1_i*weigths1,2) ; @@ -48,5 +48,5 @@ tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; sqr_det = sqrt(det(Pyy)) ; foo = (eta_t_i/Pyy).*eta_t_i ; -likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; IncrementalWeights = likelihood.*prior./proposal ; diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index 2cee18ee7..d7e82df1b 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -112,18 +112,18 @@ for t=1:sample_size if ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented StateParticles = bsxfun(@plus,StateVectorMean,StateVectorVarianceSquareRoot*nodes2') ; IncrementalWeights = ... - gaussian_densities(Y(:,t),StateVectorMean,... - StateVectorVarianceSquareRoot,PredictedStateMean,... - PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - weights2,weights_c2,ReducedForm,ThreadsOptions) ; + gaussian_densities(Y(:,t),StateVectorMean,... + StateVectorVarianceSquareRoot,PredictedStateMean,... + PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... + weights2,weights_c2,ReducedForm,ThreadsOptions) ; SampleWeights = weights2.*IncrementalWeights ; - else + else StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean) ; IncrementalWeights = ... - gaussian_densities(Y(:,t),StateVectorMean,... - StateVectorVarianceSquareRoot,PredictedStateMean,... - PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; + gaussian_densities(Y(:,t),StateVectorMean,... + StateVectorVarianceSquareRoot,PredictedStateMean,... + PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... + 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; SampleWeights = IncrementalWeights/number_of_particles ; end SampleWeights = SampleWeights + 1e-6*ones(size(SampleWeights,1),1) ; @@ -132,9 +132,9 @@ for t=1:sample_size SampleWeights = SampleWeights./SumSampleWeights ; if not(ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented) if (ParticleOptions.resampling.status.generic && neff(SampleWeights)1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) ghx ghu ghxx diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m index 06c3eec1e..7efe1ce01 100644 --- a/src/gaussian_mixture_densities.m +++ b/src/gaussian_mixture_densities.m @@ -1,8 +1,8 @@ function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... - StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) + StateMuPost,StateSqrtPPost,StateWeightsPost,... + StateParticles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) % -% Elements to calculate the importance sampling ratio +% Elements to calculate the importance sampling ratio % % INPUTS % reduced_form_model [structure] Matlab's structure describing the reduced form model. @@ -38,11 +38,11 @@ function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,State % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% Compute the density of particles under the prior distribution -[ras,ras,prior] = probability(StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateParticles) ; +% Compute the density of particles under the prior distribution +[ras,ras,prior] = probability(StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateParticles) ; prior = prior' ; -% Compute the density of particles under the proposal distribution -[ras,ras,proposal] = probability(StateMuPost,StateSqrtPPost,StateWeightsPost,StateParticles) ; +% Compute the density of particles under the proposal distribution +[ras,ras,proposal] = probability(StateMuPost,StateSqrtPPost,StateWeightsPost,StateParticles) ; proposal = proposal' ; % Compute the density of the current observation conditionally to each particle yt_t_1_i = measurement_equations(StateParticles,ReducedForm,ThreadsOptions) ; @@ -52,6 +52,5 @@ tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; sqr_det = sqrt(det(Pyy)) ; foo = (eta_t_i/Pyy).*eta_t_i ; -likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; IncrementalWeights = likelihood.*prior./proposal ; - diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index 0dc257c8c..eaab0070f 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -63,15 +63,15 @@ end % Set persistent variables. if isempty(init_flag) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - sample_size = size(Y,2); - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - G = ParticleOptions.mixture_state_variables; % number of GM components in state - number_of_particles = ParticleOptions.number_of_particles; - init_flag = 1; + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + sample_size = size(Y,2); + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + G = ParticleOptions.mixture_state_variables; % number of GM components in state + number_of_particles = ParticleOptions.number_of_particles; + init_flag = 1; end % compute gaussian quadrature nodes and weights on states and shocks @@ -104,14 +104,14 @@ else end Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; -% Initialize mixtures +% Initialize mixtures StateWeights = ones(1,G)/G ; StateMu = ReducedForm.StateVectorMean ; StateSqrtP = zeros(number_of_state_variables,number_of_state_variables,G) ; temp = reduced_rank_cholesky(ReducedForm.StateVectorVariance)' ; StateMu = bsxfun(@plus,StateMu,bsxfun(@times,diag(temp),(-(G-1)/2:1:(G-1)/2))/10) ; for g=1:G - StateSqrtP(:,:,g) = temp/sqrt(G) ; + StateSqrtP(:,:,g) = temp/sqrt(G) ; end % if ParticleOptions.mixture_structural_shocks==1 @@ -135,11 +135,11 @@ end % for i=1:I % StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; % end -% -% if ParticleOptions.mixture_measurement_shocks==1 +% +% if ParticleOptions.mixture_measurement_shocks==1 % ObservationShocksMu = zeros(1,number_of_observed_variables) ; % ObservationShocksWeights = 1 ; -% else +% else % if ParticleOptions.proposal_approximation.cubature % [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); % ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; @@ -150,7 +150,7 @@ end % error('Estimation: This approximation for the proposal is not implemented or unknown!') % end % end -% end +% end % J = size(ObservationShocksWeights,1) ; % ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; % ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; @@ -180,7 +180,7 @@ elseif ParticleOptions.mixture_structural_shocks==1 StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; for i=1:I - StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky ; + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky ; end else if ParticleOptions.proposal_approximation.cubature @@ -197,7 +197,7 @@ else StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; for i=1:I - StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; end end @@ -208,14 +208,14 @@ ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; ObservationShocksSqrtP(:,:,1) = H_lower_triangular_cholesky ; -% if ParticleOptions.mixture_measurement_shocks==0 +% if ParticleOptions.mixture_measurement_shocks==0 % ObservationShocksMu = zeros(1,number_of_observed_variables) ; % ObservationShocksWeights = 1 ; % J = 1 ; % ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; % ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; % ObservationShocksSqrtP(:,:,1) = H_lower_triangular_cholesky ; -% elseif ParticleOptions.mixture_measurement_shocks==1 +% elseif ParticleOptions.mixture_measurement_shocks==1 % if ParticleOptions.proposal_approximation.cubature % [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); % ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; @@ -232,7 +232,7 @@ ObservationShocksSqrtP(:,:,1) = H_lower_triangular_cholesky ; % for j=1:J % ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky ; % end -% else +% else % if ParticleOptions.proposal_approximation.cubature % [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); % ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; @@ -277,10 +277,10 @@ for t=1:sample_size gsecond = gprime + (j-1)*Gprime ; [StateMuPrior(:,gprime),StateSqrtPPrior(:,:,gprime),StateWeightsPrior(1,gprime),... StateMuPost(:,gsecond),StateSqrtPPost(:,:,gsecond),StateWeightsPost(1,gsecond)] =... - gaussian_mixture_filter_bank(ReducedForm,Y(:,t),StateMu(:,g),StateSqrtP(:,:,g),StateWeights(g),... - StructuralShocksMu(:,i),StructuralShocksSqrtP(:,:,i),StructuralShocksWeights(i),... - ObservationShocksMu(:,j),ObservationShocksSqrtP(:,:,j),ObservationShocksWeights(j),... - H,H_lower_triangular_cholesky,const_lik,ParticleOptions,ThreadsOptions) ; + gaussian_mixture_filter_bank(ReducedForm,Y(:,t),StateMu(:,g),StateSqrtP(:,:,g),StateWeights(g),... + StructuralShocksMu(:,i),StructuralShocksSqrtP(:,:,i),StructuralShocksWeights(i),... + ObservationShocksMu(:,j),ObservationShocksSqrtP(:,:,j),ObservationShocksWeights(j),... + H,H_lower_triangular_cholesky,const_lik,ParticleOptions,ThreadsOptions) ; end end end @@ -293,8 +293,8 @@ for t=1:sample_size for i=1:Gsecond StateParticles = bsxfun(@plus,StateMuPost(:,i),StateSqrtPPost(:,:,i)*nodes') ; IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... - StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,weights,weights_c,ReducedForm,ThreadsOptions) ; + StateMuPost,StateSqrtPPost,StateWeightsPost,... + StateParticles,H,const_lik,weights,weights_c,ReducedForm,ThreadsOptions) ; SampleWeights(i) = sum(StateWeightsPost(i)*weights.*IncrementalWeights) ; end SumSampleWeights = sum(SampleWeights) ; @@ -311,9 +311,9 @@ for t=1:sample_size % Sample particle in the proposal distribution, ie the posterior state GM StateParticles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost',number_of_particles) ; IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... - StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,1/number_of_particles,... - 1/number_of_particles,ReducedForm,ThreadsOptions) ; + StateMuPost,StateSqrtPPost,StateWeightsPost,... + StateParticles,H,const_lik,1/number_of_particles,... + 1/number_of_particles,ReducedForm,ThreadsOptions) ; SampleWeights = IncrementalWeights/number_of_particles ; SumSampleWeights = sum(SampleWeights,1) ; SampleWeights = SampleWeights./SumSampleWeights ; diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index 5bcf702cb..017192712 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -1,12 +1,12 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPPost,StateWeightsPost] =... - gaussian_mixture_filter_bank(ReducedForm,obs,StateMu,StateSqrtP,StateWeights,... - StructuralShocksMu,StructuralShocksSqrtP,StructuralShocksWeights,... - ObservationShocksMu,ObservationShocksSqrtP,ObservationShocksWeights,... - H,H_lower_triangular_cholesky,normfactO,ParticleOptions,ThreadsOptions) + gaussian_mixture_filter_bank(ReducedForm,obs,StateMu,StateSqrtP,StateWeights,... + StructuralShocksMu,StructuralShocksSqrtP,StructuralShocksWeights,... + ObservationShocksMu,ObservationShocksSqrtP,ObservationShocksWeights,... + H,H_lower_triangular_cholesky,normfactO,ParticleOptions,ThreadsOptions) % % Computes the proposal with a gaussian approximation for importance -% sampling -% This proposal is a gaussian distribution calculated à la Kalman +% sampling +% This proposal is a gaussian distribution calculated à la Kalman % % INPUTS % reduced_form_model [structure] Matlab's structure describing the reduced form model. @@ -43,8 +43,8 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP persistent init_flag2 mf0 mf1 %nodes3 weights3 weights_c3 -persistent number_of_state_variables number_of_observed_variables -persistent number_of_structural_innovations +persistent number_of_state_variables number_of_observed_variables +persistent number_of_structural_innovations % Set local state space model (first-order approximation). ghx = ReducedForm.ghx; @@ -55,8 +55,8 @@ ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... - any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... - any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) ghx ghu ghxx diff --git a/src/importance_sampling.m b/src/importance_sampling.m index 403b6beb3..b4a6daf4a 100644 --- a/src/importance_sampling.m +++ b/src/importance_sampling.m @@ -17,13 +17,12 @@ function State_Particles = importance_sampling(StateMuPost,StateSqrtPPost,StateW % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -[Xdim,Gsecond] = size(StateMuPost) ; +[Xdim,Gsecond] = size(StateMuPost) ; u = rand(numP,1); -[Nc,comp] = histc(u, cumsum([0; StateWeightsPost])); +[Nc,comp] = histc(u, cumsum([0; StateWeightsPost])); State_Particles = zeros(Xdim,numP); for k=1:Gsecond - idx = bsxfun(@eq,comp,k*ones(size(comp))) ; - State_Particles(:,idx) = StateSqrtPPost(:,:,k)*randn(Xdim,Nc(k)); + idx = bsxfun(@eq,comp,k*ones(size(comp))) ; + State_Particles(:,idx) = StateSqrtPPost(:,:,k)*randn(Xdim,Nc(k)); end -State_Particles= State_Particles + StateMuPost(:,comp); - +State_Particles= State_Particles + StateMuPost(:,comp); diff --git a/src/measurement_equations.m b/src/measurement_equations.m index d38c59aea..7cf4d9320 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -1,4 +1,4 @@ -function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions) +function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions) % Copyright (C) 2013 Dynare Team % @@ -28,6 +28,3 @@ state_variables_steady_state = ReducedForm.state_variables_steady_state; number_of_structural_innovations = length(ReducedForm.Q); yhat = bsxfun(@minus,StateVectors,state_variables_steady_state) ; measure = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,size(yhat,2)),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); - - - diff --git a/src/multivariate_smooth_resampling.m b/src/multivariate_smooth_resampling.m index 09ca287b9..e62111cc1 100644 --- a/src/multivariate_smooth_resampling.m +++ b/src/multivariate_smooth_resampling.m @@ -63,10 +63,10 @@ number_of_states = size(particles,2); [P,D] = eig(particles'*(bsxfun(@times,1/number_of_particles,particles))) ; D = diag(D) ; vectors = bsxfun(@times,P,sqrt(D)') ; -orthogonalized_particles = bsxfun(@rdivide,particles*vectors,D') ; +orthogonalized_particles = bsxfun(@rdivide,particles*vectors,D') ; new_particles = zeros(number_of_particles,number_of_states) ; for j=1:number_of_states - tout = sortrows( [orthogonalized_particles(:,j) weights],1) ; - new_particles(:,j) = univariate_smooth_resampling(tout(:,2),tout(:,1),number_of_particles) ; + tout = sortrows( [orthogonalized_particles(:,j) weights],1) ; + new_particles(:,j) = univariate_smooth_resampling(tout(:,2),tout(:,1),number_of_particles) ; end new_particles = new_particles*(vectors') ; diff --git a/src/mykmeans.m b/src/mykmeans.m index 56af5390b..4506aca25 100644 --- a/src/mykmeans.m +++ b/src/mykmeans.m @@ -1,4 +1,4 @@ -function [c,SqrtVariance,Weights] = mykmeans(x,g,init,cod) +function [c,SqrtVariance,Weights] = mykmeans(x,g,init,cod) % Copyright (C) 2013 Dynare Team % @@ -20,34 +20,34 @@ function [c,SqrtVariance,Weights] = mykmeans(x,g,init,cod) [n,m] = size(x) ; indold = zeros(1,m) ; if cod==0 - d = transpose(sum(bsxfun(@power,bsxfun(@minus,x,mean(x)),2))); - d = sortrows( [transpose(1:m) d],2) ; - d = d((1+(0:1:g-1))*m/g,1) ; - c = x(:,d); + d = transpose(sum(bsxfun(@power,bsxfun(@minus,x,mean(x)),2))); + d = sortrows( [transpose(1:m) d],2) ; + d = d((1+(0:1:g-1))*m/g,1) ; + c = x(:,d); else - c = init ; -end -for iter=1:300 - dist = zeros(g,m) ; - for i=1:g - dist(i,:) = sum(bsxfun(@power,bsxfun(@minus,x,c(:,i)),2)); - end - [rien,ind] = min(dist) ; - if isequal(ind,indold) - break ; - end - indold = ind ; - for i=1:g - lin = bsxfun(@eq,ind,i.*ones(1,m)) ; - h = x(:,lin) ; - c(:,i) = mean(h,2) ; - end + c = init ; end -SqrtVariance = zeros(n,n,g) ; -Weights = zeros(1,g) ; +for iter=1:300 + dist = zeros(g,m) ; + for i=1:g + dist(i,:) = sum(bsxfun(@power,bsxfun(@minus,x,c(:,i)),2)); + end + [rien,ind] = min(dist) ; + if isequal(ind,indold) + break ; + end + indold = ind ; + for i=1:g + lin = bsxfun(@eq,ind,i.*ones(1,m)) ; + h = x(:,lin) ; + c(:,i) = mean(h,2) ; + end +end +SqrtVariance = zeros(n,n,g) ; +Weights = zeros(1,g) ; for i=1:g - temp = x(:,bsxfun(@eq,ind,i*ones(1,m))) ; - u = bsxfun(@minus,temp,mean(temp,2)); %temp-mean(temp,1)' ; - SqrtVariance(:,:,i) = chol( (u*u')/size(temp,2) )' ; - Weights(i) = size(temp,2)/m ; + temp = x(:,bsxfun(@eq,ind,i*ones(1,m))) ; + u = bsxfun(@minus,temp,mean(temp,2)); %temp-mean(temp,1)' ; + SqrtVariance(:,:,i) = chol( (u*u')/size(temp,2) )' ; + Weights(i) = size(temp,2)/m ; end diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index dd61a5e50..608fbacec 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -10,9 +10,9 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % from the resulting nodes/particles and allows to generate new distributions at the % following observation. % Pros: The use of nodes is much faster than Monte-Carlo Gaussian particle and standard particles -% filters since it treats a lesser number of particles. -% Cons: 1. Application a linear projection formulae in a nonlinear context. -% 2. Parameter estimations may be biaised if the model is truly non-gaussian since predictive and +% filters since it treats a lesser number of particles. +% Cons: 1. Application a linear projection formulae in a nonlinear context. +% 2. Parameter estimations may be biaised if the model is truly non-gaussian since predictive and % filtered densities are unimodal. % % INPUTS @@ -47,7 +47,7 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -persistent init_flag mf0 mf1 nodes weights weights_c +persistent init_flag mf0 mf1 nodes weights weights_c persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations % Set default @@ -64,8 +64,8 @@ ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... - any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... - any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) ghx ghu ghxx @@ -100,12 +100,12 @@ end if ParticleOptions.distribution_approximation.montecarlo set_dynare_seed('default'); -end +end % Get covariance matrices H = ReducedForm.H; -H_lower_triangular_cholesky = chol(H)' ; -Q_lower_triangular_cholesky = chol(ReducedForm.Q)'; +H_lower_triangular_cholesky = chol(H)' ; +Q_lower_triangular_cholesky = chol(ReducedForm.Q)'; % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 8018ca69c..a14548559 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -1,5 +1,5 @@ function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(xparam1,DynareDataset,dataset_info,DynareOptions,Model,EstimatedParameters,BayesInfo,bounds,DynareResults) - + % Liu & West particle filter = auxiliary particle filter including Liu & West filter on parameters. % % INPUTS @@ -47,8 +47,8 @@ second_resample = 0 ; variance_update = 1 ; % initialization of state particles -[ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... - solve_model_for_online_filter(1,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; +[ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... + solve_model_for_online_filter(1,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; % Set persistent variables. if isempty(init_flag) @@ -61,11 +61,11 @@ if isempty(init_flag) number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); liu_west_delta = DynareOptions.particle.liu_west_delta ; - start_param = xparam1 ; + start_param = xparam1 ; init_flag = 1; end -% Get initial conditions for the state particles +% Get initial conditions for the state particles StateVectorMean = ReducedForm.StateVectorMean; StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); @@ -73,13 +73,13 @@ StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_r if pruning StateVectors_ = StateVectors; end - -% parameters for the Liu & West filter + +% parameters for the Liu & West filter h_square = (3*liu_west_delta-1)/(2*liu_west_delta) ; h_square = 1-h_square*h_square ; small_a = sqrt(1-h_square) ; -% Initialization of parameter particles +% Initialization of parameter particles xparam = zeros(number_of_parameters,number_of_particles) ; stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/100 ; stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/50 ; @@ -107,14 +107,14 @@ std_xparam = zeros(number_of_parameters,sample_size) ; lb95_xparam = zeros(number_of_parameters,sample_size) ; ub95_xparam = zeros(number_of_parameters,sample_size) ; -%% The Online filter +%% The Online filter for t=1:sample_size if t>1 fprintf('\nSubsample with %s first observations.\n\n', int2str(t)) else fprintf('\nSubsample with only the first observation.\n\n', int2str(t)) end - % Moments of parameters particles distribution + % Moments of parameters particles distribution m_bar = xparam*(weights') ; temp = bsxfun(@minus,xparam,m_bar) ; sigma_bar = (bsxfun(@times,weights,temp))*(temp') ; @@ -124,8 +124,8 @@ for t=1:sample_size % Prediction (without shocks) tau_tilde = zeros(1,number_of_particles) ; for i=1:number_of_particles - % model resolution - [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... + % model resolution + [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... solve_model_for_online_filter(t,xparam(:,i),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; @@ -136,7 +136,7 @@ for t=1:sample_size ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; - % particle likelihood contribution + % particle likelihood contribution yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); if pruning yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); @@ -151,7 +151,7 @@ for t=1:sample_size tau_tilde(i) = weights(i).*(tpdf(z,3*ones(size(z)))+1e-99) ; %tau_tilde(i) = weights(i).*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))) ; end - % particles selection + % particles selection tau_tilde = tau_tilde/sum(tau_tilde) ; indx = resample(0,tau_tilde',DynareOptions.particle); StateVectors = StateVectors(:,indx) ; @@ -160,7 +160,7 @@ for t=1:sample_size end xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam(:,indx)) ; w_stage1 = weights(indx)./tau_tilde(indx) ; - % draw in the new distributions + % draw in the new distributions wtilde = zeros(1,number_of_particles) ; i = 1 ; while i<=number_of_particles @@ -179,9 +179,9 @@ for t=1:sample_size ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; - % Get covariance matrices and structural shocks + % Get covariance matrices and structural shocks epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations,1) ; - % compute particles likelihood contribution + % compute particles likelihood contribution yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); if pruning yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); @@ -196,13 +196,13 @@ for t=1:sample_size i = i+1 ; end end - % normalization + % normalization weights = wtilde/sum(wtilde); if (variance_update==1) && (neff(weights)=0.025 && pass1==1 - lb95_xparam(i,t) = temp(j,1) ; - pass1 = 2 ; - end - if cumulated_weights(j)>=0.5 && pass2==1 - median_xparam(i,t) = temp(j,1) ; - pass2 = 2 ; - end - if cumulated_weights(j)>=0.975 && pass3==1 - ub95_xparam(i,t) = temp(j,1) ; - pass3 = 2 ; - end - end + temp = sortrows([xparam(i,:)' weights'],1) ; + cumulated_weights = cumsum(temp(:,2)) ; + pass1=1 ; + pass2=1 ; + pass3=1 ; + for j=1:number_of_particles + if cumulated_weights(j)>=0.025 && pass1==1 + lb95_xparam(i,t) = temp(j,1) ; + pass1 = 2 ; + end + if cumulated_weights(j)>=0.5 && pass2==1 + median_xparam(i,t) = temp(j,1) ; + pass2 = 2 ; + end + if cumulated_weights(j)>=0.975 && pass3==1 + ub95_xparam(i,t) = temp(j,1) ; + pass3 = 2 ; + end + end end end str = sprintf(' Lower Bound (95%%) \t Mean \t\t\t Upper Bound (95%%)'); @@ -262,7 +262,7 @@ lb_95 = lb95_xparam(:,sample_size) ; ub_95 = ub95_xparam(:,sample_size) ; median_param = median_xparam(:,sample_size) ; -%% Plot parameters trajectory +%% Plot parameters trajectory TeX = DynareOptions.TeX; [nbplt,nr,nc,lr,lc,nstar] = pltorg(number_of_parameters); @@ -322,7 +322,7 @@ end %% Plot Parameter Densities number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. bandwidth = 0; % Rule of thumb optimal bandwidth parameter. -kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. +kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. for plt = 1:nbplt, if TeX NAMES = []; @@ -366,5 +366,4 @@ for plt = 1:nbplt, fprintf(fidTeX,'\\end{figure}\n'); fprintf(fidTeX,' \n'); end -end - +end diff --git a/src/probability.m b/src/probability.m index 5d76e49ee..94f09b9cb 100644 --- a/src/probability.m +++ b/src/probability.m @@ -17,23 +17,23 @@ function [prior,likelihood,C,posterior] = probability(mu,sqrtP,prior,X) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -[dim,nov] = size(X); +[dim,nov] = size(X); M = size(mu,2) ; if nargout>1 - likelihood = zeros(M,nov); - normfact = (2*pi)^(dim/2); - for k=1:M - XX = bsxfun(@minus,X,mu(:,k)); - S = sqrtP(:,:,k); - foo = S \ XX; - likelihood(k,:) = exp(-0.5*sum(foo.*foo, 1))/abs((normfact*prod(diag(S)))); - end + likelihood = zeros(M,nov); + normfact = (2*pi)^(dim/2); + for k=1:M + XX = bsxfun(@minus,X,mu(:,k)); + S = sqrtP(:,:,k); + foo = S \ XX; + likelihood(k,:) = exp(-0.5*sum(foo.*foo, 1))/abs((normfact*prod(diag(S)))); + end end likelihood = likelihood + 1e-99; if nargout>2 - C = prior*likelihood + 1e-99; + C = prior*likelihood + 1e-99; end if nargout>3 - posterior = bsxfun(@rdivide,bsxfun(@times,prior',likelihood),C) + 1e-99 ; - posterior = bsxfun(@rdivide,posterior,sum(posterior,1)); + posterior = bsxfun(@rdivide,bsxfun(@times,prior',likelihood),C) + 1e-99 ; + posterior = bsxfun(@rdivide,posterior,sum(posterior,1)); end diff --git a/src/probability2.m b/src/probability2.m index a7486d1b8..dfc71ff24 100644 --- a/src/probability2.m +++ b/src/probability2.m @@ -1,7 +1,7 @@ -function [density] = probability2(mu,S,X) +function [density] = probability2(mu,S,X) % % Multivariate gaussian density -% +% % INPUTS % n [integer] scalar, number of variables. % @@ -10,10 +10,10 @@ function [density] = probability2(mu,S,X) % weigths [double] associated weigths % % REFERENCES -% +% % % NOTES -% +% % Copyright (C) 2009-2012 Dynare Team % % This file is part of Dynare. @@ -31,7 +31,7 @@ function [density] = probability2(mu,S,X) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -dim = size(X,1) ; -normfact = bsxfun(@power,(2*pi),(dim/2)) ; +dim = size(X,1) ; +normfact = bsxfun(@power,(2*pi),(dim/2)) ; foo = S\(bsxfun(@minus,X,mu)) ; density = exp(-0.5*sum(foo.*foo)')./abs((normfact*prod(diag(S)))) + 1e-99 ; \ No newline at end of file diff --git a/src/probability3.m b/src/probability3.m index 49a14b429..5e2a9b4a8 100644 --- a/src/probability3.m +++ b/src/probability3.m @@ -17,23 +17,23 @@ function [prior,likelihood,C,posterior] = probability3(mu,sqrtP,prior,X,X_weight % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -[dim,nov] = size(X); +[dim,nov] = size(X); M = size(mu,2) ; if nargout>1 - likelihood = zeros(M,nov); - normfact = (2*pi)^(dim/2); - for k=1:M - XX = bsxfun(@minus,X,mu(:,k)); - S = sqrtP(:,:,k); - foo = S \ XX; - likelihood(k,:) = exp(-0.5*sum(foo.*foo, 1))/abs((normfact*prod(diag(S)))); - end + likelihood = zeros(M,nov); + normfact = (2*pi)^(dim/2); + for k=1:M + XX = bsxfun(@minus,X,mu(:,k)); + S = sqrtP(:,:,k); + foo = S \ XX; + likelihood(k,:) = exp(-0.5*sum(foo.*foo, 1))/abs((normfact*prod(diag(S)))); + end end wlikelihood = bsxfun(@times,X_weights,likelihood) + 1e-99; if nargout>2 - C = prior*wlikelihood + 1e-99; + C = prior*wlikelihood + 1e-99; end if nargout>3 - posterior = bsxfun(@rdivide,bsxfun(@times,prior',wlikelihood),C) + 1e-99 ; - posterior = bsxfun(@rdivide,posterior,sum(posterior,1)); + posterior = bsxfun(@rdivide,bsxfun(@times,prior',wlikelihood),C) + 1e-99 ; + posterior = bsxfun(@rdivide,posterior,sum(posterior,1)); end diff --git a/src/residual_resampling.m b/src/residual_resampling.m index c2f09e3b8..9a7d8cce8 100644 --- a/src/residual_resampling.m +++ b/src/residual_resampling.m @@ -76,33 +76,33 @@ iWEIGHTS = fix(WEIGHTS); number_of_trials = number_of_particles-sum(iWEIGHTS); if number_of_trials - WEIGHTS = (WEIGHTS-iWEIGHTS)/number_of_trials; - EmpiricalCDF = cumsum(WEIGHTS); - if kitagawa_resampling - u = (transpose(1:number_of_trials)-1+noise(:))/number_of_trials; - else - u = fliplr(cumprod(noise(1:number_of_trials).^(1./(number_of_trials:-1:1)))); - end - j=1; - for i=1:number_of_trials - while (u(i)>EmpiricalCDF(j)) - j=j+1; + WEIGHTS = (WEIGHTS-iWEIGHTS)/number_of_trials; + EmpiricalCDF = cumsum(WEIGHTS); + if kitagawa_resampling + u = (transpose(1:number_of_trials)-1+noise(:))/number_of_trials; + else + u = fliplr(cumprod(noise(1:number_of_trials).^(1./(number_of_trials:-1:1)))); end - iWEIGHTS(j)=iWEIGHTS(j)+1; - if kitagawa_resampling==0 - j=1; + j=1; + for i=1:number_of_trials + while (u(i)>EmpiricalCDF(j)) + j=j+1; + end + iWEIGHTS(j)=iWEIGHTS(j)+1; + if kitagawa_resampling==0 + j=1; + end end - end end k=1; for i=1:number_of_particles - if (iWEIGHTS(i)>0) - for j=k:k+iWEIGHTS(i)-1 - indx(j) = jndx(i); + if (iWEIGHTS(i)>0) + for j=k:k+iWEIGHTS(i)-1 + indx(j) = jndx(i); + end end - end - k = k + iWEIGHTS(i); + k = k + iWEIGHTS(i); end if particles==0 diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 62ed99cb5..1ea2e67a4 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -185,18 +185,18 @@ if EstimatedParameters.ncx Q(k2,k1) = Q(k1,k2); end % Try to compute the cholesky decomposition of Q (possible iff Q is positive definite) -% [CholQ,testQ] = chol(Q); -% if testQ - % The variance-covariance matrix of the structural innovations is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. -% a = diag(eig(Q)); -% k = find(a < 0); -% if k > 0 -% fval = objective_function_penalty_base+sum(-a(k)); -% exit_flag = 0; -% info = 43; -% return -% end -% end + % [CholQ,testQ] = chol(Q); + % if testQ + % The variance-covariance matrix of the structural innovations is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. + % a = diag(eig(Q)); + % k = find(a < 0); + % if k > 0 + % fval = objective_function_penalty_base+sum(-a(k)); + % exit_flag = 0; + % info = 43; + % return + % end + % end offset = offset+EstimatedParameters.ncx; end @@ -210,18 +210,18 @@ if EstimatedParameters.ncn H(k2,k1) = H(k1,k2); end % Try to compute the cholesky decomposition of H (possible iff H is positive definite) -% [CholH,testH] = chol(H); -% if testH - % The variance-covariance matrix of the measurement errors is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. -% a = diag(eig(H)); -% k = find(a < 0); -% if k > 0 -% fval = objective_function_penalty_base+sum(-a(k)); -% exit_flag = 0; -% info = 44; -% return -% end -% end + % [CholH,testH] = chol(H); + % if testH + % The variance-covariance matrix of the measurement errors is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. + % a = diag(eig(H)); + % k = find(a < 0); + % if k > 0 + % fval = objective_function_penalty_base+sum(-a(k)); + % exit_flag = 0; + % info = 44; + % return + % end + % end offset = offset+EstimatedParameters.ncn; end @@ -244,7 +244,7 @@ Model.H = H; %disp(info) if info(1) ~= 0 - ReducedForm = 0 ; + ReducedForm = 0 ; exit_flag = 55; return end @@ -312,7 +312,7 @@ if DynareOptions.order>1 ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); -else +else ReducedForm.ghxx = zeros(size(restrict_variables_idx,1),size(dr.kstate,2)); ReducedForm.ghuu = zeros(size(restrict_variables_idx,1),size(dr.ghu,2)); ReducedForm.ghxu = zeros(size(restrict_variables_idx,1),size(dr.ghx,2)); @@ -325,7 +325,7 @@ ReducedForm.mf0 = mf0; ReducedForm.mf1 = mf1; % Set initial condition for t=1 -if observation_number==1 +if observation_number==1 switch DynareOptions.particle.initialization case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. StateVectorMean = ReducedForm.constant(mf0); diff --git a/src/spherical_radial_sigma_points.m b/src/spherical_radial_sigma_points.m index 754caacfa..db71f6119 100644 --- a/src/spherical_radial_sigma_points.m +++ b/src/spherical_radial_sigma_points.m @@ -1,7 +1,7 @@ -function [nodes,weights] = spherical_radial_sigma_points(n) +function [nodes,weights] = spherical_radial_sigma_points(n) % -% Computes nodes and weigths from a third-degree spherical-radial cubature -% rule. +% Computes nodes and weigths from a third-degree spherical-radial cubature +% rule. % INPUTS % n [integer] scalar, number of variables. % @@ -11,10 +11,10 @@ function [nodes,weights] = spherical_radial_sigma_points(n) % % REFERENCES % -% Arasaratnam & Haykin 2008,2009. +% Arasaratnam & Haykin 2008,2009. % % NOTES -% +% % Copyright (C) 2009-2012 Dynare Team % % This file is part of Dynare. diff --git a/src/traditional_resampling.m b/src/traditional_resampling.m index a9d86eb36..87f550368 100644 --- a/src/traditional_resampling.m +++ b/src/traditional_resampling.m @@ -75,7 +75,7 @@ c = cumsum(weights); % Draw a starting point. if kitagawa_resampling randvec = (transpose(1:number_of_particles)-1+noise(:))/number_of_particles ; -else +else randvec = fliplr(cumprod(noise.^(1./(number_of_particles:-1:1)))); end diff --git a/src/univariate_smooth_resampling.m b/src/univariate_smooth_resampling.m index 8238902a1..e89b2cc6d 100644 --- a/src/univariate_smooth_resampling.m +++ b/src/univariate_smooth_resampling.m @@ -61,16 +61,16 @@ lambda_tilde = [ (.5*weights(1)) ; lambda_bar = cumsum(lambda_tilde) ; u = rand(1,1) ; new_particles = zeros(number_of_new_particles,1) ; -rj = 0 ; +rj = 0 ; i = 1 ; j = 1 ; while i<=number_of_new_particles u_j = ( i-1 + u)/number_of_new_particles ; while u_j>lambda_bar(j) - rj = j ; + rj = j ; j = j+1 ; end - if rj==0 + if rj==0 new_particles(i) = particles(1) ; elseif rj==M new_particles(i) = particles(M) ; diff --git a/src/unscented_sigma_points.m b/src/unscented_sigma_points.m index 38771758b..d1cba6eb5 100644 --- a/src/unscented_sigma_points.m +++ b/src/unscented_sigma_points.m @@ -1,6 +1,6 @@ -function [nodes,W_m,W_c] = unscented_sigma_points(n,ParticleOptions) +function [nodes,W_m,W_c] = unscented_sigma_points(n,ParticleOptions) % -% Computes nodes and weigths for a scaled unscented transform cubature +% Computes nodes and weigths for a scaled unscented transform cubature % INPUTS % n [integer] scalar, number of variables. % @@ -10,10 +10,10 @@ function [nodes,W_m,W_c] = unscented_sigma_points(n,ParticleOptions) % % REFERENCES % -% +% % % NOTES -% +% % Copyright (C) 2009-2012 Dynare Team % % This file is part of Dynare. @@ -31,12 +31,10 @@ function [nodes,W_m,W_c] = unscented_sigma_points(n,ParticleOptions) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -lambda = (ParticleOptions.unscented.alpha^2)*(n+ParticleOptions.unscented.kappa) - n ; +lambda = (ParticleOptions.unscented.alpha^2)*(n+ParticleOptions.unscented.kappa) - n ; nodes = [ zeros(n,1) ( sqrt(n+lambda).*([ eye(n) -eye(n)]) ) ]' ; W_m = lambda/(n+lambda) ; W_c = W_m + (1-ParticleOptions.unscented.alpha^2+ParticleOptions.unscented.beta) ; temp = ones(2*n,1)/(2*(n+lambda)) ; -W_m = [W_m ; temp] ; -W_c = [W_c ; temp] ; - - +W_m = [W_m ; temp] ; +W_c = [W_c ; temp] ; From 84d213ea3e705f36871bc8f960d175a330fd71de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 18 May 2017 23:59:49 +0200 Subject: [PATCH 058/101] Fixed copyright notices. --- src/auxiliary_initialization.m | 2 +- src/auxiliary_particle_filter.m | 2 +- src/conditional_filter_proposal.m | 2 +- src/conditional_particle_filter.m | 2 +- src/fit_gaussian_mixture.m | 2 +- src/gaussian_densities.m | 2 +- src/gaussian_filter.m | 2 +- src/gaussian_filter_bank.m | 2 +- src/gaussian_mixture_densities.m | 2 +- src/gaussian_mixture_filter.m | 2 +- src/gaussian_mixture_filter_bank.m | 2 +- src/importance_sampling.m | 2 +- src/measurement_equations.m | 2 +- src/multivariate_smooth_resampling.m | 2 +- src/mykmeans.m | 2 +- src/neff.m | 2 +- src/nonlinear_kalman_filter.m | 2 +- src/probability.m | 2 +- src/probability2.m | 2 +- src/probability3.m | 2 +- src/resample.m | 2 +- src/residual_resampling.m | 2 +- src/sequential_importance_particle_filter.m | 2 +- src/solve_model_for_online_filter.m | 2 +- src/spherical_radial_sigma_points.m | 2 +- src/traditional_resampling.m | 2 +- src/univariate_smooth_resampling.m | 2 +- src/unscented_sigma_points.m | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index 98f79aecb..002a8038a 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -2,7 +2,7 @@ function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,Par % Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. -% Copyright (C) 2011-2014 Dynare Team +% Copyright (C) 2011-2017 Dynare Team % % This file is part of Dynare (particles module). % diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 42d57ca45..61a43bc13 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -3,7 +3,7 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptio % Evaluates the likelihood of a nonlinear model with the auxiliary particle filter % allowing eventually resampling. % -% Copyright (C) 2011-2015 Dynare Team +% Copyright (C) 2011-2017 Dynare Team % % This file is part of Dynare (particles module). % diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 0c4121884..5137b83f7 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -18,7 +18,7 @@ function [ProposalStateVector,Weights] = conditional_filter_proposal(ReducedForm % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2012-2013 Dynare Team +% Copyright (C) 2012-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 01437773e..6216cf15c 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -37,7 +37,7 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOpt % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2010 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/fit_gaussian_mixture.m b/src/fit_gaussian_mixture.m index cc34e66b6..672c90e68 100644 --- a/src/fit_gaussian_mixture.m +++ b/src/fit_gaussian_mixture.m @@ -1,6 +1,6 @@ function [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(X,X_weights,StateMu,StateSqrtP,StateWeights,crit,niters,check) -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 2246e45e1..889a5bbe2 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -19,7 +19,7 @@ function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sq % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2010 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index d7e82df1b..e885cce72 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -30,7 +30,7 @@ function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, Thr % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2015 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index 3e9deb31c..fb2299631 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -19,7 +19,7 @@ function [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,St % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m index 7efe1ce01..c82605934 100644 --- a/src/gaussian_mixture_densities.m +++ b/src/gaussian_mixture_densities.m @@ -21,7 +21,7 @@ function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,State % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index eaab0070f..f744210d8 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -35,7 +35,7 @@ function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,ParticleOptions % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2013 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index 017192712..9c47b1021 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -23,7 +23,7 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/importance_sampling.m b/src/importance_sampling.m index b4a6daf4a..ae20b02a7 100644 --- a/src/importance_sampling.m +++ b/src/importance_sampling.m @@ -1,6 +1,6 @@ function State_Particles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost,numP) -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/measurement_equations.m b/src/measurement_equations.m index 7cf4d9320..1c386b6fd 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -1,6 +1,6 @@ function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions) -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/multivariate_smooth_resampling.m b/src/multivariate_smooth_resampling.m index e62111cc1..01c9208a7 100644 --- a/src/multivariate_smooth_resampling.m +++ b/src/multivariate_smooth_resampling.m @@ -38,7 +38,7 @@ function new_particles = multivariate_smooth_resampling(particles,weights) %! @end deftypefn %@eod: -% Copyright (C) 2012-2013 Dynare Team +% Copyright (C) 2012-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/mykmeans.m b/src/mykmeans.m index 4506aca25..c39afedb9 100644 --- a/src/mykmeans.m +++ b/src/mykmeans.m @@ -1,6 +1,6 @@ function [c,SqrtVariance,Weights] = mykmeans(x,g,init,cod) -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/neff.m b/src/neff.m index 9e02b679e..e0fb4f70e 100644 --- a/src/neff.m +++ b/src/neff.m @@ -1,7 +1,7 @@ function n = neff(w) % Evaluates the criterion for resampling -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2014 Dynare Team % % This file is part of Dynare. % diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index 608fbacec..6710e69d4 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -30,7 +30,7 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2015 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/probability.m b/src/probability.m index 94f09b9cb..68efb3fa1 100644 --- a/src/probability.m +++ b/src/probability.m @@ -1,6 +1,6 @@ function [prior,likelihood,C,posterior] = probability(mu,sqrtP,prior,X) -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/probability2.m b/src/probability2.m index dfc71ff24..268cd0394 100644 --- a/src/probability2.m +++ b/src/probability2.m @@ -14,7 +14,7 @@ function [density] = probability2(mu,S,X) % % NOTES % -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/probability3.m b/src/probability3.m index 5e2a9b4a8..710a84267 100644 --- a/src/probability3.m +++ b/src/probability3.m @@ -1,6 +1,6 @@ function [prior,likelihood,C,posterior] = probability3(mu,sqrtP,prior,X,X_weights) -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/resample.m b/src/resample.m index 3fee0c355..e29d62e4f 100644 --- a/src/resample.m +++ b/src/resample.m @@ -36,7 +36,7 @@ function resampled_output = resample(particles,weights,ParticleOptions) %! @end deftypefn %@eod: -% Copyright (C) 2011-2013 Dynare Team +% Copyright (C) 2011-2014 Dynare Team % % This file is part of Dynare. % diff --git a/src/residual_resampling.m b/src/residual_resampling.m index 9a7d8cce8..d4d250309 100644 --- a/src/residual_resampling.m +++ b/src/residual_resampling.m @@ -30,7 +30,7 @@ function return_resample = residual_resampling(particles,weights,noise) %! @end deftypefn %@eod: -% Copyright (C) 2011-2013 Dynare Team +% Copyright (C) 2011-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 51e0bd7a1..72a789ccd 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -2,7 +2,7 @@ function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,P % Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). -% Copyright (C) 2011-2014 Dynare Team +% Copyright (C) 2011-2015 Dynare Team % % This file is part of Dynare (particles module). % diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 1ea2e67a4..74d2fd925 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -101,7 +101,7 @@ function [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResu %! @end deftypefn %@eod: -% Copyright (C) 2013 Dynare Team +% Copyright (C) 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/spherical_radial_sigma_points.m b/src/spherical_radial_sigma_points.m index db71f6119..aeaf7d5c5 100644 --- a/src/spherical_radial_sigma_points.m +++ b/src/spherical_radial_sigma_points.m @@ -15,7 +15,7 @@ function [nodes,weights] = spherical_radial_sigma_points(n) % % NOTES % -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/traditional_resampling.m b/src/traditional_resampling.m index 87f550368..ce6ed90c4 100644 --- a/src/traditional_resampling.m +++ b/src/traditional_resampling.m @@ -33,7 +33,7 @@ function return_resample = traditional_resampling(particles,weights,noise) %! @end deftypefn %@eod: -% Copyright (C) 2011-2013 Dynare Team +% Copyright (C) 2011-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/univariate_smooth_resampling.m b/src/univariate_smooth_resampling.m index e89b2cc6d..1a8d10439 100644 --- a/src/univariate_smooth_resampling.m +++ b/src/univariate_smooth_resampling.m @@ -34,7 +34,7 @@ function new_particles = univariate_smooth_resampling(weights,particles,number_o %! @end deftypefn %@eod: -% Copyright (C) 2012 Dynare Team +% Copyright (C) 2012-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/unscented_sigma_points.m b/src/unscented_sigma_points.m index d1cba6eb5..54c5b0b0d 100644 --- a/src/unscented_sigma_points.m +++ b/src/unscented_sigma_points.m @@ -14,7 +14,7 @@ function [nodes,W_m,W_c] = unscented_sigma_points(n,ParticleOptions) % % NOTES % -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2017 Dynare Team % % This file is part of Dynare. % From 857168ddf8c2d386dac875da1ede31fd689be309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 1 Jun 2018 11:16:29 +0200 Subject: [PATCH 059/101] Added routines for Dynamic Striated Metropolis Hastings. --- src/DSMH_initialization.m | 118 +++++++++++++++ src/DSMH_sampler.m | 303 ++++++++++++++++++++++++++++++++++++++ src/tempered_likelihood.m | 5 + 3 files changed, 426 insertions(+) create mode 100644 src/DSMH_initialization.m create mode 100644 src/DSMH_sampler.m create mode 100644 src/tempered_likelihood.m diff --git a/src/DSMH_initialization.m b/src/DSMH_initialization.m new file mode 100644 index 000000000..38e16da4e --- /dev/null +++ b/src/DSMH_initialization.m @@ -0,0 +1,118 @@ +function [ ix2, temperedlogpost, loglik, ModelName, MetropolisFolder, npar, NumberOfParticles, bayestopt_] = ... + DSMH_initialization(TargetFun, xparam1, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% function [ ix2, ilogpo2, ModelName, MetropolisFolder, FirstBlock, FirstLine, npar, NumberOfParticles, bayestopt_] = ... +% DSMH_initialization(TargetFun, xparam1, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% Dynamic Striated Metropolis-Hastings initialization. +% +% INPUTS +% o TargetFun [char] string specifying the name of the objective +% function (tempered posterior kernel and likelihood). +% o xparam1 [double] (p*1) vector of parameters to be estimated (initial values). +% o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. +% o dataset_ data structure +% o dataset_info dataset info structure +% o options_ options structure +% o M_ model structure +% o estim_params_ estimated parameters structure +% o bayestopt_ estimation options structure +% o oo_ outputs structure +% +% OUTPUTS +% o ix2 [double] (NumberOfParticles*npar) vector of starting points for different chains +% o ilogpo2 [double] (NumberOfParticles*1) vector of initial posterior values for different chains +% o iloglik2 [double] (NumberOfParticles*1) vector of initial likelihood values for different chains +% o ModelName [string] name of the mod-file +% o MetropolisFolder [string] path to the Metropolis subfolder +% o npar [scalar] number of parameters estimated +% o NumberOfParticles [scalar] Number of particles requested for the parameters distributions +% o bayestopt_ [structure] estimation options structure +% +% SPECIAL REQUIREMENTS +% None. + +% Copyright (C) 2006-2017 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + +%Initialize outputs +ix2 = []; +ilogpo2 = []; +iloglik2 = []; +ModelName = []; +MetropolisFolder = []; +npar = []; +NumberOfParticles = []; + +ModelName = M_.fname; +if ~isempty(M_.bvar) + ModelName = [ModelName '_bvar']; +end + +MetropolisFolder = CheckPath('dsmh',M_.dname); +BaseName = [MetropolisFolder filesep ModelName]; + +NumberOfParticles = options_.dsmh.number_of_particles; %Number of particles for the parameters +npar = length(xparam1); + +% Here we start a new DS Metropolis-Hastings, previous draws are discarded. +disp('Estimation::dsmh: Initialization...') +% Delete old dsmh files if any... +files = dir([BaseName '_dsmh*_blck*.mat']); +%if length(files) +% delete([BaseName '_dsmh*_blck*.mat']); +% disp('Estimation::smc: Old dsmh-files successfully erased!') +%end +% Delete old log file. +file = dir([ MetropolisFolder '/dsmh.log']); +%if length(file) +% delete([ MetropolisFolder '/dsmh.log']); +% disp('Estimation::dsmh: Old dsmh.log file successfully erased!') +% disp('Estimation::dsmh: Creation of a new dsmh.log file.') +%end +fidlog = fopen([MetropolisFolder '/dsmh.log'],'w'); +fprintf(fidlog,'%% DSMH log file (Dynare).\n'); +fprintf(fidlog,['%% ' datestr(now,0) '.\n']); +fprintf(fidlog,' \n\n'); +fprintf(fidlog,'%% Session 1.\n'); +fprintf(fidlog,' \n'); +prior_draw(bayestopt_,options_.prior_trunc); +% Find initial values for the NumberOfParticles chains... +set_dynare_seed('default'); +fprintf(fidlog,[' Initial values of the parameters:\n']); +disp('Estimation::dsmh: Searching for initial values...'); +ix2 = zeros(npar,NumberOfParticles); +temperedlogpost = zeros(NumberOfParticles,1); +loglik = zeros(NumberOfParticles,1); +%stderr = sqrt(bsxfun(@power,mh_bounds.ub-mh_bounds.lb,2)/12)/10; +for j=1:NumberOfParticles + validate = 0; + while validate == 0 + candidate = prior_draw()'; +% candidate = xparam1(:) + 0.001*randn(npar,1);%bsxfun(@times,stderr,randn(npar,1)) ; + if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + ix2(:,j) = candidate ; + [temperedlogpost(j),loglik(j)] = tempered_likelihood(TargetFun,candidate,0.0,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglik(j)) % if returned log-density is Inf or Nan (penalized value) + validate = 1; + end + end + end +end +fprintf(fidlog,' \n'); +disp('Estimation::dsmh: Initial values found!') +skipline() + + diff --git a/src/DSMH_sampler.m b/src/DSMH_sampler.m new file mode 100644 index 000000000..56c9185a0 --- /dev/null +++ b/src/DSMH_sampler.m @@ -0,0 +1,303 @@ +function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% function DSMH_sampler(TargetFun,ProposalFun,xparam1,sampler_options,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% Dynamic Striated Metropolis-Hastings algorithm. +% +% INPUTS +% o TargetFun [char] string specifying the name of the objective +% function (posterior kernel). +% o ProposalFun [char] string specifying the name of the proposal +% density +% o xparam1 [double] (p*1) vector of parameters to be estimated (initial values). +% o sampler_options structure +% .invhess [double] (p*p) matrix, posterior covariance matrix (at the mode). +% o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. +% o dataset_ data structure +% o dataset_info dataset info structure +% o options_ options structure +% o M_ model structure +% o estim_params_ estimated parameters structure +% o bayestopt_ estimation options structure +% o oo_ outputs structure +% +% SPECIAL REQUIREMENTS +% None. +% +% PARALLEL CONTEXT +% The most computationally intensive part of this function may be executed +% in parallel. The code suitable to be executed in +% parallel on multi core or cluster machine (in general a 'for' cycle) +% has been removed from this function and been placed in the posterior_sampler_core.m funtion. +% +% The DYNARE parallel packages comprise a i) set of pairs of Matlab functions that can be executed in +% parallel and called name_function.m and name_function_core.m and ii) a second set of functions used +% to manage the parallel computations. +% +% This function was the first function to be parallelized. Later, other +% functions have been parallelized using the same methodology. +% Then the comments write here can be used for all the other pairs of +% parallel functions and also for management functions. + +% Copyright (C) 2006-2017 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + + +lambda = exp(bsxfun(@minus,options_.dsmh.H,1:1:options_.dsmh.H)/(options_.dsmh.H-1)*log(options_.dsmh.lambda1)); +c = 55 ; + +% Step 0: Initialization of the sampler +[ param, tlogpost_iminus1, loglik, ~, ~, npar, nparticles, bayestopt_] = ... + DSMH_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_); + +ESS = zeros(options_.dsmh.H,1) ; +zhat = 1 ; + +% The DSMH starts here + for i=1:options_.dsmh.H + disp(''); + disp('Tempered iteration'); + disp(i) ; + % Step 1: sort the densities and compute IS weigths + [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) ; + [tlogpost_i,weights,zhat,ESS,mu,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) ; + % Step 2: tune c_i + c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + % Step 3: Metropolis step + [param,tlogpost_iminus1,loglik] = mutation_DSMH(TargetFun,param,tlogpost_i,tlogpost_iminus1,loglik,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + end + +weights = exp(loglik*(lambda(end)-lambda(end-1))); +weights = weights/sum(weights); +indx_resmpl = DSMH_resampling(weights,rand(1,1),nparticles); +distrib_param = param(:,indx_resmpl); + +%% Plot parameters densities +TeX = options_.TeX; + +[nbplt,nr,nc,lr,lc,nstar] = pltorg(npar); + +if TeX + fidTeX = fopen([M_.fname '_param_density.tex'],'w'); + fprintf(fidTeX,'%% TeX eps-loader file generated by DSMH.m (Dynare).\n'); + fprintf(fidTeX,['%% ' datestr(now,0) '\n']); + fprintf(fidTeX,' \n'); +end + +number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. +bandwidth = 0; % Rule of thumb optimal bandwidth parameter. +kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. +for plt = 1:nbplt, + if TeX + NAMES = []; + TeXNAMES = []; + end + hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); + for k=1:min(nstar,npar-(plt-1)*nstar) + subplot(nr,nc,k) + kk = (plt-1)*nstar+k; + [name,texname] = get_the_name(kk,TeX,M_,estim_params_,options_); + if TeX + if isempty(NAMES) + NAMES = name; + TeXNAMES = texname; + else + NAMES = char(NAMES,name); + TeXNAMES = char(TeXNAMES,texname); + end + end + optimal_bandwidth = mh_optimal_bandwidth(distrib_param(kk,:)',nparticles,bandwidth,kernel_function); + [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(kk,:)',number_of_grid_points,... + nparticles,optimal_bandwidth,kernel_function); + plot(density(:,1),density(:,2)); + hold on + title(name,'interpreter','none') + hold off + axis tight + drawnow + end + dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); + if TeX + % TeX eps loader file + fprintf(fidTeX,'\\begin{figure}[H]\n'); + for jj = 1:min(nstar,length(x)-(plt-1)*nstar) + fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); + end + fprintf(fidTeX,'\\centering \n'); + fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',M_.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{ParametersDensities.}'); + fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); + fprintf(fidTeX,'\\end{figure}\n'); + fprintf(fidTeX,' \n'); + end +end + +function indx = DSMH_resampling(weights,noise,number) + indx = zeros(number,1); + cumweights = cumsum(weights); + randvec = (transpose(1:number)-1+noise(:))/number; + j = 1; + for i=1:number + while (randvec(i)>cumweights(j)) + j = j+1; + end + indx(i) = j; + end + +function [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) + [~,indx_ord] = sortrows(tlogpost_iminus1); + tlogpost_iminus1 = tlogpost_iminus1(indx_ord); + param = param(:,indx_ord); + loglik = loglik(indx_ord); + +function [tlogpost_i,weights,zhat,ESS,mu,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) + if i==1 + tlogpost_i = tlogpost_iminus1 + loglik*lambda(i); + else + tlogpost_i = tlogpost_iminus1 + loglik*(lambda(i)-lambda(i-1)); + end + weights = exp(tlogpost_i-tlogpost_iminus1); + zhat = (mean(weights))*zhat ; + weights = weights/sum(weights); + ESS(i) = 1/sum(weights.^2); + % estimates of mean and variance + mu = param*weights; + z = bsxfun(@minus,param,mu); + Omega = z*diag(weights)*z'; + Omegachol = chol(Omega)'; + +function c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) + disp('tuning c_i...'); + disp('Initial value ='); + disp(c) ; + npar = size(param,1); + lower_prob = (.5*(options_.dsmh.alpha0+options_.dsmh.alpha1))^5; + upper_prob = (.5*(options_.dsmh.alpha0+options_.dsmh.alpha1))^(1/5); + stop=0 ; + while stop==0 + acpt = 0.0; + indx_resmpl = DSMH_resampling(weights,rand(1,1),options_.dsmh.G); + param0 = param(:,indx_resmpl); + tlogpost0 = tlogpost_i(indx_resmpl); + for j=1:options_.dsmh.G + for l=1:options_.dsmh.K + validate = 0; + while validate == 0 + candidate = param0(:,j) + sqrt(c)*Omegachol*randn(npar,1); + if all(candidate >= mh_bounds.lb) && all(candidate <= mh_bounds.ub) + [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) + validate = 1; + if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) + validate = 1; + if u2 Date: Fri, 8 Jun 2018 20:56:24 +0200 Subject: [PATCH 060/101] Correct the calculation of the incremental weights. --- src/gaussian_densities.m | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 889a5bbe2..f1c595100 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -42,11 +42,12 @@ proposal = probability2(mut_t,sqr_Pss_t_t,particles) ; prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; % likelihood yt_t_1_i = measurement_equations(particles,ReducedForm,ThreadsOptions) ; -eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; -yt_t_1 = sum(yt_t_1_i*weigths1,2) ; -tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; -Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; -sqr_det = sqrt(det(Pyy)) ; -foo = (eta_t_i/Pyy).*eta_t_i ; -likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +%eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; +%yt_t_1 = sum(yt_t_1_i*weigths1,2) ; +%tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; +%Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; +%sqr_det = sqrt(det(Pyy)) ; +%foo = (eta_t_i/Pyy).*eta_t_i ; +%likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +likelihood = probability2(obs,sqrt(H),yt_t_1_i) ; IncrementalWeights = likelihood.*prior./proposal ; From ee6eaa8449033b7074a468646e93dbaaf76160c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 8 Jun 2018 20:57:38 +0200 Subject: [PATCH 061/101] Add the possibility of proposal approximated with Monte Carlo. --- src/gaussian_filter_bank.m | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index fb2299631..dc15dc3ab 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -71,7 +71,11 @@ if isempty(init_flag2) init_flag2 = 1; end -if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo +if ParticleOptions.proposal_approximation.montecarlo + nodes = randn(ParticleOptions.number_of_particles,number_of_state_variables+number_of_structural_innovations) ; + weights = 1/ParticleOptions.number_of_particles ; + weights_c = weights ; +elseif ParticleOptions.proposal_approximation.cubature [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations) ; weights_c = weights ; elseif ParticleOptions.proposal_approximation.unscented @@ -118,5 +122,5 @@ else StateVectorMean = PredictedStateMean + KalmanFilterGain*PredictionError; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); - StateVectorVarianceSquareRoot = chol(StateVectorVariance)'; %reduced_rank_cholesky(StateVectorVariance)'; -end \ No newline at end of file + StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; +end From 28f7c7621babacfa6eb7588b3ec25e47914dedb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Fri, 8 Jun 2018 20:58:48 +0200 Subject: [PATCH 062/101] Add the option of Monte Carlo nonlinear Kalman filter. --- src/nonlinear_kalman_filter.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index 6710e69d4..9e118b995 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -89,7 +89,11 @@ end % compute gaussian quadrature nodes and weights on states and shocks -if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo +if ParticleOptions.proposal_approximation.montecarlo + nodes = randn(ParticleOptions.number_of_particles,number_of_state_variables+number_of_structural_innovations) ; + weights = 1/ParticleOptions.number_of_particles ; + weights_c = weights ; +elseif ParticleOptions.proposal_approximation.cubature [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations) ; weights_c = weights ; elseif ParticleOptions.proposal_approximation.unscented From 1f08164b05b6276f82cb48ca27ccde54e9f634c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Sat, 9 Jun 2018 14:59:20 +0200 Subject: [PATCH 063/101] Correct the calculation of the incremental weights. --- src/gaussian_mixture_densities.m | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m index c82605934..cd4f6b58e 100644 --- a/src/gaussian_mixture_densities.m +++ b/src/gaussian_mixture_densities.m @@ -46,11 +46,12 @@ prior = prior' ; proposal = proposal' ; % Compute the density of the current observation conditionally to each particle yt_t_1_i = measurement_equations(StateParticles,ReducedForm,ThreadsOptions) ; -eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; -yt_t_1 = sum(yt_t_1_i*weigths1,2) ; -tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; -Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; -sqr_det = sqrt(det(Pyy)) ; -foo = (eta_t_i/Pyy).*eta_t_i ; -likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +%eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; +%yt_t_1 = sum(yt_t_1_i*weigths1,2) ; +%tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; +%Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; +%sqr_det = sqrt(det(Pyy)) ; +%foo = (eta_t_i/Pyy).*eta_t_i ; +%likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; +likelihood = probability2(obs,sqrt(H),yt_t_1_i) ; IncrementalWeights = likelihood.*prior./proposal ; From 43615ce4f6bd522f3a7b309e3025204b9ab9df59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Mon, 11 Jun 2018 09:46:17 +0200 Subject: [PATCH 064/101] Add flags to deal with errors on Cholesky matrices in CPF filter. --- src/conditional_filter_proposal.m | 23 ++++++++++++++++++++--- src/conditional_particle_filter.m | 9 +++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 5137b83f7..fe9278c48 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -1,4 +1,4 @@ -function [ProposalStateVector,Weights] = conditional_filter_proposal(ReducedForm,obs,StateVectors,SampleWeights,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) +function [ProposalStateVector,Weights,flag] = conditional_filter_proposal(ReducedForm,obs,StateVectors,SampleWeights,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) % % Computes the proposal for each past particle using Gaussian approximations % for the state errors and the Kalman filter @@ -42,6 +42,7 @@ persistent init_flag2 mf0 mf1 persistent number_of_state_variables number_of_observed_variables persistent number_of_structural_innovations +flag=0 ; % Set local state space model (first-order approximation). ghx = ReducedForm.ghx; ghu = ReducedForm.ghu; @@ -118,15 +119,31 @@ else Error = obs - PredictedObservedMean ; StateVectorMean = PredictedStateMean + KalmanFilterGain*Error ; StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; - StateVectorVarianceSquareRoot = chol(StateVectorVariance + eye(number_of_state_variables)*1e-6)' ; + StateVectorVariance = 0.5*(StateVectorVariance+StateVectorVariance'); + %StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)';%chol(StateVectorVariance + eye(number_of_state_variables)*1e-6)' ; + [StateVectorVarianceSquareRoot,p] = chol(StateVectorVariance,'lower') ; + if p + flag=1; + ProposalStateVector = zeros(number_of_state_variables,1) ; + Weights = 0.0 ; + return + end if ParticleOptions.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; end end -PredictedStateVarianceSquareRoot = chol(PredictedStateVariance + eye(number_of_state_variables)*1e-6)' ; ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; if ParticleOptions.cpf_weights_method.murrayjonesparslow + PredictedStateVariance = 0.5*(PredictedStateVariance+PredictedStateVariance'); + %PredictedStateVarianceSquareRoot = reduced_rank_cholesky(PredictedStateVariance)';%chol(PredictedStateVariance + eye(number_of_state_variables)*1e-6)' ; + [PredictedStateVarianceSquareRoot,p] = chol(PredictedStateVariance,'lower') ; + if p + flag=1; + ProposalStateVector = zeros(number_of_state_variables,1) ; + Weights = 0.0 ; + return + end Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 6216cf15c..9ba069a19 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -103,8 +103,13 @@ StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance SampleWeights = ones(1,number_of_particles)/number_of_particles ; for t=1:sample_size for i=1:number_of_particles - [StateParticles(:,i),SampleWeights(i)] = ... + [StateParticles(:,i),SampleWeights(i),flag] = ... conditional_filter_proposal(ReducedForm,Y(:,t),StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) ; + if flag==1 + LIK=-Inf; + lik(t)=-Inf; + return + end end SumSampleWeights = sum(SampleWeights) ; lik(t) = log(SumSampleWeights) ; @@ -116,4 +121,4 @@ for t=1:sample_size end end -LIK = -sum(lik(start:end)); \ No newline at end of file +LIK = -sum(lik(start:end)); From ef22c716d3e23f749b82cb0e73392ddcf93c42b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 13 Jun 2018 18:43:04 +0200 Subject: [PATCH 065/101] Initial particles are drawn in the prior distribution + bug fixes. --- src/online_auxiliary_filter.m | 176 ++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 81 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index a14548559..8598a1318 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -43,7 +43,7 @@ persistent start_param sample_size number_of_observed_variables number_of_struct % Set seed for randn(). set_dynare_seed('default') ; pruning = DynareOptions.particle.pruning; -second_resample = 0 ; +second_resample = DynareOptions.particle.resampling.status.systematic ; variance_update = 1 ; % initialization of state particles @@ -75,25 +75,31 @@ if pruning end % parameters for the Liu & West filter -h_square = (3*liu_west_delta-1)/(2*liu_west_delta) ; -h_square = 1-h_square*h_square ; -small_a = sqrt(1-h_square) ; +small_a = (3*liu_west_delta-1)/(2*liu_west_delta) ; +b_square = 1-small_a*small_a ; % Initialization of parameter particles xparam = zeros(number_of_parameters,number_of_particles) ; -stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/100 ; -stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/50 ; +%stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/100 ; +%stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/50 ; %stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/20 ; -i = 1 ; -while i<=number_of_particles - %candidate = start_param + .001*liu_west_chol_sigma_bar*randn(number_of_parameters,1) ; - candidate = start_param + bsxfun(@times,stderr,randn(number_of_parameters,1)) ; - if all(candidate(:) >= bounds.lb) && all(candidate(:) <= bounds.ub) - xparam(:,i) = candidate(:) ; - i = i+1 ; +bounds = prior_bounds(BayesInfo,DynareOptions.prior_trunc); %reset bounds as lb and ub must only be operational during mode-finding +prior_draw(BayesInfo,DynareOptions.prior_trunc); +for i=1:number_of_particles + info = 1; + while info==1 + %candidate = start_param + .001*liu_west_chol_sigma_bar*randn(number_of_parameters,1) ; + %candidate = start_param + bsxfun(@times,stderr,randn(number_of_parameters,1)) ; + candidate = prior_draw()'; + if all(candidate(:) >= bounds.lb) && all(candidate(:) <= bounds.ub) + [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... + solve_model_for_online_filter(1,candidate(:),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; + if info==0 + xparam(:,i) = candidate(:) ; + end + end end -end - +end %xparam = bsxfun(@plus,bounds(:,1),bsxfun(@times,(bounds(:,2)-bounds(:,1)),rand(number_of_parameters,number_of_particles))) ; % Initialization of the weights of particles. @@ -119,81 +125,87 @@ for t=1:sample_size temp = bsxfun(@minus,xparam,m_bar) ; sigma_bar = (bsxfun(@times,weights,temp))*(temp') ; if variance_update==1 - chol_sigma_bar = chol(h_square*sigma_bar)' ; + chol_sigma_bar = chol(b_square*sigma_bar)' ; end % Prediction (without shocks) + fore_xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam) ; tau_tilde = zeros(1,number_of_particles) ; for i=1:number_of_particles % model resolution [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... - solve_model_for_online_filter(t,xparam(:,i),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; - steadystate = ReducedForm.steadystate; - state_variables_steady_state = ReducedForm.state_variables_steady_state; - % Set local state space model (second-order approximation). - constant = ReducedForm.constant; - ghx = ReducedForm.ghx; - ghu = ReducedForm.ghu; - ghxx = ReducedForm.ghxx; - ghuu = ReducedForm.ghuu; - ghxu = ReducedForm.ghxu; - % particle likelihood contribution - yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); - if pruning - yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); - else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); - end - PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); - % Replace Gaussian density with a Student density with 3 degrees of - % freedom for fat tails. - z = sum(PredictionError.*(ReducedForm.H\PredictionError),1) ; - tau_tilde(i) = weights(i).*(tpdf(z,3*ones(size(z)))+1e-99) ; - %tau_tilde(i) = weights(i).*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))) ; - end - % particles selection - tau_tilde = tau_tilde/sum(tau_tilde) ; - indx = resample(0,tau_tilde',DynareOptions.particle); - StateVectors = StateVectors(:,indx) ; - if pruning - StateVectors_ = StateVectors_(:,indx) ; - end - xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam(:,indx)) ; - w_stage1 = weights(indx)./tau_tilde(indx) ; - % draw in the new distributions - wtilde = zeros(1,number_of_particles) ; - i = 1 ; - while i<=number_of_particles - candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters,1) ; - if all(candidate >= bounds.lb) && all(candidate <= bounds.ub) - xparam(:,i) = candidate ; - % model resolution for new parameters particles - [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... - solve_model_for_online_filter(t,xparam(:,i),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; + solve_model_for_online_filter(t,fore_xparam(:,i),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; + if info==0 steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; - % Set local state space model (second order approximation). + % Set local state space model (second-order approximation). constant = ReducedForm.constant; ghx = ReducedForm.ghx; ghu = ReducedForm.ghu; ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; - % Get covariance matrices and structural shocks - epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations,1) ; - % compute particles likelihood contribution + % particle likelihood contribution yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); if pruning yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); - StateVectors_(:,i) = tmp_(mf0,:) ; + [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); end - StateVectors(:,i) = tmp(mf0,:) ; PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); - wtilde(i) = w_stage1(i)*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))); - i = i+1 ; + % Replace Gaussian density with a Student density with 3 degrees of + % freedom for fat tails. + z = sum(PredictionError.*(ReducedForm.H\PredictionError),1) ; + tau_tilde(i) = weights(i).*(tpdf(z,3*ones(size(z)))+1e-99) ; + %tau_tilde(i) = weights(i).*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))) ; + end + end + % particles selection + tau_tilde = tau_tilde/sum(tau_tilde) ; + indx = resample(0,tau_tilde',DynareOptions.particle); + StateVectors = StateVectors(:,indx) ; + xparam = fore_xparam(:,indx); + if pruning + StateVectors_ = StateVectors_(:,indx) ; + end + w_stage1 = weights(indx)./tau_tilde(indx) ; + % draw in the new distributions + wtilde = zeros(1,number_of_particles) ; + for i=1:number_of_particles + info=1 ; + while info==1 + candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters,1) ; + if all(candidate >= bounds.lb) && all(candidate <= bounds.ub) + % model resolution for new parameters particles + [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... + solve_model_for_online_filter(t,candidate,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; + if info==0 + xparam(:,i) = candidate ; + steadystate = ReducedForm.steadystate; + state_variables_steady_state = ReducedForm.state_variables_steady_state; + % Set local state space model (second order approximation). + constant = ReducedForm.constant; + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; + % Get covariance matrices and structural shocks + epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations,1) ; + % compute particles likelihood contribution + yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); + if pruning + yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + StateVectors_(:,i) = tmp_(mf0,:) ; + else + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + end + StateVectors(:,i) = tmp(mf0,:) ; + PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); + wtilde(i) = w_stage1(i)*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))); + end + end end end % normalization @@ -266,6 +278,10 @@ median_param = median_xparam(:,sample_size) ; TeX = DynareOptions.TeX; [nbplt,nr,nc,lr,lc,nstar] = pltorg(number_of_parameters); +nr = ceil(sqrt(number_of_parameters)) ; +nc = floor(sqrt(number_of_parameters)); +nbplt = 1 ; + if TeX fidTeX = fopen([Model.fname '_param_traj.tex'],'w'); @@ -282,10 +298,9 @@ for plt = 1:nbplt, TeXNAMES = []; end hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Trajectories'); - for k=1:min(nstar,length(xparam)-(plt-1)*nstar) + for k=1:length(xparam) subplot(nr,nc,k) - kk = (plt-1)*nstar+k; - [name,texname] = get_the_name(kk,TeX,Model,EstimatedParameters,DynareOptions); + [name,texname] = get_the_name(k,TeX,Model,EstimatedParameters,DynareOptions); if TeX if isempty(NAMES) NAMES = name; @@ -295,7 +310,7 @@ for plt = 1:nbplt, TeXNAMES = char(TeXNAMES,texname); end end - y = [mean_xparam(kk,:)' median_xparam(kk,:)' lb95_xparam(kk,:)' ub95_xparam(kk,:)' xparam(kk)*ones(sample_size,1)] ; + y = [mean_xparam(k,:)' median_xparam(k,:)' lb95_xparam(k,:)' ub95_xparam(k,:)' xparam(k)*ones(sample_size,1)] ; plot(z,y); hold on title(name,'interpreter','none') @@ -307,7 +322,7 @@ for plt = 1:nbplt, if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); - for jj = 1:min(nstar,length(x)-(plt-1)*nstar) + for jj = 1:length(x) fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); end fprintf(fidTeX,'\\centering \n'); @@ -329,10 +344,9 @@ for plt = 1:nbplt, TeXNAMES = []; end hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Densities'); - for k=1:min(nstar,length(xparam)-(plt-1)*nstar) + for k=1:length(xparam) subplot(nr,nc,k) - kk = (plt-1)*nstar+k; - [name,texname] = get_the_name(kk,TeX,Model,EstimatedParameters,DynareOptions); + [name,texname] = get_the_name(k,TeX,Model,EstimatedParameters,DynareOptions); if TeX if isempty(NAMES) NAMES = name; @@ -342,8 +356,8 @@ for plt = 1:nbplt, TeXNAMES = char(TeXNAMES,texname); end end - optimal_bandwidth = mh_optimal_bandwidth(distrib_param(kk,:)',number_of_particles,bandwidth,kernel_function); - [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(kk,:)',number_of_grid_points,... + optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',number_of_particles,bandwidth,kernel_function); + [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... number_of_particles,optimal_bandwidth,kernel_function); plot(density(:,1),density(:,2)); hold on @@ -356,7 +370,7 @@ for plt = 1:nbplt, if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); - for jj = 1:min(nstar,length(x)-(plt-1)*nstar) + for jj = 1:length(x) fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); end fprintf(fidTeX,'\\centering \n'); From 35c3a9fcd9181d1f5ba250172a6abf5daa0a04dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Thu, 28 Jun 2018 09:20:19 +0200 Subject: [PATCH 066/101] Replace the likelihood of the mean by the mean of the likelihoods. --- src/nonlinear_kalman_filter.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index 9e118b995..cf4339473 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -169,7 +169,9 @@ for t=1:sample_size return end end - lik(t) = log( probability2(0,PredictedObservedVarianceSquareRoot,PredictionError) ) ; +% lik(t) = log( probability2(0,PredictedObservedVarianceSquareRoot,PredictionError) ) ; + lik(t) = log( sum(probability2(Y(:,t),H_lower_triangular_cholesky,tmp(mf1,:)).*weights,1) ) ; +% lik(t) = log(sum(probability2(Y(:,t),PredictedObservedVarianceSquareRoot,tmp(mf1,:)).*weights,1) ) ; end LIK = -sum(lik(start:end)); From fb7ec278d6fbb88853e6306e7eae54fa95bbd998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Thu, 28 Jun 2018 09:21:50 +0200 Subject: [PATCH 067/101] include parallelisation, correction of the likelihood calculation for the Amisano and Tristani option and the possibility of monte carlo draws for the proposal. --- src/conditional_filter_proposal.m | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index fe9278c48..ab746c01c 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -74,7 +74,11 @@ if isempty(init_flag2) init_flag2 = 1; end -if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo +if ParticleOptions.proposal_approximation.montecarlo + nodes = randn(ParticleOptions.number_of_particles/10,number_of_structural_innovations) ; + weights = 1/ParticleOptions.number_of_particles ; + weights_c = weights ; +elseif ParticleOptions.proposal_approximation.cubature [nodes,weights] = spherical_radial_sigma_points(number_of_structural_innovations); weights_c = weights ; elseif ParticleOptions.proposal_approximation.unscented @@ -108,7 +112,8 @@ if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_a StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*Error ; if ParticleOptions.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),PredictedObservedVarianceSquareRoot,Error) ; - end + % Weights = SampleWeights.*sum(weights*probability2(obs,H_lower_triangular_cholesky,tmp(mf1,:)),1) ; + end else dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); @@ -130,7 +135,8 @@ else end if ParticleOptions.cpf_weights_method.amisanotristani Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; - end +% Weights = SampleWeights.*sum(probability2(obs,H_lower_triangular_cholesky,tmp(mf1,:))*weights) ; + end end ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; From 66867386ef5c70e8db69293af8a0e051488196f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Thu, 28 Jun 2018 09:22:34 +0200 Subject: [PATCH 068/101] include modifications for parallelisation. --- src/conditional_particle_filter.m | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 9ba069a19..87fb5cded 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -102,15 +102,17 @@ ks = 0 ; StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); SampleWeights = ones(1,number_of_particles)/number_of_particles ; for t=1:sample_size - for i=1:number_of_particles - [StateParticles(:,i),SampleWeights(i),flag] = ... - conditional_filter_proposal(ReducedForm,Y(:,t),StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) ; - if flag==1 - LIK=-Inf; - lik(t)=-Inf; - return - end + obs=Y(:,t); + flag = zeros(number_of_particles) ; + parfor i=1:number_of_particles + [StateParticles(:,i),SampleWeights(i),flag(i)] = ... + conditional_filter_proposal(ReducedForm,obs,StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) ; end + if sum(flag)~=0 + LIK=-Inf; + lik(t)=-Inf; + return + end SumSampleWeights = sum(SampleWeights) ; lik(t) = log(SumSampleWeights) ; SampleWeights = SampleWeights./SumSampleWeights ; From 7c8518731911d98ab1322894d49500638ae201a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Mon, 10 Sep 2018 12:18:49 +0200 Subject: [PATCH 069/101] Update URLs for the move to GitLab --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73b04f7dc..31463754a 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,5 @@ This package, used in [Dynare](http://www.dynare.org), provides nonlinear filtering algorithms. The documentation is available in the -[doc](https://github.com/DynareTeam/particles/tree/master/doc) +[doc](https://git.dynare.org/Dynare/particles/tree/master/doc) subfolder. From 22be3797a87b2f9ce5ae75556ab18774088d66ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Mon, 11 Feb 2019 10:59:51 +0100 Subject: [PATCH 070/101] New SMC sampler (Herbst and Schorfheide). --- src/DSMH_sampler.m | 71 +++++---- src/Herbst_Schorfheide_sampler.m | 257 ++++++++++++++++++++++++++++++ src/SMC_samplers_initialization.m | 117 ++++++++++++++ src/smc_resampling.m | 11 ++ 4 files changed, 426 insertions(+), 30 deletions(-) create mode 100644 src/Herbst_Schorfheide_sampler.m create mode 100644 src/SMC_samplers_initialization.m create mode 100644 src/smc_resampling.m diff --git a/src/DSMH_sampler.m b/src/DSMH_sampler.m index 56c9185a0..d44a43f50 100644 --- a/src/DSMH_sampler.m +++ b/src/DSMH_sampler.m @@ -56,17 +56,17 @@ function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_ lambda = exp(bsxfun(@minus,options_.dsmh.H,1:1:options_.dsmh.H)/(options_.dsmh.H-1)*log(options_.dsmh.lambda1)); -c = 55 ; +c = 0.055 ; % Step 0: Initialization of the sampler -[ param, tlogpost_iminus1, loglik, ~, ~, npar, nparticles, bayestopt_] = ... - DSMH_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_); +[ param, tlogpost_iminus1, loglik, npar, ~, bayestopt_] = ... + SMC_samplers_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,options_.dsmh.number_of_particles); ESS = zeros(options_.dsmh.H,1) ; zhat = 1 ; % The DSMH starts here - for i=1:options_.dsmh.H + for i=2:options_.dsmh.H disp(''); disp('Tempered iteration'); disp(i) ; @@ -81,12 +81,33 @@ zhat = 1 ; weights = exp(loglik*(lambda(end)-lambda(end-1))); weights = weights/sum(weights); -indx_resmpl = DSMH_resampling(weights,rand(1,1),nparticles); +indx_resmpl = smc_resampling(weights,rand(1,1),options_.dsmh.number_of_particles); distrib_param = param(:,indx_resmpl); -%% Plot parameters densities +mean_xparam = mean(distrib_param,2); +%mat_var_cov = bsxfun(@minus,distrib_param,mean_xparam) ; +%mat_var_cov = (mat_var_cov*mat_var_cov')/(options_.HSsmc.nparticles-1) ; +%std_xparam = sqrt(diag(mat_var_cov)) ; +lb95_xparam = zeros(npar,1) ; +ub95_xparam = zeros(npar,1) ; +for i=1:npar + temp = sortrows(distrib_param(i,:)') ; + lb95_xparam(i) = temp(0.025*options_.HSsmc.nparticles) ; + ub95_xparam(i) = temp(0.975*options_.HSsmc.nparticles) ; +end + TeX = options_.TeX; +str = sprintf(' Param. \t Lower Bound (95%%) \t Mean \t Upper Bound (95%%)'); +for l=1:npar + [name,~] = get_the_name(l,TeX,M_,estim_params_,options_); + str = sprintf('%s\n %s \t\t %5.4f \t\t %7.5f \t\t %5.4f', str, name, lb95_xparam(l), mean_xparam(l), ub95_xparam(l)); +end +disp([str]) +disp('') + +%% Plot parameters densities + [nbplt,nr,nc,lr,lc,nstar] = pltorg(npar); if TeX @@ -99,16 +120,18 @@ end number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. bandwidth = 0; % Rule of thumb optimal bandwidth parameter. kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. -for plt = 1:nbplt, + +plt = 1 ; +%for plt = 1:nbplt, if TeX NAMES = []; TeXNAMES = []; end hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); - for k=1:min(nstar,npar-(plt-1)*nstar) - subplot(nr,nc,k) - kk = (plt-1)*nstar+k; - [name,texname] = get_the_name(kk,TeX,M_,estim_params_,options_); + for k=1:npar %min(nstar,npar-(plt-1)*nstar) + subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) + %kk = (plt-1)*nstar+k; + [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); if TeX if isempty(NAMES) NAMES = name; @@ -118,9 +141,9 @@ for plt = 1:nbplt, TeXNAMES = char(TeXNAMES,texname); end end - optimal_bandwidth = mh_optimal_bandwidth(distrib_param(kk,:)',nparticles,bandwidth,kernel_function); - [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(kk,:)',number_of_grid_points,... - nparticles,optimal_bandwidth,kernel_function); + optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.dsmh.number_of_particles,bandwidth,kernel_function); + [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... + options_.dsmh.number_of_particles,optimal_bandwidth,kernel_function); plot(density(:,1),density(:,2)); hold on title(name,'interpreter','none') @@ -142,19 +165,7 @@ for plt = 1:nbplt, fprintf(fidTeX,'\\end{figure}\n'); fprintf(fidTeX,' \n'); end -end - -function indx = DSMH_resampling(weights,noise,number) - indx = zeros(number,1); - cumweights = cumsum(weights); - randvec = (transpose(1:number)-1+noise(:))/number; - j = 1; - for i=1:number - while (randvec(i)>cumweights(j)) - j = j+1; - end - indx(i) = j; - end +%end function [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) [~,indx_ord] = sortrows(tlogpost_iminus1); @@ -188,7 +199,7 @@ function c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,data stop=0 ; while stop==0 acpt = 0.0; - indx_resmpl = DSMH_resampling(weights,rand(1,1),options_.dsmh.G); + indx_resmpl = smc_resampling(weights,rand(1,1),options_.dsmh.G); param0 = param(:,indx_resmpl); tlogpost0 = tlogpost_i(indx_resmpl); for j=1:options_.dsmh.G @@ -240,7 +251,7 @@ function [out_param,out_tlogpost_iminus1,out_loglik] = mutation_DSMH(TargetFun,p out_tlogpost_iminus1 = tlogpost_i; out_loglik = loglik; % resample and initialize the starting groups - indx_resmpl = DSMH_resampling(weights,rand(1,1),options_.dsmh.G); + indx_resmpl = smc_resampling(weights,rand(1,1),options_.dsmh.G); param0 = param(:,indx_resmpl); tlogpost_iminus10 = tlogpost_iminus1(indx_resmpl); tlogpost_i0 = tlogpost_i(indx_resmpl); @@ -300,4 +311,4 @@ function [out_param,out_tlogpost_iminus1,out_loglik] = mutation_DSMH(TargetFun,p out_loglik(rang) = loglik0; end end - \ No newline at end of file + diff --git a/src/Herbst_Schorfheide_sampler.m b/src/Herbst_Schorfheide_sampler.m new file mode 100644 index 000000000..3c6482919 --- /dev/null +++ b/src/Herbst_Schorfheide_sampler.m @@ -0,0 +1,257 @@ +function Herbst_Schorfheide_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% function Herbst_Schorfheide_sampler(TargetFun,ProposalFun,xparam1,sampler_options,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% SMC sampler from JAE 2014 . +% +% INPUTS +% o TargetFun [char] string specifying the name of the objective +% function (posterior kernel). +% o ProposalFun [char] string specifying the name of the proposal +% density +% o xparam1 [double] (p*1) vector of parameters to be estimated (initial values). +% o sampler_options structure +% .invhess [double] (p*p) matrix, posterior covariance matrix (at the mode). +% o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. +% o dataset_ data structure +% o dataset_info dataset info structure +% o options_ options structure +% o M_ model structure +% o estim_params_ estimated parameters structure +% o bayestopt_ estimation options structure +% o oo_ outputs structure +% +% SPECIAL REQUIREMENTS +% None. +% +% PARALLEL CONTEXT +% The most computationally intensive part of this function may be executed +% in parallel. The code suitable to be executed in +% parallel on multi core or cluster machine (in general a 'for' cycle) +% has been removed from this function and been placed in the posterior_sampler_core.m funtion. +% +% The DYNARE parallel packages comprise a i) set of pairs of Matlab functions that can be executed in +% parallel and called name_function.m and name_function_core.m and ii) a second set of functions used +% to manage the parallel computations. +% +% This function was the first function to be parallelized. Later, other +% functions have been parallelized using the same methodology. +% Then the comments write here can be used for all the other pairs of +% parallel functions and also for management functions. + +% Copyright (C) 2006-2017 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see . + + +% Create the tempering schedule +phi = bsxfun(@power,(bsxfun(@minus,1:1:options_.HSsmc.nphi,1)/(options_.HSsmc.nphi-1)),options_.HSsmc.lambda) ; +% tuning for MH algorithms matrices +zhat = 0 ; % normalization constant +csim = zeros(options_.HSsmc.nphi,1) ; % scale parameter +ESSsim = zeros(options_.HSsmc.nphi,1) ; % ESS +acptsim = zeros(options_.HSsmc.nphi,1) ; % average acceptance rate +% Step 0: Initialization of the sampler +[ param, tlogpost_i, loglik, npar, ~, bayestopt_] = ... + SMC_samplers_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,options_.HSsmc.nparticles); +weights = ones(options_.HSsmc.nparticles,1)/options_.HSsmc.nparticles ; +% The Herbst and Schorfheide sampler starts here +for i=2:options_.HSsmc.nphi + % (a) Correction + % incremental weights + incwt = exp((phi(i)-phi(i-1))*loglik) ; + % update weights + weights = bsxfun(@times,weights,incwt) ; + sum_weights = sum(weights) ; + zhat = zhat + log(sum_weights) ; + % normalize weights + weights = weights/sum_weights ; + % (b) Selection + ESSsim(i) = 1/sum(weights.^2) ; + if (ESSsim(i) < options_.HSsmc.nparticles/2) + indx_resmpl = smc_resampling(weights,rand(1,1),options_.HSsmc.nparticles) ; + param = param(:,indx_resmpl) ; + loglik = loglik(indx_resmpl) ; + tlogpost_i = tlogpost_i(indx_resmpl) ; + weights = ones(options_.HSsmc.nparticles,1)/options_.HSsmc.nparticles ; + end + % (c) Mutation + options_.HSsmc.c = options_.HSsmc.c*modified_logit(0.95,0.1,16.0,options_.HSsmc.acpt-options_.HSsmc.trgt) ; + % Calculate estimates of mean and variance + mu = param*weights ; + z = bsxfun(@minus,param,mu) ; + R = z*(bsxfun(@times,z',weights)) ; + Rchol = chol(R)' ; + % Mutation + if options_.HSsmc.option_mutation==1 + [param,tlogpost_i,loglik,options_.HSsmc.acpt] = mutation_RW(TargetFun,param,tlogpost_i,loglik,phi,i,options_.HSsmc.c*Rchol,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) ; + elseif options_.HSsmc.option_mutation==2 + inv_R = inv(options_.HSsmc.c^2*R) ; + Rdiagchol = sqrt(diag(R)) ; + [param,tlogpost_i,loglik,options_.HSsmc.acpt] = mutation_Mixture(TargetFun,param,tlogpost_i,loglik,phi,i,options_.HSsmc.c*Rchol,options_.HSsmc.c*Rdiagchol,inv_R,mu,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) ; + end + acptsim(i) = options_.HSsmc.acpt ; + csim(i) = options_.HSsmc.c ; + % print information + fprintf(' Iteration = %5.0f / %5.0f \n', i, options_.HSsmc.nphi); + fprintf(' phi = %5.4f \n', phi(i)); + fprintf(' Neff = %5.4f \n', ESSsim(i)); + fprintf(' %accept. = %5.4f \n', acptsim(i)); +end +indx_resmpl = smc_resampling(weights,rand(1,1),options_.HSsmc.nparticles); +distrib_param = param(:,indx_resmpl); +fprintf(' Log_lik = %5.4f \n', zhat); + +mean_xparam = mean(distrib_param,2); +%mat_var_cov = bsxfun(@minus,distrib_param,mean_xparam) ; +%mat_var_cov = (mat_var_cov*mat_var_cov')/(options_.HSsmc.nparticles-1) ; +%std_xparam = sqrt(diag(mat_var_cov)) ; +lb95_xparam = zeros(npar,1) ; +ub95_xparam = zeros(npar,1) ; +for i=1:npar + temp = sortrows(distrib_param(i,:)') ; + lb95_xparam(i) = temp(0.025*options_.HSsmc.nparticles) ; + ub95_xparam(i) = temp(0.975*options_.HSsmc.nparticles) ; +end + +TeX = options_.TeX; + +str = sprintf(' Param. \t Lower Bound (95%%) \t Mean \t Upper Bound (95%%)'); +for l=1:npar + [name,~] = get_the_name(l,TeX,M_,estim_params_,options_); + str = sprintf('%s\n %s \t\t %5.4f \t\t %7.5f \t\t %5.4f', str, name, lb95_xparam(l), mean_xparam(l), ub95_xparam(l)); +end +disp([str]) +disp('') + +%% Plot parameters densities + +[nbplt,nr,nc,lr,lc,nstar] = pltorg(npar); + +if TeX + fidTeX = fopen([M_.fname '_param_density.tex'],'w'); + fprintf(fidTeX,'%% TeX eps-loader file generated by DSMH.m (Dynare).\n'); + fprintf(fidTeX,['%% ' datestr(now,0) '\n']); + fprintf(fidTeX,' \n'); +end + +number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. +bandwidth = 0; % Rule of thumb optimal bandwidth parameter. +kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. +plt = 1 ; +%for plt = 1:nbplt, + if TeX + NAMES = []; + TeXNAMES = []; + end + hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); + for k=1:npar %min(nstar,npar-(plt-1)*nstar) + subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) + %kk = (plt-1)*nstar+k; + [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); + if TeX + if isempty(NAMES) + NAMES = name; + TeXNAMES = texname; + else + NAMES = char(NAMES,name); + TeXNAMES = char(TeXNAMES,texname); + end + end + optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.HSsmc.nparticles,bandwidth,kernel_function); + [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... + options_.HSsmc.nparticles,optimal_bandwidth,kernel_function); + plot(density(:,1),density(:,2)); + hold on + title(name,'interpreter','none') + hold off + axis tight + drawnow + end + dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); + if TeX + % TeX eps loader file + fprintf(fidTeX,'\\begin{figure}[H]\n'); + for jj = 1:min(nstar,length(x)-(plt-1)*nstar) + fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); + end + fprintf(fidTeX,'\\centering \n'); + fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',M_.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{ParametersDensities.}'); + fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); + fprintf(fidTeX,'\\end{figure}\n'); + fprintf(fidTeX,' \n'); + end +%end + +function [param,tlogpost_i,loglik,acpt] = mutation_RW(TargetFun,param,tlogpost_i,loglik,phi,i,cRchol,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) + acpt = 0.0 ; + tlogpost_i = tlogpost_i + (phi(i)-phi(i-1))*loglik ; + for j=1:options_.HSsmc.nparticles + validate= 0; + while validate==0 + candidate = param(:,j) + cRchol*randn(size(param,1),1) ; + if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) + validate = 1; + if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) + validate = 1; + if rand(1,1). + +%Initialize outputs +ix2 = []; +ilogpo2 = []; +iloglik2 = []; +ModelName = []; +MetropolisFolder = []; +npar = []; + +ModelName = M_.fname; +if ~isempty(M_.bvar) + ModelName = [ModelName '_bvar']; +end + +MetropolisFolder = CheckPath('dsmh',M_.dname); +BaseName = [MetropolisFolder filesep ModelName]; + +npar = length(xparam1); + +% Here we start a new DS Metropolis-Hastings, previous draws are discarded. +disp('Estimation:: Initialization...') +% Delete old dsmh files if any... +files = dir([BaseName '_dsmh*_blck*.mat']); +%if length(files) +% delete([BaseName '_dsmh*_blck*.mat']); +% disp('Estimation::smc: Old dsmh-files successfully erased!') +%end +% Delete old log file. +file = dir([ MetropolisFolder '/dsmh.log']); +%if length(file) +% delete([ MetropolisFolder '/dsmh.log']); +% disp('Estimation::dsmh: Old dsmh.log file successfully erased!') +% disp('Estimation::dsmh: Creation of a new dsmh.log file.') +%end +fidlog = fopen([MetropolisFolder '/dsmh.log'],'w'); +fprintf(fidlog,'%% DSMH log file (Dynare).\n'); +fprintf(fidlog,['%% ' datestr(now,0) '.\n']); +fprintf(fidlog,' \n\n'); +fprintf(fidlog,'%% Session 1.\n'); +fprintf(fidlog,' \n'); +prior_draw(bayestopt_,options_.prior_trunc); +% Find initial values for the NumberOfParticles chains... +set_dynare_seed('default'); +fprintf(fidlog,[' Initial values of the parameters:\n']); +disp('Estimation::dsmh: Searching for initial values...'); +ix2 = zeros(npar,NumberOfParticles); +temperedlogpost = zeros(NumberOfParticles,1); +loglik = zeros(NumberOfParticles,1); +%stderr = sqrt(bsxfun(@power,mh_bounds.ub-mh_bounds.lb,2)/12)/10; +for j=1:NumberOfParticles + validate = 0; + while validate == 0 + candidate = prior_draw()'; +% candidate = xparam1(:) + 0.001*randn(npar,1);%bsxfun(@times,stderr,randn(npar,1)) ; + if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + ix2(:,j) = candidate ; + [temperedlogpost(j),loglik(j)] = tempered_likelihood(TargetFun,candidate,0.0,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglik(j)) % if returned log-density is Inf or Nan (penalized value) + validate = 1; + end + end + end +end +fprintf(fidlog,' \n'); +disp('Estimation:: Initial values found!') +skipline() + + diff --git a/src/smc_resampling.m b/src/smc_resampling.m new file mode 100644 index 000000000..bac7eeac0 --- /dev/null +++ b/src/smc_resampling.m @@ -0,0 +1,11 @@ +function indx = smc_resampling(weights,noise,number) + indx = zeros(number,1); + cumweights = cumsum(weights); + randvec = (transpose(1:number)-1+noise(:))/number; + j = 1; + for i=1:number + while (randvec(i)>cumweights(j)) + j = j+1; + end + indx(i) = j; + end From a0fb5c73484b8b8cf44061ec9ad7707b61267ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Thu, 11 Jul 2019 12:45:26 +0200 Subject: [PATCH 071/101] Updated online filter routines. - Rewrote doc headers - Changed function signatures - Removed persistent variables - Compute the mode of the particle weights - Return the covariance matrix of the particles in the last period - Various cosmetic changes --- src/online_auxiliary_filter.m | 321 +++++++++++++--------------- src/solve_model_for_online_filter.m | 319 ++++++++------------------- 2 files changed, 238 insertions(+), 402 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 8598a1318..18f762ec9 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -1,27 +1,27 @@ -function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(xparam1,DynareDataset,dataset_info,DynareOptions,Model,EstimatedParameters,BayesInfo,bounds,DynareResults) +function [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxiliary_filter(xparam1, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, DynareResults) % Liu & West particle filter = auxiliary particle filter including Liu & West filter on parameters. % % INPUTS -% ReducedForm [structure] Matlab's structure describing the reduced form model. -% ReducedForm.measurement.H [double] (pp x pp) variance matrix of measurement errors. -% ReducedForm.state.Q [double] (qq x qq) variance matrix of state errors. -% ReducedForm.state.dr [structure] output of resol.m. -% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. -% start [integer] scalar, likelihood evaluation starts at 'start'. -% mf [integer] pp*1 vector of indices. -% number_of_particles [integer] scalar. +% - xparam1 [double] n×1 vector, Initial condition for the estimated parameters. +% - DynareDataset [dseries] Sample used for estimation. +% - dataset_info [struct] Description of the sample. +% - DynareOptions [struct] Option values (options_). +% - Model [struct] Description of the model (M_). +% - EstimatedParameters [struct] Description of the estimated parameters (estim_params_). +% - BayesInfo [struct] Prior definition (bayestopt_). +% - DynareResults [struct] Results (oo_). % % OUTPUTS -% LIK [double] scalar, likelihood -% lik [double] vector, density of observations in each period. -% -% REFERENCES -% -% NOTES -% The vector "lik" is used to evaluate the jacobian of the likelihood. +% - pmean [double] n×1 vector, mean of the particles at the end of the sample (for the parameters). +% - pmode [double] n×1 vector, mode of the particles at the end of the sample (for the parameters). +% - pmedian [double] n×1 vector, median of the particles at the end of the sample (for the parameters). +% - pstdev [double] n×1 vector, st. dev. of the particles at the end of the sample (for the parameters). +% - p025 [double] n×1 vector, 2.5 percent of the particles are below p025(i) for i=1,…,n. +% - p975 [double] n×1 vector, 97.5 percent of the particles are below p975(i) for i=1,…,n. +% - covariance [double] n×n matrix, covariance of the particles at the end of the sample. -% Copyright (C) 2013-2017 Dynare Team +% Copyright (C) 2013-2019 Dynare Team % % This file is part of Dynare. % @@ -37,33 +37,27 @@ function [xparam,std_param,lb_95,ub_95,median_param] = online_auxiliary_filter(x % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -persistent Y init_flag mf0 mf1 number_of_particles number_of_parameters liu_west_delta liu_west_chol_sigma_bar -persistent start_param sample_size number_of_observed_variables number_of_structural_innovations % Set seed for randn(). -set_dynare_seed('default') ; +set_dynare_seed('default'); pruning = DynareOptions.particle.pruning; -second_resample = DynareOptions.particle.resampling.status.systematic ; -variance_update = 1 ; +second_resample = DynareOptions.particle.resampling.status.systematic; +variance_update = true; + +bounds = prior_bounds(BayesInfo, DynareOptions.prior_trunc); % Reset bounds as lb and ub must only be operational during mode-finding % initialization of state particles -[ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... - solve_model_for_online_filter(1,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; +[~, Model, DynareOptions, DynareResults, ReducedForm] = solve_model_for_online_filter(true, xparam1, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults); -% Set persistent variables. -if isempty(init_flag) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - number_of_particles = DynareOptions.particle.number_of_particles; - number_of_parameters = size(xparam1,1) ; - Y = DynareDataset.data ; - sample_size = size(Y,1); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - liu_west_delta = DynareOptions.particle.liu_west_delta ; - start_param = xparam1 ; - init_flag = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +number_of_particles = DynareOptions.particle.number_of_particles; +number_of_parameters = size(xparam1,1); +Y = DynareDataset.data; +sample_size = size(Y,1); +number_of_observed_variables = length(mf1); +number_of_structural_innovations = length(ReducedForm.Q); +liu_west_delta = DynareOptions.particle.liu_west_delta; % Get initial conditions for the state particles StateVectorMean = ReducedForm.StateVectorMean; @@ -75,43 +69,34 @@ if pruning end % parameters for the Liu & West filter -small_a = (3*liu_west_delta-1)/(2*liu_west_delta) ; -b_square = 1-small_a*small_a ; +small_a = (3*liu_west_delta-1)/(2*liu_west_delta); +b_square = 1-small_a*small_a; % Initialization of parameter particles -xparam = zeros(number_of_parameters,number_of_particles) ; -%stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/100 ; -%stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/50 ; -%stderr = sqrt(bsxfun(@power,bounds.ub-bounds.lb,2)/12)/20 ; -bounds = prior_bounds(BayesInfo,DynareOptions.prior_trunc); %reset bounds as lb and ub must only be operational during mode-finding +xparam = zeros(number_of_parameters,number_of_particles); prior_draw(BayesInfo,DynareOptions.prior_trunc); for i=1:number_of_particles - info = 1; - while info==1 - %candidate = start_param + .001*liu_west_chol_sigma_bar*randn(number_of_parameters,1) ; - %candidate = start_param + bsxfun(@times,stderr,randn(number_of_parameters,1)) ; + info = 12042009; + while info candidate = prior_draw()'; - if all(candidate(:) >= bounds.lb) && all(candidate(:) <= bounds.ub) - [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... - solve_model_for_online_filter(1,candidate(:),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; - if info==0 - xparam(:,i) = candidate(:) ; - end - end + [info, Model, DynareOptions, DynareResults] = solve_model_for_online_filter(false, xparam1, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults); + if ~info + xparam(:,i) = candidate(:); + end end -end -%xparam = bsxfun(@plus,bounds(:,1),bsxfun(@times,(bounds(:,2)-bounds(:,1)),rand(number_of_parameters,number_of_particles))) ; +end % Initialization of the weights of particles. -weights = ones(1,number_of_particles)/number_of_particles ; +weights = ones(1,number_of_particles)/number_of_particles; % Initialization of the likelihood. const_lik = log(2*pi)*number_of_observed_variables; -mean_xparam = zeros(number_of_parameters,sample_size) ; -median_xparam = zeros(number_of_parameters,sample_size) ; -std_xparam = zeros(number_of_parameters,sample_size) ; -lb95_xparam = zeros(number_of_parameters,sample_size) ; -ub95_xparam = zeros(number_of_parameters,sample_size) ; +mean_xparam = zeros(number_of_parameters,sample_size); +mode_xparam = zeros(number_of_parameters,sample_size); +median_xparam = zeros(number_of_parameters,sample_size); +std_xparam = zeros(number_of_parameters,sample_size); +lb95_xparam = zeros(number_of_parameters,sample_size); +ub95_xparam = zeros(number_of_parameters,sample_size); %% The Online filter for t=1:sample_size @@ -121,20 +106,20 @@ for t=1:sample_size fprintf('\nSubsample with only the first observation.\n\n', int2str(t)) end % Moments of parameters particles distribution - m_bar = xparam*(weights') ; - temp = bsxfun(@minus,xparam,m_bar) ; - sigma_bar = (bsxfun(@times,weights,temp))*(temp') ; - if variance_update==1 - chol_sigma_bar = chol(b_square*sigma_bar)' ; + m_bar = xparam*(weights'); + temp = bsxfun(@minus,xparam,m_bar); + sigma_bar = (bsxfun(@times,weights,temp))*(temp'); + if variance_update + chol_sigma_bar = chol(b_square*sigma_bar)'; end % Prediction (without shocks) - fore_xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam) ; - tau_tilde = zeros(1,number_of_particles) ; + fore_xparam = bsxfun(@plus,(1-small_a).*m_bar,small_a.*xparam); + tau_tilde = zeros(1,number_of_particles); for i=1:number_of_particles % model resolution - [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... - solve_model_for_online_filter(t,fore_xparam(:,i),DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; - if info==0 + [info, Model, DynareOptions, DynareResults, ReducedForm] = ... + solve_model_for_online_filter(false, fore_xparam(:,i), DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults); + if ~info steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; % Set local state space model (second-order approximation). @@ -148,38 +133,36 @@ for t=1:sample_size yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); if pruning yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); + [tmp, ~] = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); else - tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,1),ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); end - PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); - % Replace Gaussian density with a Student density with 3 degrees of - % freedom for fat tails. - z = sum(PredictionError.*(ReducedForm.H\PredictionError),1) ; - tau_tilde(i) = weights(i).*(tpdf(z,3*ones(size(z)))+1e-99) ; - %tau_tilde(i) = weights(i).*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))) ; - end + PredictionError = bsxfun(@minus,Y(t,:)', tmp(mf1,:)); + % Replace Gaussian density with a Student density with 3 degrees of freedom for fat tails. + z = sum(PredictionError.*(ReducedForm.H\PredictionError), 1) ; + tau_tilde(i) = weights(i).*(tpdf(z, 3*ones(size(z)))+1e-99) ; + end end % particles selection - tau_tilde = tau_tilde/sum(tau_tilde) ; - indx = resample(0,tau_tilde',DynareOptions.particle); - StateVectors = StateVectors(:,indx) ; - xparam = fore_xparam(:,indx); + tau_tilde = tau_tilde/sum(tau_tilde); + indx = resample(0, tau_tilde', DynareOptions.particle); + StateVectors = StateVectors(:,indx); + xparam = fore_xparam(:,indx); if pruning - StateVectors_ = StateVectors_(:,indx) ; + StateVectors_ = StateVectors_(:,indx); end - w_stage1 = weights(indx)./tau_tilde(indx) ; + w_stage1 = weights(indx)./tau_tilde(indx); % draw in the new distributions - wtilde = zeros(1,number_of_particles) ; + wtilde = zeros(1, number_of_particles); for i=1:number_of_particles - info=1 ; - while info==1 - candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters,1) ; - if all(candidate >= bounds.lb) && all(candidate <= bounds.ub) - % model resolution for new parameters particles - [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = ... - solve_model_for_online_filter(t,candidate,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) ; - if info==0 + info = 12042009; + while info + candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters, 1); + if all(candidate>=bounds.lb) && all(candidate<=bounds.ub) + % model resolution for new parameters particles + [info, Model, DynareOptions, DynareResults, ReducedForm] = ... + solve_model_for_online_filter(false, candidate, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults) ; + if ~info xparam(:,i) = candidate ; steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; @@ -191,71 +174,75 @@ for t=1:sample_size ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; % Get covariance matrices and structural shocks - epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations,1) ; + epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations, 1); % compute particles likelihood contribution - yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); + yhat = bsxfun(@minus,StateVectors(:,i), state_variables_steady_state); if pruning - yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,DynareOptions.threads.local_state_space_iteration_2); - StateVectors_(:,i) = tmp_(mf0,:) ; + yhat_ = bsxfun(@minus,StateVectors_(:,i), state_variables_steady_state); + [tmp, tmp_] = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); + StateVectors_(:,i) = tmp_(mf0,:); else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); end - StateVectors(:,i) = tmp(mf0,:) ; - PredictionError = bsxfun(@minus,Y(t,:)',tmp(mf1,:)); - wtilde(i) = w_stage1(i)*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError),1))); - end + StateVectors(:,i) = tmp(mf0,:); + PredictionError = bsxfun(@minus,Y(t,:)', tmp(mf1,:)); + wtilde(i) = w_stage1(i)*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError), 1))); + end end end end % normalization weights = wtilde/sum(wtilde); - if (variance_update==1) && (neff(weights)=0.025 && pass1==1 - lb95_xparam(i,t) = temp(j,1) ; - pass1 = 2 ; + if ~pass1 && cumulated_weights(j)>=0.025 + lb95_xparam(i,t) = temp(j,1); + pass1 = true; end - if cumulated_weights(j)>=0.5 && pass2==1 - median_xparam(i,t) = temp(j,1) ; - pass2 = 2 ; + if ~pass2 && cumulated_weights(j)>=0.5 + median_xparam(i,t) = temp(j,1); + pass2 = true; end - if cumulated_weights(j)>=0.975 && pass3==1 - ub95_xparam(i,t) = temp(j,1) ; - pass3 = 2 ; + if ~pass3 && cumulated_weights(j)>=0.975 + ub95_xparam(i,t) = temp(j,1); + pass3 = true; end end end @@ -267,22 +254,22 @@ for t=1:sample_size disp([str]) disp('') end -distrib_param = xparam ; -xparam = mean_xparam(:,sample_size) ; -std_param = std_xparam(:,sample_size) ; -lb_95 = lb95_xparam(:,sample_size) ; -ub_95 = ub95_xparam(:,sample_size) ; -median_param = median_xparam(:,sample_size) ; + +pmean = xparam(:,sample_size); +pmode = mode_xparam(:,sample_size); +pstdev = std_xparam(:,sample_size) ; +p025 = lb95_xparam(:,sample_size) ; +p975 = ub95_xparam(:,sample_size) ; +pmedian = median_xparam(:,sample_size) ; +covariance = mat_var_cov; %% Plot parameters trajectory TeX = DynareOptions.TeX; -[nbplt,nr,nc,lr,lc,nstar] = pltorg(number_of_parameters); nr = ceil(sqrt(number_of_parameters)) ; nc = floor(sqrt(number_of_parameters)); nbplt = 1 ; - if TeX fidTeX = fopen([Model.fname '_param_traj.tex'],'w'); fprintf(fidTeX,'%% TeX eps-loader file generated by online_auxiliary_filter.m (Dynare).\n'); @@ -290,15 +277,13 @@ if TeX fprintf(fidTeX,' \n'); end -z = 1:1:sample_size ; - -for plt = 1:nbplt, +for plt = 1:nbplt if TeX NAMES = []; TeXNAMES = []; end hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Trajectories'); - for k=1:length(xparam) + for k=1:length(pmean) subplot(nr,nc,k) [name,texname] = get_the_name(k,TeX,Model,EstimatedParameters,DynareOptions); if TeX @@ -310,15 +295,17 @@ for plt = 1:nbplt, TeXNAMES = char(TeXNAMES,texname); end end - y = [mean_xparam(k,:)' median_xparam(k,:)' lb95_xparam(k,:)' ub95_xparam(k,:)' xparam(k)*ones(sample_size,1)] ; - plot(z,y); + % Draw the surface for an interval containing 95% of the particles. + shade(1:sample_size, ub95_xparam(k,:)', 1:sample_size, lb95_xparam(k,:)', 'FillType',[1 2], 'LineStyle', 'none', 'Marker', 'none') hold on + % Draw the mean of particles. + plot(1:sample_size, mean_xparam(k,:), '-k', 'linewidth', 2) title(name,'interpreter','none') hold off axis tight drawnow end - dyn_saveas(hh,[ Model.fname '_param_traj' int2str(plt) ],DynareOptions.nodisplay,DynareOptions.graph_format); + dyn_saveas(hh, [Model.fname '_param_traj' int2str(plt)], DynareOptions.nodisplay, DynareOptions.graph_format); if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); @@ -334,17 +321,17 @@ for plt = 1:nbplt, end end -%% Plot Parameter Densities +% Plot Parameter Densities number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. bandwidth = 0; % Rule of thumb optimal bandwidth parameter. kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. -for plt = 1:nbplt, +for plt = 1:nbplt if TeX NAMES = []; TeXNAMES = []; end hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Densities'); - for k=1:length(xparam) + for k=1:length(pmean) subplot(nr,nc,k) [name,texname] = get_the_name(k,TeX,Model,EstimatedParameters,DynareOptions); if TeX @@ -356,12 +343,12 @@ for plt = 1:nbplt, TeXNAMES = char(TeXNAMES,texname); end end - optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',number_of_particles,bandwidth,kernel_function); - [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... - number_of_particles,optimal_bandwidth,kernel_function); - plot(density(:,1),density(:,2)); + optimal_bandwidth = mh_optimal_bandwidth(xparam(k,:)',number_of_particles,bandwidth,kernel_function); + [density(:,1),density(:,2)] = kernel_density_estimate(xparam(k,:)', number_of_grid_points, ... + number_of_particles, optimal_bandwidth, kernel_function); + plot(density(:,1), density(:,2)); hold on - title(name,'interpreter','none') + title(name, 'interpreter', 'none') hold off axis tight drawnow @@ -369,9 +356,9 @@ for plt = 1:nbplt, dyn_saveas(hh,[ Model.fname '_param_density' int2str(plt) ],DynareOptions.nodisplay,DynareOptions.graph_format); if TeX % TeX eps loader file - fprintf(fidTeX,'\\begin{figure}[H]\n'); + fprintf(fidTeX, '\\begin{figure}[H]\n'); for jj = 1:length(x) - fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); + fprintf(fidTeX, '\\psfrag{%s}[1][][0.5][0]{%s}\n', deblank(NAMES(jj,:)), deblank(TeXNAMES(jj,:))); end fprintf(fidTeX,'\\centering \n'); fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',Model.fname,int2str(plt)); diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 74d2fd925..4df219d87 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -1,107 +1,26 @@ -function [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResults,ReducedForm] = solve_model_for_online_filter(observation_number,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults) -% solve the dsge model for an particular parameters set. +function [info, Model, DynareOptions, DynareResults, ReducedForm] = ... + solve_model_for_online_filter(setinitialcondition, xparam1, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults) -%@info: -%! @deftypefn {Function File} {[@var{fval},@var{exit_flag},@var{ys},@var{trend_coeff},@var{info},@var{Model},@var{DynareOptions},@var{BayesInfo},@var{DynareResults}] =} non_linear_dsge_likelihood (@var{xparam1},@var{DynareDataset},@var{DynareOptions},@var{Model},@var{EstimatedParameters},@var{BayesInfo},@var{DynareResults}) -%! @anchor{dsge_likelihood} -%! @sp 1 -%! Evaluates the posterior kernel of a dsge model using a non linear filter. -%! @sp 2 -%! @strong{Inputs} -%! @sp 1 -%! @table @ @var -%! @item xparam1 -%! Vector of doubles, current values for the estimated parameters. -%! @item DynareDataset -%! Matlab's structure describing the dataset (initialized by dynare, see @ref{dataset_}). -%! @item DynareOptions -%! Matlab's structure describing the options (initialized by dynare, see @ref{options_}). -%! @item Model -%! Matlab's structure describing the Model (initialized by dynare, see @ref{M_}). -%! @item EstimatedParamemeters -%! Matlab's structure describing the estimated_parameters (initialized by dynare, see @ref{estim_params_}). -%! @item BayesInfo -%! Matlab's structure describing the priors (initialized by dynare, see @ref{bayesopt_}). -%! @item DynareResults -%! Matlab's structure gathering the results (initialized by dynare, see @ref{oo_}). -%! @end table -%! @sp 2 -%! @strong{Outputs} -%! @sp 1 -%! @table @ @var -%! @item fval -%! Double scalar, value of (minus) the likelihood. -%! @item exit_flag -%! Integer scalar, equal to zero if the routine return with a penalty (one otherwise). -%! @item ys -%! Vector of doubles, steady state level for the endogenous variables. -%! @item trend_coeffs -%! Matrix of doubles, coefficients of the deterministic trend in the measurement equation. -%! @item info -%! Integer scalar, error code. -%! @table @ @code -%! @item info==0 -%! No error. -%! @item info==1 -%! The model doesn't determine the current variables uniquely. -%! @item info==2 -%! MJDGGES returned an error code. -%! @item info==3 -%! Blanchard & Kahn conditions are not satisfied: no stable equilibrium. -%! @item info==4 -%! Blanchard & Kahn conditions are not satisfied: indeterminacy. -%! @item info==5 -%! Blanchard & Kahn conditions are not satisfied: indeterminacy due to rank failure. -%! @item info==6 -%! The jacobian evaluated at the deterministic steady state is complex. -%! @item info==19 -%! The steadystate routine thrown an exception (inconsistent deep parameters). -%! @item info==20 -%! Cannot find the steady state, info(2) contains the sum of square residuals (of the static equations). -%! @item info==21 -%! The steady state is complex, info(2) contains the sum of square of imaginary parts of the steady state. -%! @item info==22 -%! The steady has NaNs. -%! @item info==23 -%! M_.params has been updated in the steadystate routine and has complex valued scalars. -%! @item info==24 -%! M_.params has been updated in the steadystate routine and has some NaNs. -%! @item info==30 -%! Ergodic variance can't be computed. -%! @item info==41 -%! At least one parameter is violating a lower bound condition. -%! @item info==42 -%! At least one parameter is violating an upper bound condition. -%! @item info==43 -%! The covariance matrix of the structural innovations is not positive definite. -%! @item info==44 -%! The covariance matrix of the measurement errors is not positive definite. -%! @item info==45 -%! Likelihood is not a number (NaN). -%! @item info==45 -%! Likelihood is a complex valued number. -%! @end table -%! @item Model -%! Matlab's structure describing the model (initialized by dynare, see @ref{M_}). -%! @item DynareOptions -%! Matlab's structure describing the options (initialized by dynare, see @ref{options_}). -%! @item BayesInfo -%! Matlab's structure describing the priors (initialized by dynare, see @ref{bayesopt_}). -%! @item DynareResults -%! Matlab's structure gathering the results (initialized by dynare, see @ref{oo_}). -%! @end table -%! @sp 2 -%! @strong{This function is called by:} -%! @sp 1 -%! @ref{dynare_estimation_1}, @ref{mode_check} -%! @sp 2 -%! @strong{This function calls:} -%! @sp 1 -%! @ref{dynare_resolve}, @ref{lyapunov_symm}, @ref{priordens} -%! @end deftypefn -%@eod: +% Solves the dsge model for an particular parameters set. +% +% INPUTS +% - setinitialcondition [logical] return initial condition if true. +% - xparam1 [double] n×1 vector, parameter values. +% - DynareDataset [struct] Dataset for estimation (dataset_). +% - DynareOptions [struct] Dynare options (options_). +% - Model [struct] Model description (M_). +% - EstimatedParameters [struct] Estimated parameters (estim_params_). +% - BayesInfo [struct] Prior definition (bayestopt_). +% - DynareResults [struct] Dynare results (oo_). +% +% OUTPUTS +% - info [integer] scalar, nonzero if any problem occur when computing the reduced form. +% - Model [struct] Model description (M_). +% - DynareOptions [struct] Dynare options (options_). +% - DynareResults [struct] Dynare results (oo_). +% - ReducedForm [struct] Reduced form model. -% Copyright (C) 2013-2017 Dynare Team +% Copyright (C) 2013-2019 Dynare Team % % This file is part of Dynare. % @@ -118,46 +37,25 @@ function [ys,trend_coeff,exit_flag,info,Model,DynareOptions,BayesInfo,DynareResu % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% AUTHOR(S) stephane DOT adjemian AT univ DASH lemans DOT fr -% frederic DOT karame AT univ DASH lemans DOT fr +persistent init_flag restrict_variables_idx state_variables_idx mf0 mf1 number_of_state_variables -%global objective_function_penalty_base -% Declaration of the penalty as a persistent variable. -persistent init_flag -persistent restrict_variables_idx observed_variables_idx state_variables_idx mf0 mf1 -persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations +info = 0; -% Initialization of the returned arguments. -fval = []; -ys = []; -trend_coeff = []; -exit_flag = 1; - -% Set the number of observed variables -%nvobs = DynareDataset.info.nvobs; -nvobs = size(DynareDataset.data,1) ; - -%------------------------------------------------------------------------------ +%---------------------------------------------------- % 1. Get the structural parameters & define penalties -%------------------------------------------------------------------------------ +%---------------------------------------------------- -% Return, with endogenous penalty, if some parameters are smaller than the lower bound of the prior domain. -%if (DynareOptions.mode_compute~=1) && any(xparam1BayesInfo.ub) -% k = find(xparam1(:)>BayesInfo.ub); -% fval = objective_function_penalty_base+sum((xparam1(k)-BayesInfo.ub(k)).^2); -% exit_flag = 0; -% info = 42; -% return -%end +% Test if some parameters are greater than the upper bound of the prior domain. +if any(xparam1>bounds.ub) + info = 42; + return +end % Get the diagonal elements of the covariance matrices for the structural innovations (Q) and the measurement error (H). Q = Model.Sigma_e; @@ -173,7 +71,7 @@ if EstimatedParameters.nvn end offset = offset+EstimatedParameters.nvn; else - H = zeros(nvobs); + H = zeros(size(DynareDataset.data, 1)); end % Get the off-diagonal elements of the covariance matrix for the structural innovations. Test if Q is positive definite. @@ -185,18 +83,12 @@ if EstimatedParameters.ncx Q(k2,k1) = Q(k1,k2); end % Try to compute the cholesky decomposition of Q (possible iff Q is positive definite) - % [CholQ,testQ] = chol(Q); - % if testQ - % The variance-covariance matrix of the structural innovations is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. - % a = diag(eig(Q)); - % k = find(a < 0); - % if k > 0 - % fval = objective_function_penalty_base+sum(-a(k)); - % exit_flag = 0; - % info = 43; - % return - % end - % end + [~, testQ] = chol(Q); + if testQ + % The variance-covariance matrix of the structural innovations is not definite positive. + info = 43; + return + end offset = offset+EstimatedParameters.ncx; end @@ -210,18 +102,12 @@ if EstimatedParameters.ncn H(k2,k1) = H(k1,k2); end % Try to compute the cholesky decomposition of H (possible iff H is positive definite) - % [CholH,testH] = chol(H); - % if testH - % The variance-covariance matrix of the measurement errors is not definite positive. We have to compute the eigenvalues of this matrix in order to build the endogenous penalty. - % a = diag(eig(H)); - % k = find(a < 0); - % if k > 0 - % fval = objective_function_penalty_base+sum(-a(k)); - % exit_flag = 0; - % info = 44; - % return - % end - % end + [~, testH] = chol(H); + if testH + % The variance-covariance matrix of the measurement errors is not definite positive. + info = 44; + return + end offset = offset+EstimatedParameters.ncn; end @@ -238,55 +124,18 @@ Model.H = H; % 2. call model setup & reduction program %------------------------------------------------------------------------------ -% Linearize the model around the deterministic sdteadystate and extract the matrices of the state equation (T and R). -[T,R,SteadyState,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict'); +warning('off', 'MATLAB:nearlySingularMatrix') +[~, ~, ~, info, Model, DynareOptions, DynareResults] = ... + dynare_resolve(Model, DynareOptions, DynareResults, 'restrict'); +warning('on', 'MATLAB:nearlySingularMatrix') -%disp(info) - -if info(1) ~= 0 - ReducedForm = 0 ; - exit_flag = 55; +if info(1)~=0 + if nargout==5 + ReducedForm = 0; + end return end -% Define a vector of indices for the observed variables. Is this really usefull?... -BayesInfo.mf = BayesInfo.mf1; - -% Define the deterministic linear trend of the measurement equation. -if DynareOptions.noconstant - constant = zeros(nvobs,1); -else - if DynareOptions.loglinear - constant = log(SteadyState(BayesInfo.mfys)); - else - constant = SteadyState(BayesInfo.mfys); - end -end - -% Define the deterministic linear trend of the measurement equation. -%if BayesInfo.with_trend -% trend_coeff = zeros(DynareDataset.info.nvobs,1); -% t = DynareOptions.trend_coeffs; -% for i=1:length(t) -% if ~isempty(t{i}) -% trend_coeff(i) = evalin('base',t{i}); -% end -% end -% trend = repmat(constant,1,DynareDataset.info.ntobs)+trend_coeff*[1:DynareDataset.info.ntobs]; -%else -% trend = repmat(constant,1,DynareDataset.info.ntobs); -%end - -% Get needed informations for kalman filter routines. -start = DynareOptions.presample+1; -np = size(T,1); -mf = BayesInfo.mf; -Y = transpose(DynareDataset.data); - -%------------------------------------------------------------------------------ -% 3. Initial condition of the Kalman filter -%------------------------------------------------------------------------------ - % Get decision rules and transition equations. dr = DynareResults.dr; @@ -295,37 +144,37 @@ if isempty(init_flag) mf0 = BayesInfo.mf0; mf1 = BayesInfo.mf1; restrict_variables_idx = dr.restrict_var_list; - observed_variables_idx = restrict_variables_idx(mf1); - state_variables_idx = restrict_variables_idx(mf0); - sample_size = size(Y,2); + state_variables_idx = restrict_variables_idx(mf0); number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(Q); - init_flag = 1; + init_flag = true; end -ReducedForm.ghx = dr.ghx(restrict_variables_idx,:); -ReducedForm.ghu = dr.ghu(restrict_variables_idx,:); -ReducedForm.steadystate = dr.ys(dr.order_var(restrict_variables_idx)); -if DynareOptions.order>1 - ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); - ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); - ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); - ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); -else - ReducedForm.ghxx = zeros(size(restrict_variables_idx,1),size(dr.kstate,2)); - ReducedForm.ghuu = zeros(size(restrict_variables_idx,1),size(dr.ghu,2)); - ReducedForm.ghxu = zeros(size(restrict_variables_idx,1),size(dr.ghx,2)); - ReducedForm.constant = ReducedForm.steadystate ; -end -ReducedForm.state_variables_steady_state = dr.ys(dr.order_var(state_variables_idx)); -ReducedForm.Q = Q; -ReducedForm.H = H; -ReducedForm.mf0 = mf0; -ReducedForm.mf1 = mf1; -% Set initial condition for t=1 -if observation_number==1 +% Return reduced form model. +if nargout>4 + ReducedForm.ghx = dr.ghx(restrict_variables_idx,:); + ReducedForm.ghu = dr.ghu(restrict_variables_idx,:); + ReducedForm.steadystate = dr.ys(dr.order_var(restrict_variables_idx)); + if DynareOptions.order>1 + ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); + ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); + ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); + ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); + else + ReducedForm.ghxx = zeros(size(restrict_variables_idx,1),size(dr.kstate,2)); + ReducedForm.ghuu = zeros(size(restrict_variables_idx,1),size(dr.ghu,2)); + ReducedForm.ghxu = zeros(size(restrict_variables_idx,1),size(dr.ghx,2)); + ReducedForm.constant = ReducedForm.steadystate ; + end + ReducedForm.state_variables_steady_state = dr.ys(dr.order_var(state_variables_idx)); + ReducedForm.Q = Q; + ReducedForm.H = H; + ReducedForm.mf0 = mf0; + ReducedForm.mf1 = mf1; +end + +% Set initial condition +if setinitialcondition switch DynareOptions.particle.initialization case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. StateVectorMean = ReducedForm.constant(mf0); @@ -347,4 +196,4 @@ if observation_number==1 end ReducedForm.StateVectorMean = StateVectorMean; ReducedForm.StateVectorVariance = StateVectorVariance; -end +end \ No newline at end of file From 13d79cb4382ade3b74a4509fdd8ddad3d273ffaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Fri, 20 Dec 2019 11:21:13 +0100 Subject: [PATCH 072/101] Allow k order approximation in SIP filter. --- src/sequential_importance_particle_filter.m | 26 ++++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 72a789ccd..526ee825f 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -1,4 +1,4 @@ -function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) +function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions, DynareOptions, Model) % Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). @@ -49,14 +49,18 @@ if isempty(init_flag) init_flag = 1; end -% Set local state space model (first order approximation). -ghx = ReducedForm.ghx; -ghu = ReducedForm.ghu; +if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; +else + % Set local state space model (first order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; -% Set local state space model (second order approximation). -ghxx = ReducedForm.ghxx; -ghuu = ReducedForm.ghuu; -ghxu = ReducedForm.ghxu; + % Set local state space model (second order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; +end % Get covariance matrices. Q = ReducedForm.Q; % Covariance matrix of the structural innovations. @@ -101,7 +105,11 @@ for t=1:sample_size yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + else + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + end end %PredictedObservedMean = tmp(mf1,:)*transpose(weights); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); From 8eaccada384548fe52ff1e0591955fae65dfe403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Sat, 21 Dec 2019 10:37:48 +0100 Subject: [PATCH 073/101] Allow k order approximation in Auxiliary Particle Filter. Ref. dynare#1673 --- src/auxiliary_particle_filter.m | 79 +++++++++++++++------------------ 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 61a43bc13..905a569d2 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -1,9 +1,9 @@ -function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) +function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions, DynareOptions, Model) % Evaluates the likelihood of a nonlinear model with the auxiliary particle filter % allowing eventually resampling. % -% Copyright (C) 2011-2017 Dynare Team +% Copyright (C) 2011-2019 Dynare Team % % This file is part of Dynare (particles module). % @@ -20,9 +20,6 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptio % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -persistent init_flag mf0 mf1 number_of_particles -persistent sample_size number_of_observed_variables number_of_structural_innovations - % Set default if isempty(start) start = 1; @@ -36,24 +33,24 @@ steadystate = ReducedForm.steadystate; constant = ReducedForm.constant; state_variables_steady_state = ReducedForm.state_variables_steady_state; -% Set persistent variables. -if isempty(init_flag) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - sample_size = size(Y,2); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - number_of_particles = ParticleOptions.number_of_particles; - init_flag = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +sample_size = size(Y,2); +number_of_observed_variables = length(mf1); +number_of_structural_innovations = length(ReducedForm.Q); +number_of_particles = ParticleOptions.number_of_particles; -% Set local state space model (first order approximation). -ghx = ReducedForm.ghx; -ghu = ReducedForm.ghu; -% Set local state space model (second order approximation). -ghxx = ReducedForm.ghxx; -ghuu = ReducedForm.ghuu; -ghxu = ReducedForm.ghxu; +if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; +else + % Set local state space model (first order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + % Set local state space model (second order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; +end % Get covariance matrices Q = ReducedForm.Q; @@ -81,19 +78,6 @@ if pruning StateVectors_ = StateVectors; end -% Uncomment for building the mean average predictions based on a sparse -% grids of structural shocks. Otherwise, all shocks are set to 0 in the -% prediction. -% if ParticleOptions.proposal_approximation.cubature -% [nodes,nodes_weights] = spherical_radial_sigma_points(number_of_structural_innovations) ; -% nodes_weights = ones(size(nodes,1),1)*nodes_weights ; -% elseif ParticleOptions.proposal_approximation.unscented -% [nodes,nodes_weights,nodes_weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); -% else -% error('Estimation: This approximation for the proposal is not implemented or unknown!') -% end -% nodes = (Q_lower_triangular_cholesky*(nodes'))' ; - nodes = zeros(1,number_of_structural_innovations) ; nodes_weights = ones(number_of_structural_innovations,1) ; @@ -109,15 +93,19 @@ for t=1:sample_size tmp_ = tmp_ + nodes_weights(i)*tmp1_ ; end else - tmp = 0 ; - for i=1:size(nodes) - tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)'*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + if ReducedForm.use_k_order_solver + tmp = 0; + for i=1:size(nodes) + tmp = tmp + nodes_weights(i)*local_state_space_iteration_k(yhat, nodes(i,:)'*ones(1,number_of_particles), dr, Model, DynareOptions); + end + else + tmp = 0; + for i=1:size(nodes) + tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)'*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + end end end PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); - %tau_tilde = weights.*(exp(-.5*(const_lik+sum(PredictionError.*(H\PredictionError),1))) + 1e-99) ; - % Replace Gaussian density with a Student density with 3 degrees of - % freedom for fat tails. z = sum(PredictionError.*(H\PredictionError),1) ; tau_tilde = weights.*(tpdf(z,3*ones(size(z)))+1e-99) ; tau_tilde = tau_tilde/sum(tau_tilde) ; @@ -132,7 +120,11 @@ for t=1:sample_size [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); StateVectors_ = tmp_(mf0,:); else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + else + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + end end StateVectors = tmp(mf0,:); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); @@ -151,5 +143,4 @@ for t=1:sample_size end end -%plot(lik) ; -LIK = -sum(lik(start:end)); +LIK = -sum(lik(start:end)); \ No newline at end of file From 89a941605ffd90829a02ff4481a2f68edfd344af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Sat, 21 Dec 2019 10:44:23 +0100 Subject: [PATCH 074/101] Allow k order approximation in nonlinear Kalman Filter (nlkf). Ref. dynare#1673 --- src/nonlinear_kalman_filter.m | 83 +++++++++++++++-------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index cf4339473..9f9d729c5 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -1,4 +1,5 @@ -function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions) +function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions, DynareOptions, Model) + % Evaluates the likelihood of a non-linear model approximating the % predictive (prior) and filtered (posterior) densities for state variables % by a Kalman filter. @@ -30,7 +31,8 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2017 Dynare Team + +% Copyright (C) 2009-2019 Dynare Team % % This file is part of Dynare. % @@ -47,55 +49,41 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -persistent init_flag mf0 mf1 nodes weights weights_c -persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations - % Set default if isempty(start) start = 1; end -% Set local state space model (first-order approximation). -ghx = ReducedForm.ghx; -ghu = ReducedForm.ghu; -% Set local state space model (second-order approximation). -ghxx = ReducedForm.ghxx; -ghuu = ReducedForm.ghuu; -ghxu = ReducedForm.ghxu; - -if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... - any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... - any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) - ghx - ghu - ghxx - ghuu - ghxu +if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; +else + % Set local state space model (first-order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + % Set local state space model (second-order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; end constant = ReducedForm.constant; state_variables_steady_state = ReducedForm.state_variables_steady_state; -% Set persistent variables. -if isempty(init_flag) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - sample_size = size(Y,2); - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - init_flag = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +sample_size = size(Y,2); +number_of_state_variables = length(mf0); +number_of_observed_variables = length(mf1); +number_of_structural_innovations = length(ReducedForm.Q); % compute gaussian quadrature nodes and weights on states and shocks - if ParticleOptions.proposal_approximation.montecarlo - nodes = randn(ParticleOptions.number_of_particles,number_of_state_variables+number_of_structural_innovations) ; - weights = 1/ParticleOptions.number_of_particles ; - weights_c = weights ; + nodes = randn(ParticleOptions.number_of_particles,number_of_state_variables+number_of_structural_innovations); + weights = 1/ParticleOptions.number_of_particles; + weights_c = weights; elseif ParticleOptions.proposal_approximation.cubature - [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations) ; - weights_c = weights ; + [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations); + weights_c = weights; elseif ParticleOptions.proposal_approximation.unscented [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables+number_of_structural_innovations,ParticleOptions); else @@ -120,27 +108,28 @@ lik = NaN(sample_size,1); LIK = NaN; for t=1:sample_size - xbar = [StateVectorMean ; zeros(number_of_structural_innovations,1) ] ; - sqr_Px = [ [ StateVectorVarianceSquareRoot zeros(number_of_state_variables,number_of_structural_innovations) ] ; - [ zeros(number_of_structural_innovations,number_of_state_variables) Q_lower_triangular_cholesky ] ]; + sqr_Px = [StateVectorVarianceSquareRoot zeros(number_of_state_variables,number_of_structural_innovations); + zeros(number_of_structural_innovations,number_of_state_variables) Q_lower_triangular_cholesky]; sigma_points = bsxfun(@plus,xbar,sqr_Px*(nodes')); StateVectors = sigma_points(1:number_of_state_variables,:); epsilon = sigma_points(number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations,:); yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + else + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + end PredictedStateMean = tmp(mf0,:)*weights ; PredictedObservedMean = tmp(mf1,:)*weights; - if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo PredictedStateMean = sum(PredictedStateMean,2); PredictedObservedMean = sum(PredictedObservedMean,2); dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights); dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)'.*sqrt(weights); big_mat = [dObserved dState ; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; - [mat1,mat] = qr2(big_mat,0); + [~, mat] = qr2(big_mat,0); mat = mat'; - clear('mat1'); PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); @@ -162,16 +151,14 @@ for t=1:sample_size lik(t)=-Inf; return end - [PredictedObservedVarianceSquareRoot, p]= chol(PredictedObservedVariance,'lower'); + [~, p]= chol(PredictedObservedVariance,'lower'); if p LIK=-Inf; lik(t)=-Inf; return end end -% lik(t) = log( probability2(0,PredictedObservedVarianceSquareRoot,PredictionError) ) ; lik(t) = log( sum(probability2(Y(:,t),H_lower_triangular_cholesky,tmp(mf1,:)).*weights,1) ) ; -% lik(t) = log(sum(probability2(Y(:,t),PredictedObservedVarianceSquareRoot,tmp(mf1,:)).*weights,1) ) ; end -LIK = -sum(lik(start:end)); +LIK = -sum(lik(start:end)); \ No newline at end of file From 472d755d984f8caf688d49621e70f52e3346213d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Sat, 21 Dec 2019 12:06:41 +0100 Subject: [PATCH 075/101] Allow k order approximation in Gaussian Filter (gf). Ref. dynare#1673 --- src/gaussian_densities.m | 25 +++++----- src/gaussian_filter.m | 95 +++++++++++++++++-------------------- src/gaussian_filter_bank.m | 93 +++++++++++++++++------------------- src/measurement_equations.m | 27 +++++++---- 4 files changed, 115 insertions(+), 125 deletions(-) diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index f1c595100..64128cf58 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -1,4 +1,4 @@ -function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) +function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sqr_Pss_t_t_1,particles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions,DynareOptions, Model) % % Elements to calculate the importance sampling ratio % @@ -19,7 +19,8 @@ function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sq % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2017 Dynare Team + +% Copyright (C) 2009-2019 Dynare Team % % This file is part of Dynare. % @@ -37,17 +38,13 @@ function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sq % along with Dynare. If not, see . % proposal density -proposal = probability2(mut_t,sqr_Pss_t_t,particles) ; +proposal = probability2(mut_t, sqr_Pss_t_t, particles); + % prior density -prior = probability2(st_t_1,sqr_Pss_t_t_1,particles) ; +prior = probability2(st_t_1, sqr_Pss_t_t_1, particles); + % likelihood -yt_t_1_i = measurement_equations(particles,ReducedForm,ThreadsOptions) ; -%eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; -%yt_t_1 = sum(yt_t_1_i*weigths1,2) ; -%tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; -%Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; -%sqr_det = sqrt(det(Pyy)) ; -%foo = (eta_t_i/Pyy).*eta_t_i ; -%likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; -likelihood = probability2(obs,sqrt(H),yt_t_1_i) ; -IncrementalWeights = likelihood.*prior./proposal ; +yt_t_1_i = measurement_equations(particles, ReducedForm, ThreadsOptions, DynareOptions, Model); +likelihood = probability2(obs, sqrt(H), yt_t_1_i); + +IncrementalWeights = likelihood.*prior./proposal; diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index e885cce72..29cc021e0 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -1,4 +1,5 @@ -function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions) +function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions, DynareOptions, Model) + % Evaluates the likelihood of a non-linear model approximating the % predictive (prior) and filtered (posterior) densities for state variables % by gaussian distributions. @@ -30,7 +31,8 @@ function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, Thr % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2017 Dynare Team + +% Copyright (C) 2009-2019 Dynare Team % % This file is part of Dynare. % @@ -47,37 +49,27 @@ function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, Thr % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -persistent init_flag mf0 mf1 -persistent nodes2 weights2 weights_c2 number_of_particles -persistent sample_size number_of_state_variables number_of_observed_variables - % Set default if isempty(start) start = 1; end -% Set persistent variables. -if isempty(init_flag) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - sample_size = size(Y,2); - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_particles = ParticleOptions.number_of_particles; - init_flag = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +sample_size = size(Y,2); +number_of_state_variables = length(mf0); +number_of_observed_variables = length(mf1); +number_of_particles = ParticleOptions.number_of_particles; % compute gaussian quadrature nodes and weights on states and shocks -if isempty(nodes2) - if ParticleOptions.distribution_approximation.cubature - [nodes2,weights2] = spherical_radial_sigma_points(number_of_state_variables); - weights_c2 = weights2; - elseif ParticleOptions.distribution_approximation.unscented - [nodes2,weights2,weights_c2] = unscented_sigma_points(number_of_state_variables,ParticleOptions); - else - if ~ParticleOptions.distribution_approximation.montecarlo - error('Estimation: This approximation for the proposal is not implemented or unknown!') - end +if ParticleOptions.distribution_approximation.cubature + [nodes2, weights2] = spherical_radial_sigma_points(number_of_state_variables); + weights_c2 = weights2; +elseif ParticleOptions.distribution_approximation.unscented + [nodes2, weights2, weights_c2] = unscented_sigma_points(number_of_state_variables,ParticleOptions); +else + if ~ParticleOptions.distribution_approximation.montecarlo + error('This approximation for the proposal is unknown!') end end @@ -107,38 +99,37 @@ lik = NaN(sample_size,1); LIK = NaN; for t=1:sample_size - [PredictedStateMean,PredictedStateVarianceSquareRoot,StateVectorMean,StateVectorVarianceSquareRoot] = ... - gaussian_filter_bank(ReducedForm,Y(:,t),StateVectorMean,StateVectorVarianceSquareRoot,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions) ; + [PredictedStateMean, PredictedStateVarianceSquareRoot, StateVectorMean, StateVectorVarianceSquareRoot] = ... + gaussian_filter_bank(ReducedForm, Y(:,t), StateVectorMean, StateVectorVarianceSquareRoot, Q_lower_triangular_cholesky, H_lower_triangular_cholesky, ... + H, ParticleOptions, ThreadsOptions, DynareOptions, Model); if ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented - StateParticles = bsxfun(@plus,StateVectorMean,StateVectorVarianceSquareRoot*nodes2') ; - IncrementalWeights = ... - gaussian_densities(Y(:,t),StateVectorMean,... - StateVectorVarianceSquareRoot,PredictedStateMean,... - PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - weights2,weights_c2,ReducedForm,ThreadsOptions) ; - SampleWeights = weights2.*IncrementalWeights ; + StateParticles = bsxfun(@plus, StateVectorMean, StateVectorVarianceSquareRoot*nodes2'); + IncrementalWeights = gaussian_densities(Y(:,t), StateVectorMean, StateVectorVarianceSquareRoot, PredictedStateMean, ... + PredictedStateVarianceSquareRoot, StateParticles, H, const_lik, ... + weights2, weights_c2, ReducedForm, ThreadsOptions, ... + DynareOptions, Model); + SampleWeights = weights2.*IncrementalWeights; else - StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean) ; - IncrementalWeights = ... - gaussian_densities(Y(:,t),StateVectorMean,... - StateVectorVarianceSquareRoot,PredictedStateMean,... - PredictedStateVarianceSquareRoot,StateParticles,H,const_lik,... - 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions) ; - SampleWeights = IncrementalWeights/number_of_particles ; + StateParticles = bsxfun(@plus, StateVectorVarianceSquareRoot*randn(state_variance_rank, number_of_particles), StateVectorMean) ; + IncrementalWeights = gaussian_densities(Y(:,t), StateVectorMean, StateVectorVarianceSquareRoot, PredictedStateMean, ... + PredictedStateVarianceSquareRoot,StateParticles,H,const_lik, ... + 1/number_of_particles,1/number_of_particles,ReducedForm,ThreadsOptions, ... + DynareOptions, Model); + SampleWeights = IncrementalWeights/number_of_particles; end - SampleWeights = SampleWeights + 1e-6*ones(size(SampleWeights,1),1) ; - SumSampleWeights = sum(SampleWeights) ; - lik(t) = log(SumSampleWeights) ; - SampleWeights = SampleWeights./SumSampleWeights ; + SampleWeights = SampleWeights + 1e-6*ones(size(SampleWeights, 1), 1); + SumSampleWeights = sum(SampleWeights); + lik(t) = log(SumSampleWeights); + SampleWeights = SampleWeights./SumSampleWeights; if not(ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented) if (ParticleOptions.resampling.status.generic && neff(SampleWeights). -persistent init_flag2 mf0 mf1 -persistent number_of_state_variables number_of_observed_variables -persistent number_of_structural_innovations - -% Set local state space model (first-order approximation). -ghx = ReducedForm.ghx; -ghu = ReducedForm.ghu; -% Set local state space model (second-order approximation). -ghxx = ReducedForm.ghxx; -ghuu = ReducedForm.ghuu; -ghxu = ReducedForm.ghxu; - -if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... - any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... - any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) - ghx - ghu - ghxx - ghuu - ghxu +if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; +else + % Set local state space model (first-order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + % Set local state space model (second-order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; end constant = ReducedForm.constant; state_variables_steady_state = ReducedForm.state_variables_steady_state; -% Set persistent variables. -if isempty(init_flag2) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - init_flag2 = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +number_of_state_variables = length(mf0); +number_of_observed_variables = length(mf1); +number_of_structural_innovations = length(ReducedForm.Q); if ParticleOptions.proposal_approximation.montecarlo - nodes = randn(ParticleOptions.number_of_particles,number_of_state_variables+number_of_structural_innovations) ; + nodes = randn(ParticleOptions.number_of_particles, number_of_state_variables+number_of_structural_innovations) ; weights = 1/ParticleOptions.number_of_particles ; weights_c = weights ; elseif ParticleOptions.proposal_approximation.cubature [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables+number_of_structural_innovations) ; weights_c = weights ; elseif ParticleOptions.proposal_approximation.unscented - [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables+number_of_structural_innovations,ParticleOptions); + [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables+number_of_structural_innovations, ParticleOptions); else - error('Estimation: This approximation for the proposal is not implemented or unknown!') + error('This approximation for the proposal is not implemented or unknown!') end -xbar = [StateVectorMean ; zeros(number_of_structural_innovations,1) ] ; -sqr_Px = [ [ StateVectorVarianceSquareRoot zeros(number_of_state_variables,number_of_structural_innovations) ] ; - [ zeros(number_of_structural_innovations,number_of_state_variables) Q_lower_triangular_cholesky ] ]; -sigma_points = bsxfun(@plus,xbar,sqr_Px*(nodes')); +xbar = [StateVectorMean ; zeros(number_of_structural_innovations,1)] ; +sqr_Px = [ StateVectorVarianceSquareRoot, zeros(number_of_state_variables, number_of_structural_innovations); + zeros(number_of_structural_innovations, number_of_state_variables) Q_lower_triangular_cholesky]; +sigma_points = bsxfun(@plus, xbar, sqr_Px*(nodes')); StateVectors = sigma_points(1:number_of_state_variables,:); epsilon = sigma_points(number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations,:); -yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); -tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); -PredictedStateMean = tmp(mf0,:)*weights ; +yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); +if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); +else + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); +end + +PredictedStateMean = tmp(mf0,:)*weights; PredictedObservedMean = tmp(mf1,:)*weights; if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo - PredictedStateMean = sum(PredictedStateMean,2); - PredictedObservedMean = sum(PredictedObservedMean,2); - dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights); - dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)'.*sqrt(weights); + PredictedStateMean = sum(PredictedStateMean, 2); + PredictedObservedMean = sum(PredictedObservedMean, 2); + dState = bsxfun(@minus,tmp(mf0,:), PredictedStateMean)'.*sqrt(weights); + dObserved = bsxfun(@minus, tmp(mf1,:), PredictedObservedMean)'.*sqrt(weights); PredictedStateVarianceSquareRoot = chol(dState'*dState)'; - big_mat = [dObserved dState ; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; - [mat1,mat] = qr2(big_mat,0); + big_mat = [dObserved, dState ; H_lower_triangular_cholesky, zeros(number_of_observed_variables,number_of_state_variables)]; + [~, mat] = qr2(big_mat, 0); mat = mat'; - clear('mat1'); PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); PredictionError = obs - PredictedObservedMean; StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*PredictionError; else - dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); - dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + dState = bsxfun(@minus, tmp(mf0,:), PredictedStateMean); + dObserved = bsxfun(@minus, tmp(mf1,:), PredictedObservedMean); PredictedStateVariance = dState*diag(weights_c)*dState'; PredictedObservedVariance = dObserved*diag(weights_c)*dObserved' + H; PredictedStateAndObservedCovariance = dState*diag(weights_c)*dObserved'; @@ -123,4 +116,4 @@ else StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; -end +end \ No newline at end of file diff --git a/src/measurement_equations.m b/src/measurement_equations.m index 1c386b6fd..e450d1c11 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -1,6 +1,6 @@ -function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions) +function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions, DynareOptions, Model) -% Copyright (C) 2013-2017 Dynare Team +% Copyright (C) 2013-2019 Dynare Team % % This file is part of Dynare. % @@ -18,13 +18,22 @@ function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions % along with Dynare. If not, see . mf1 = ReducedForm.mf1; -ghx = ReducedForm.ghx(mf1,:); -ghu = ReducedForm.ghu(mf1,:); -ghxx = ReducedForm.ghxx(mf1,:); -ghuu = ReducedForm.ghuu(mf1,:); -ghxu = ReducedForm.ghxu(mf1,:); +if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; +else + ghx = ReducedForm.ghx(mf1,:); + ghu = ReducedForm.ghu(mf1,:); + ghxx = ReducedForm.ghxx(mf1,:); + ghuu = ReducedForm.ghuu(mf1,:); + ghxu = ReducedForm.ghxu(mf1,:); +end constant = ReducedForm.constant(mf1,:); state_variables_steady_state = ReducedForm.state_variables_steady_state; number_of_structural_innovations = length(ReducedForm.Q); -yhat = bsxfun(@minus,StateVectors,state_variables_steady_state) ; -measure = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,size(yhat,2)),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); +if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, size(yhat,2)), dr, Model, DynareOptions); + measure = tmp(mf1,:); +else + measure = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); +end \ No newline at end of file From 313003b1458223d75ed1419749a8ab52b62c5387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Mon, 23 Dec 2019 17:25:43 +0100 Subject: [PATCH 076/101] Allow k order approximation in Gaussian Mixture Filter (gmf). Ref. dynare#1673 --- src/gaussian_mixture_densities.m | 36 ++-- src/gaussian_mixture_filter.m | 283 +++++++++-------------------- src/gaussian_mixture_filter_bank.m | 108 +++++------ 3 files changed, 155 insertions(+), 272 deletions(-) diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m index cd4f6b58e..9e4851093 100644 --- a/src/gaussian_mixture_densities.m +++ b/src/gaussian_mixture_densities.m @@ -1,7 +1,7 @@ -function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... - StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,normconst,weigths1,weigths2,ReducedForm,ThreadsOptions) -% +function IncrementalWeights = gaussian_mixture_densities(obs, StateMuPrior, StateSqrtPPrior, StateWeightsPrior, ... + StateMuPost, StateSqrtPPost, StateWeightsPost, StateParticles, H, ... + ReducedForm, ThreadsOptions, DynareOptions, Model) + % Elements to calculate the importance sampling ratio % % INPUTS @@ -21,7 +21,8 @@ function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,State % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2017 Dynare Team + +% Copyright (C) 2009-2019 Dynare Team % % This file is part of Dynare. % @@ -39,19 +40,16 @@ function IncrementalWeights = gaussian_mixture_densities(obs,StateMuPrior,State % along with Dynare. If not, see . % Compute the density of particles under the prior distribution -[ras,ras,prior] = probability(StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateParticles) ; -prior = prior' ; +[~, ~, prior] = probability(StateMuPrior, StateSqrtPPrior, StateWeightsPrior, StateParticles); +prior = prior'; + % Compute the density of particles under the proposal distribution -[ras,ras,proposal] = probability(StateMuPost,StateSqrtPPost,StateWeightsPost,StateParticles) ; -proposal = proposal' ; +[~, ~, proposal] = probability(StateMuPost, StateSqrtPPost, StateWeightsPost, StateParticles); +proposal = proposal'; + % Compute the density of the current observation conditionally to each particle -yt_t_1_i = measurement_equations(StateParticles,ReducedForm,ThreadsOptions) ; -%eta_t_i = bsxfun(@minus,obs,yt_t_1_i)' ; -%yt_t_1 = sum(yt_t_1_i*weigths1,2) ; -%tmp = bsxfun(@minus,yt_t_1_i,yt_t_1) ; -%Pyy = bsxfun(@times,weigths2',tmp)*tmp' + H ; -%sqr_det = sqrt(det(Pyy)) ; -%foo = (eta_t_i/Pyy).*eta_t_i ; -%likelihood = exp(-0.5*sum(foo,2))/(normconst*sqr_det) + 1e-99 ; -likelihood = probability2(obs,sqrt(H),yt_t_1_i) ; -IncrementalWeights = likelihood.*prior./proposal ; +yt_t_1_i = measurement_equations(StateParticles, ReducedForm, ThreadsOptions, DynareOptions, Model); + +% likelihood +likelihood = probability2(obs, sqrt(H), yt_t_1_i); +IncrementalWeights = likelihood.*prior./proposal; diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index f744210d8..65c16995d 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -1,4 +1,5 @@ -function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) +function [LIK, lik] = gaussian_mixture_filter(ReducedForm, Y, start, ParticleOptions, ThreadsOptions, DynareOptions, Model) + % Evaluates the likelihood of a non-linear model approximating the state % variables distributions with gaussian mixtures. Gaussian Mixture allows reproducing % a wide variety of generalized distributions (when multimodal for instance). @@ -52,45 +53,33 @@ function [LIK,lik] = gaussian_mixture_filter(ReducedForm,Y,start,ParticleOptions % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -persistent init_flag mf0 mf1 -persistent nodes weights weights_c I J G number_of_particles -persistent sample_size number_of_state_variables number_of_observed_variables number_of_structural_innovations - % Set default if isempty(start) start = 1; end -% Set persistent variables. -if isempty(init_flag) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - sample_size = size(Y,2); - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - G = ParticleOptions.mixture_state_variables; % number of GM components in state - number_of_particles = ParticleOptions.number_of_particles; - init_flag = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +sample_size = size(Y,2); +number_of_state_variables = length(mf0); +number_of_observed_variables = length(mf1); +number_of_structural_innovations = length(ReducedForm.Q); +G = ParticleOptions.mixture_state_variables; % number of GM components in state +number_of_particles = ParticleOptions.number_of_particles; % compute gaussian quadrature nodes and weights on states and shocks -if isempty(nodes) - if ParticleOptions.distribution_approximation.cubature - [nodes,weights] = spherical_radial_sigma_points(number_of_state_variables); - weights_c = weights; - elseif ParticleOptions.distribution_approximation.unscented - [nodes,weights,weights_c] = unscented_sigma_points(number_of_state_variables,ParticleOptions); - else - if ~ParticleOptions.distribution_approximation.montecarlo - error('Estimation: This approximation for the proposal is not implemented or unknown!') - end +if ParticleOptions.distribution_approximation.cubature + [nodes, weights] = spherical_radial_sigma_points(number_of_state_variables); +elseif ParticleOptions.distribution_approximation.unscented + [nodes, weights] = unscented_sigma_points(number_of_state_variables, ParticleOptions); +else + if ~ParticleOptions.distribution_approximation.montecarlo + error('This approximation for the proposal is unknown!') end end if ParticleOptions.distribution_approximation.montecarlo set_dynare_seed('default'); - SampleWeights = 1/number_of_particles ; end % Get covariance matrices @@ -105,225 +94,133 @@ end Q_lower_triangular_cholesky = reduced_rank_cholesky(Q)'; % Initialize mixtures -StateWeights = ones(1,G)/G ; -StateMu = ReducedForm.StateVectorMean ; -StateSqrtP = zeros(number_of_state_variables,number_of_state_variables,G) ; -temp = reduced_rank_cholesky(ReducedForm.StateVectorVariance)' ; -StateMu = bsxfun(@plus,StateMu,bsxfun(@times,diag(temp),(-(G-1)/2:1:(G-1)/2))/10) ; +StateWeights = ones(1, G)/G; +StateMu = ReducedForm.StateVectorMean; +StateSqrtP = zeros(number_of_state_variables, number_of_state_variables, G); +temp = reduced_rank_cholesky(ReducedForm.StateVectorVariance)'; +StateMu = bsxfun(@plus, StateMu, bsxfun(@times,diag(temp), (-(G-1)/2:1:(G-1)/2))/10); for g=1:G StateSqrtP(:,:,g) = temp/sqrt(G) ; end -% if ParticleOptions.mixture_structural_shocks==1 -% StructuralShocksMu = zeros(1,number_of_structural_innovations) ; -% StructuralShocksWeights = 1 ; -% else -% if ParticleOptions.proposal_approximation.cubature -% [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); -% StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; -% elseif ParticleOptions.proposal_approximation.unscented -% [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); -% else -% if ~ParticleOptions.distribution_approximation.montecarlo -% error('Estimation: This approximation for the proposal is not implemented or unknown!') -% end -% end -% end -% I = size(StructuralShocksWeights,1) ; -% StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; -% StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; -% for i=1:I -% StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; -% end -% -% if ParticleOptions.mixture_measurement_shocks==1 -% ObservationShocksMu = zeros(1,number_of_observed_variables) ; -% ObservationShocksWeights = 1 ; -% else -% if ParticleOptions.proposal_approximation.cubature -% [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); -% ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; -% elseif ParticleOptions.proposal_approximation.unscented -% [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); -% else -% if ~ParticleOptions.distribution_approximation.montecarlo -% error('Estimation: This approximation for the proposal is not implemented or unknown!') -% end -% end -% end -% J = size(ObservationShocksWeights,1) ; -% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; -% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; -% for j=1:J -% ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky/sqrt(ObservationShocksWeights(j)) ; -% end - -if ParticleOptions.mixture_structural_shocks==0 - StructuralShocksMu = zeros(1,number_of_structural_innovations) ; - StructuralShocksWeights = 1 ; - I = 1 ; - StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; - StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; - StructuralShocksSqrtP(:,:,1) = Q_lower_triangular_cholesky ; +if ~ParticleOptions.mixture_structural_shocks + StructuralShocksMu = zeros(1, number_of_structural_innovations); + StructuralShocksWeights = 1; + I = 1; + StructuralShocksMu = Q_lower_triangular_cholesky*StructuralShocksMu'; + StructuralShocksSqrtP = zeros(number_of_structural_innovations, number_of_structural_innovations, I); + StructuralShocksSqrtP(:,:,1) = Q_lower_triangular_cholesky; elseif ParticleOptions.mixture_structural_shocks==1 if ParticleOptions.proposal_approximation.cubature - [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); - StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; + [StructuralShocksMu, StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); + StructuralShocksWeights = ones(size(StructuralShocksMu, 1), 1)*StructuralShocksWeights; elseif ParticleOptions.proposal_approximation.unscented - [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); + [StructuralShocksMu, StructuralShocksWeights] = unscented_sigma_points(number_of_structural_innovations, ParticleOptions); else if ~ParticleOptions.distribution_approximation.montecarlo - error('Estimation: This approximation for the proposal is not implemented or unknown!') + error('This approximation for the proposal is unknown!') end end - I = size(StructuralShocksWeights,1) ; - StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; - StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; + I = size(StructuralShocksWeights, 1); + StructuralShocksMu = Q_lower_triangular_cholesky*StructuralShocksMu'; + StructuralShocksSqrtP = zeros(number_of_structural_innovations, number_of_structural_innovations, I); for i=1:I - StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky ; + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky; end else if ParticleOptions.proposal_approximation.cubature - [StructuralShocksMu,StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); - StructuralShocksWeights = ones(size(StructuralShocksMu,1),1)*StructuralShocksWeights ; + [StructuralShocksMu, StructuralShocksWeights] = spherical_radial_sigma_points(number_of_structural_innovations); + StructuralShocksWeights = ones(size(StructuralShocksMu, 1), 1)*StructuralShocksWeights ; elseif ParticleOptions.proposal_approximation.unscented - [StructuralShocksMu,StructuralShocksWeights,raf] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); + [StructuralShocksMu, StructuralShocksWeights] = unscented_sigma_points(number_of_structural_innovations, ParticleOptions); else if ~ParticleOptions.distribution_approximation.montecarlo - error('Estimation: This approximation for the proposal is not implemented or unknown!') + error('This approximation for the proposal is unknown!') end end - I = size(StructuralShocksWeights,1) ; - StructuralShocksMu = Q_lower_triangular_cholesky*(StructuralShocksMu') ; - StructuralShocksSqrtP = zeros(number_of_structural_innovations,number_of_structural_innovations,I) ; + I = size(StructuralShocksWeights, 1); + StructuralShocksMu = Q_lower_triangular_cholesky*StructuralShocksMu'; + StructuralShocksSqrtP = zeros(number_of_structural_innovations, number_of_structural_innovations, I); for i=1:I - StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)) ; + StructuralShocksSqrtP(:,:,i) = Q_lower_triangular_cholesky/sqrt(StructuralShocksWeights(i)); end end -ObservationShocksMu = zeros(1,number_of_observed_variables) ; -ObservationShocksWeights = 1 ; +ObservationShocksWeights = 1; J = 1 ; -ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; -ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; -ObservationShocksSqrtP(:,:,1) = H_lower_triangular_cholesky ; -% if ParticleOptions.mixture_measurement_shocks==0 -% ObservationShocksMu = zeros(1,number_of_observed_variables) ; -% ObservationShocksWeights = 1 ; -% J = 1 ; -% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; -% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; -% ObservationShocksSqrtP(:,:,1) = H_lower_triangular_cholesky ; -% elseif ParticleOptions.mixture_measurement_shocks==1 -% if ParticleOptions.proposal_approximation.cubature -% [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); -% ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; -% elseif ParticleOptions.proposal_approximation.unscented -% [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); -% else -% if ~ParticleOptions.distribution_approximation.montecarlo -% error('Estimation: This approximation for the proposal is not implemented or unknown!') -% end -% end -% J = size(ObservationShocksWeights,1) ; -% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; -% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; -% for j=1:J -% ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky ; -% end -% else -% if ParticleOptions.proposal_approximation.cubature -% [ObservationShocksMu,ObservationShocksWeights] = spherical_radial_sigma_points(number_of_observed_variables); -% ObservationShocksWeights = ones(size(ObservationShocksMu,1),1)*ObservationShocksWeights; -% elseif ParticleOptions.proposal_approximation.unscented -% [ObservationShocksMu,ObservationShocksWeights,raf] = unscented_sigma_points(number_of_observed_variables,ParticleOptions); -% else -% if ~ParticleOptions.distribution_approximation.montecarlo -% error('Estimation: This approximation for the proposal is not implemented or unknown!') -% end -% end -% J = size(ObservationShocksWeights,1) ; -% ObservationShocksMu = H_lower_triangular_cholesky*(ObservationShocksMu') ; -% ObservationShocksSqrtP = zeros(number_of_observed_variables,number_of_observed_variables,J) ; -% for j=1:J -% ObservationShocksSqrtP(:,:,j) = H_lower_triangular_cholesky/sqrt(ObservationShocksWeights(j)) ; -% end -% end +Gprime = G*I; +Gsecond = G*I*J; +SampleWeights = ones(Gsecond, 1)/Gsecond; -Gprime = G*I ; -Gsecond = G*I*J ; -SampleWeights = ones(Gsecond,1)/Gsecond ; +StateWeightsPrior = zeros(1,Gprime); +StateMuPrior = zeros(number_of_state_variables,Gprime); +StateSqrtPPrior = zeros(number_of_state_variables, number_of_state_variables, Gprime); -StateWeightsPrior = zeros(1,Gprime) ; -StateMuPrior = zeros(number_of_state_variables,Gprime) ; -StateSqrtPPrior = zeros(number_of_state_variables,number_of_state_variables,Gprime) ; +StateWeightsPost = zeros(1, Gsecond); +StateMuPost = zeros(number_of_state_variables, Gsecond); +StateSqrtPPost = zeros(number_of_state_variables, number_of_state_variables, Gsecond); -StateWeightsPost = zeros(1,Gsecond) ; -StateMuPost = zeros(number_of_state_variables,Gsecond) ; -StateSqrtPPost = zeros(number_of_state_variables,number_of_state_variables,Gsecond) ; +const_lik = (2*pi)^(.5*number_of_observed_variables); -const_lik = (2*pi)^(.5*number_of_observed_variables) ; - -lik = NaN(sample_size,1); +lik = NaN(sample_size, 1); LIK = NaN; for t=1:sample_size % Build the proposal joint quadratures of Gaussian on states, structural % shocks and observation shocks based on each combination of mixtures for i=1:I for j=1:J - for g=1:G ; - gprime = g + (i-1)*G ; - gsecond = gprime + (j-1)*Gprime ; - [StateMuPrior(:,gprime),StateSqrtPPrior(:,:,gprime),StateWeightsPrior(1,gprime),... - StateMuPost(:,gsecond),StateSqrtPPost(:,:,gsecond),StateWeightsPost(1,gsecond)] =... - gaussian_mixture_filter_bank(ReducedForm,Y(:,t),StateMu(:,g),StateSqrtP(:,:,g),StateWeights(g),... - StructuralShocksMu(:,i),StructuralShocksSqrtP(:,:,i),StructuralShocksWeights(i),... - ObservationShocksMu(:,j),ObservationShocksSqrtP(:,:,j),ObservationShocksWeights(j),... - H,H_lower_triangular_cholesky,const_lik,ParticleOptions,ThreadsOptions) ; + for g=1:G + gprime = g + (i-1)*G; + gsecond = gprime + (j-1)*Gprime; + [StateMuPrior(:,gprime), StateSqrtPPrior(:,:,gprime), StateWeightsPrior(1,gprime), ... + StateMuPost(:,gsecond), StateSqrtPPost(:,:,gsecond), StateWeightsPost(1,gsecond)] = ... + gaussian_mixture_filter_bank(ReducedForm,Y(:,t), StateMu(:,g), StateSqrtP(:,:,g), StateWeights(g),... + StructuralShocksMu(:,i), StructuralShocksSqrtP(:,:,i), StructuralShocksWeights(i),... + ObservationShocksWeights(j), H, H_lower_triangular_cholesky, const_lik, ... + ParticleOptions, ThreadsOptions, DynareOptions, Model); end end end % Normalize weights - StateWeightsPrior = StateWeightsPrior/sum(StateWeightsPrior,2) ; - StateWeightsPost = StateWeightsPost/sum(StateWeightsPost,2) ; + StateWeightsPrior = StateWeightsPrior/sum(StateWeightsPrior, 2); + StateWeightsPost = StateWeightsPost/sum(StateWeightsPost, 2); if ParticleOptions.distribution_approximation.cubature || ParticleOptions.distribution_approximation.unscented for i=1:Gsecond - StateParticles = bsxfun(@plus,StateMuPost(:,i),StateSqrtPPost(:,:,i)*nodes') ; - IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... - StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,weights,weights_c,ReducedForm,ThreadsOptions) ; - SampleWeights(i) = sum(StateWeightsPost(i)*weights.*IncrementalWeights) ; + StateParticles = bsxfun(@plus, StateMuPost(:,i), StateSqrtPPost(:,:,i)*nodes'); + IncrementalWeights = gaussian_mixture_densities(Y(:,t), StateMuPrior, StateSqrtPPrior, StateWeightsPrior, ... + StateMuPost, StateSqrtPPost, StateWeightsPost, StateParticles, H, ... + ReducedForm, ThreadsOptions, DynareOptions, Model); + SampleWeights(i) = sum(StateWeightsPost(i)*weights.*IncrementalWeights); end - SumSampleWeights = sum(SampleWeights) ; - lik(t) = log(SumSampleWeights) ; - SampleWeights = SampleWeights./SumSampleWeights ; - [ras,SortedRandomIndx] = sort(rand(1,Gsecond)); + SumSampleWeights = sum(SampleWeights); + lik(t) = log(SumSampleWeights); + SampleWeights = SampleWeights./SumSampleWeights; + [~, SortedRandomIndx] = sort(rand(1,Gsecond)); SortedRandomIndx = SortedRandomIndx(1:G); - indx = resample(0,SampleWeights,ParticleOptions) ; - indx = indx(SortedRandomIndx) ; + indx = resample(0,SampleWeights,ParticleOptions); + indx = indx(SortedRandomIndx); StateMu = StateMuPost(:,indx); StateSqrtP = StateSqrtPPost(:,:,indx); - StateWeights = ones(1,G)/G ; + StateWeights = ones(1,G)/G; else % Sample particle in the proposal distribution, ie the posterior state GM - StateParticles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost',number_of_particles) ; - IncrementalWeights = gaussian_mixture_densities(Y(:,t),StateMuPrior,StateSqrtPPrior,StateWeightsPrior,... - StateMuPost,StateSqrtPPost,StateWeightsPost,... - StateParticles,H,const_lik,1/number_of_particles,... - 1/number_of_particles,ReducedForm,ThreadsOptions) ; - SampleWeights = IncrementalWeights/number_of_particles ; - SumSampleWeights = sum(SampleWeights,1) ; - SampleWeights = SampleWeights./SumSampleWeights ; - lik(t) = log(SumSampleWeights) ; + StateParticles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost',number_of_particles); + IncrementalWeights = gaussian_mixture_densities(Y(:,t), StateMuPrior, StateSqrtPPrior, StateWeightsPrior, ... + StateMuPost, StateSqrtPPost, StateWeightsPost, StateParticles, H, ... + ReducedForm, ThreadsOptions, DynareOptions, Model); + SampleWeights = IncrementalWeights/number_of_particles; + SumSampleWeights = sum(SampleWeights,1); + SampleWeights = SampleWeights./SumSampleWeights; + lik(t) = log(SumSampleWeights); if (ParticleOptions.resampling.status.generic && neff(SampleWeights). - - -persistent init_flag2 mf0 mf1 %nodes3 weights3 weights_c3 -persistent number_of_state_variables number_of_observed_variables -persistent number_of_structural_innovations - -% Set local state space model (first-order approximation). -ghx = ReducedForm.ghx; -ghu = ReducedForm.ghu; -% Set local state space model (second-order approximation). -ghxx = ReducedForm.ghxx; -ghuu = ReducedForm.ghuu; -ghxu = ReducedForm.ghxu; - -if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... - any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... - any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) - ghx - ghu - ghxx - ghuu - ghxu +if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; +else + % Set local state space model (first-order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + % Set local state space model (second-order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; end constant = ReducedForm.constant; state_variables_steady_state = ReducedForm.state_variables_steady_state; -% Set persistent variables. -if isempty(init_flag2) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - init_flag2 = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +number_of_state_variables = length(mf0); +number_of_observed_variables = length(mf1); +number_of_structural_innovations = length(ReducedForm.Q); -numb = number_of_state_variables+number_of_structural_innovations ; +numb = number_of_state_variables+number_of_structural_innovations; if ParticleOptions.proposal_approximation.cubature - [nodes3,weights3] = spherical_radial_sigma_points(numb); + [nodes3, weights3] = spherical_radial_sigma_points(numb); weights_c3 = weights3; elseif ParticleOptions.proposal_approximation.unscented - [nodes3,weights3,weights_c3] = unscented_sigma_points(numb,ParticleOptions); + [nodes3, weights3, weights_c3] = unscented_sigma_points(numb, ParticleOptions); else - error('Estimation: This approximation for the proposal is not implemented or unknown!') + error('This approximation for the proposal is unknown!') end -epsilon = bsxfun(@plus,StructuralShocksSqrtP*nodes3(:,number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations)',StructuralShocksMu) ; -StateVectors = bsxfun(@plus,StateSqrtP*nodes3(:,1:number_of_state_variables)',StateMu); -yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); -tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +epsilon = bsxfun(@plus, StructuralShocksSqrtP*nodes3(:,number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations)', StructuralShocksMu); +StateVectors = bsxfun(@plus, StateSqrtP*nodes3(:,1:number_of_state_variables)', StateMu); +yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); +if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); +else + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); +end PredictedStateMean = tmp(mf0,:)*weights3; PredictedObservedMean = tmp(mf1,:)*weights3; if ParticleOptions.proposal_approximation.cubature - PredictedStateMean = sum(PredictedStateMean,2); - PredictedObservedMean = sum(PredictedObservedMean,2); - dState = (bsxfun(@minus,tmp(mf0,:),PredictedStateMean)').*sqrt(weights3); - dObserved = (bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)').*sqrt(weights3); + PredictedStateMean = sum(PredictedStateMean, 2); + PredictedObservedMean = sum(PredictedObservedMean, 2); + dState = (bsxfun(@minus, tmp(mf0,:), PredictedStateMean)').*sqrt(weights3); + dObserved = (bsxfun(@minus, tmp(mf1,:), PredictedObservedMean)').*sqrt(weights3); PredictedStateVariance = dState'*dState; - big_mat = [dObserved dState ; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; - [mat1,mat] = qr2(big_mat,0); + big_mat = [dObserved, dState ; H_lower_triangular_cholesky, zeros(number_of_observed_variables, number_of_state_variables)]; + [~, mat] = qr2(big_mat, 0); mat = mat'; - clear('mat1'); - PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); - CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); - StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); + PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables, 1:number_of_observed_variables); + CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables), 1:number_of_observed_variables); + StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables), number_of_observed_variables+(1:number_of_state_variables)); iPredictedObservedVarianceSquareRoot = inv(PredictedObservedVarianceSquareRoot); iPredictedObservedVariance = iPredictedObservedVarianceSquareRoot'*iPredictedObservedVarianceSquareRoot; sqrdet = 1/sqrt(det(iPredictedObservedVariance)); PredictionError = obs - PredictedObservedMean; StateVectorMean = PredictedStateMean + CovarianceObservedStateSquareRoot*iPredictedObservedVarianceSquareRoot*PredictionError; else - dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); - dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + dState = bsxfun(@minus, tmp(mf0,:), PredictedStateMean); + dObserved = bsxfun(@minus, tmp(mf1,:), PredictedObservedMean); PredictedStateVariance = dState*diag(weights_c3)*dState'; PredictedObservedVariance = dObserved*diag(weights_c3)*dObserved' + H; PredictedStateAndObservedCovariance = dState*diag(weights_c3)*dObserved'; - sqrdet = sqrt(det(PredictedObservedVariance)) ; + sqrdet = sqrt(det(PredictedObservedVariance)); iPredictedObservedVariance = inv(PredictedObservedVariance); PredictionError = obs - PredictedObservedMean; KalmanFilterGain = PredictedStateAndObservedCovariance*iPredictedObservedVariance; @@ -130,9 +118,9 @@ else end data_lik_GM_g = exp(-0.5*PredictionError'*iPredictedObservedVariance*PredictionError)/abs(normfactO*sqrdet) + 1e-99; -StateMuPrior = PredictedStateMean ; +StateMuPrior = PredictedStateMean; StateSqrtPPrior = reduced_rank_cholesky(PredictedStateVariance)'; StateWeightsPrior = StateWeights*StructuralShocksWeights; StateMuPost = StateVectorMean; StateSqrtPPost = StateVectorVarianceSquareRoot; -StateWeightsPost = StateWeightsPrior*ObservationShocksWeights*data_lik_GM_g ; +StateWeightsPost = StateWeightsPrior*ObservationShocksWeights*data_lik_GM_g; \ No newline at end of file From 2ed534e52e77698f036b40ed595bc439413e47e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Mon, 27 Jan 2020 10:39:34 +0100 Subject: [PATCH 077/101] Allow k order approximation in conditional particle filter (cpf). Ref. dynare#1673 --- src/conditional_filter_proposal.m | 181 ++++++++++++++---------------- src/conditional_particle_filter.m | 116 +++++++++---------- 2 files changed, 134 insertions(+), 163 deletions(-) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index ab746c01c..741f8d487 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -1,24 +1,28 @@ -function [ProposalStateVector,Weights,flag] = conditional_filter_proposal(ReducedForm,obs,StateVectors,SampleWeights,Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) -% +function [ProposalStateVector, Weights, flag] = conditional_filter_proposal(ReducedForm, y, StateVectors, SampleWeights, Q_lower_triangular_cholesky, H_lower_triangular_cholesky, ... + H, ParticleOptions, ThreadsOptions, DynareOptions, Model) + % Computes the proposal for each past particle using Gaussian approximations % for the state errors and the Kalman filter % % INPUTS -% reduced_form_model [structure] Matlab's structure describing the reduced form model. -% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. -% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. -% reduced_form_model.state.dr [structure] output of resol.m. -% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% - ReducedForm [structure] Matlab's structure describing the reduced form model. +% - y [double] p×1 vector, current observation (p is the number of observed variables). +% - StateVectors +% - SampleWeights +% - Q_lower_triangular_cholesky +% - H_lower_triangular_cholesky +% - H +% - ParticleOptions +% - ThreadsOptions +% - DynareOptions +% - Model % % OUTPUTS -% LIK [double] scalar, likelihood -% lik [double] vector, density of observations in each period. -% -% REFERENCES -% -% NOTES -% The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2012-2017 Dynare Team +% - ProposalStateVector +% - Weights +% - flag + +% Copyright © 2012-2020 Dynare Team % % This file is part of Dynare. % @@ -34,124 +38,107 @@ function [ProposalStateVector,Weights,flag] = conditional_filter_proposal(Reduce % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% -% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr -% stephane DOT adjemian AT univ DASH lemans DOT fr -persistent init_flag2 mf0 mf1 -persistent number_of_state_variables number_of_observed_variables -persistent number_of_structural_innovations +flag = false; -flag=0 ; -% Set local state space model (first-order approximation). -ghx = ReducedForm.ghx; -ghu = ReducedForm.ghu; -% Set local state space model (second-order approximation). -ghxx = ReducedForm.ghxx; -ghuu = ReducedForm.ghuu; -ghxu = ReducedForm.ghxu; - -if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... - any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... - any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) - ghx - ghu - ghxx - ghuu - ghxu +if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; +else + % Set local state space model (first-order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + % Set local state space model (second-order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; end constant = ReducedForm.constant; state_variables_steady_state = ReducedForm.state_variables_steady_state; -% Set persistent variables. -if isempty(init_flag2) - mf0 = ReducedForm.mf0; - mf1 = ReducedForm.mf1; - number_of_state_variables = length(mf0); - number_of_observed_variables = length(mf1); - number_of_structural_innovations = length(ReducedForm.Q); - init_flag2 = 1; -end +mf0 = ReducedForm.mf0; +mf1 = ReducedForm.mf1; +number_of_state_variables = length(mf0); +number_of_observed_variables = length(mf1); +number_of_structural_innovations = length(ReducedForm.Q); if ParticleOptions.proposal_approximation.montecarlo - nodes = randn(ParticleOptions.number_of_particles/10,number_of_structural_innovations) ; - weights = 1/ParticleOptions.number_of_particles ; - weights_c = weights ; + nodes = randn(ParticleOptions.number_of_particles/10, number_of_structural_innovations); + weights = 1.0/ParticleOptions.number_of_particles; + weights_c = weights; elseif ParticleOptions.proposal_approximation.cubature - [nodes,weights] = spherical_radial_sigma_points(number_of_structural_innovations); - weights_c = weights ; + [nodes, weights] = spherical_radial_sigma_points(number_of_structural_innovations); + weights_c = weights; elseif ParticleOptions.proposal_approximation.unscented - [nodes,weights,weights_c] = unscented_sigma_points(number_of_structural_innovations,ParticleOptions); + [nodes, weights, weights_c] = unscented_sigma_points(number_of_structural_innovations, ParticleOptions); else error('Estimation: This approximation for the proposal is not implemented or unknown!') end -epsilon = Q_lower_triangular_cholesky*(nodes') ; -yhat = repmat(StateVectors-state_variables_steady_state,1,size(epsilon,2)) ; +epsilon = Q_lower_triangular_cholesky*nodes'; +yhat = repmat(StateVectors-state_variables_steady_state, 1, size(epsilon, 2)); -tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); +else + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); +end -PredictedStateMean = tmp(mf0,:)*weights ; +PredictedStateMean = tmp(mf0,:)*weights; PredictedObservedMean = tmp(mf1,:)*weights; if ParticleOptions.proposal_approximation.cubature || ParticleOptions.proposal_approximation.montecarlo - PredictedStateMean = sum(PredictedStateMean,2) ; - PredictedObservedMean = sum(PredictedObservedMean,2) ; - dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean)'.*sqrt(weights) ; - dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)'.*sqrt(weights); + PredictedStateMean = sum(PredictedStateMean, 2); + PredictedObservedMean = sum(PredictedObservedMean, 2); + dState = bsxfun(@minus, tmp(mf0,:), PredictedStateMean)'.*sqrt(weights); + dObserved = bsxfun(@minus, tmp(mf1,:), PredictedObservedMean)'.*sqrt(weights); PredictedStateVariance = dState*dState'; - big_mat = [dObserved dState; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ]; - [mat1,mat] = qr2(big_mat,0); + big_mat = [dObserved dState; H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)]; + [~, mat] = qr2(big_mat,0); mat = mat'; - clear('mat1'); - PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables); + PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables, 1:number_of_observed_variables); CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables); StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)); - Error = obs - PredictedObservedMean ; - StateVectorMean = PredictedStateMean + (CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*Error ; + Error = y-PredictedObservedMean; + StateVectorMean = PredictedStateMean+(CovarianceObservedStateSquareRoot/PredictedObservedVarianceSquareRoot)*Error; if ParticleOptions.cpf_weights_method.amisanotristani - Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),PredictedObservedVarianceSquareRoot,Error) ; - % Weights = SampleWeights.*sum(weights*probability2(obs,H_lower_triangular_cholesky,tmp(mf1,:)),1) ; - end + Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1), PredictedObservedVarianceSquareRoot, Error); + end else - dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); - dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + dState = bsxfun(@minus, tmp(mf0,:), PredictedStateMean); + dObserved = bsxfun(@minus, tmp(mf1,:), PredictedObservedMean); PredictedStateVariance = dState*diag(weights_c)*dState'; - PredictedObservedVariance = dObserved*diag(weights_c)*dObserved' + H; + PredictedObservedVariance = dObserved*diag(weights_c)*dObserved'+H; PredictedStateAndObservedCovariance = dState*diag(weights_c)*dObserved'; - KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance ; - Error = obs - PredictedObservedMean ; - StateVectorMean = PredictedStateMean + KalmanFilterGain*Error ; - StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; + KalmanFilterGain = PredictedStateAndObservedCovariance/PredictedObservedVariance; + Error = y-PredictedObservedMean; + StateVectorMean = PredictedStateMean+KalmanFilterGain*Error; + StateVectorVariance = PredictedStateVariance-KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVariance = 0.5*(StateVectorVariance+StateVectorVariance'); - %StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)';%chol(StateVectorVariance + eye(number_of_state_variables)*1e-6)' ; - [StateVectorVarianceSquareRoot,p] = chol(StateVectorVariance,'lower') ; + [StateVectorVarianceSquareRoot, p] = chol(StateVectorVariance, 'lower') ; if p - flag=1; - ProposalStateVector = zeros(number_of_state_variables,1) ; - Weights = 0.0 ; + flag = true; + ProposalStateVector = zeros(number_of_state_variables, 1); + Weights = 0.0; return - end + end if ParticleOptions.cpf_weights_method.amisanotristani - Weights = SampleWeights.*probability2(zeros(number_of_observed_variables,1),chol(PredictedObservedVariance)',Error) ; -% Weights = SampleWeights.*sum(probability2(obs,H_lower_triangular_cholesky,tmp(mf1,:))*weights) ; - end + Weights = SampleWeights.*probability2(zeros(number_of_observed_variables, 1), chol(PredictedObservedVariance)', Error); + end end -ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot,2),1)+StateVectorMean ; +ProposalStateVector = StateVectorVarianceSquareRoot*randn(size(StateVectorVarianceSquareRoot, 2), 1)+StateVectorMean; if ParticleOptions.cpf_weights_method.murrayjonesparslow PredictedStateVariance = 0.5*(PredictedStateVariance+PredictedStateVariance'); - %PredictedStateVarianceSquareRoot = reduced_rank_cholesky(PredictedStateVariance)';%chol(PredictedStateVariance + eye(number_of_state_variables)*1e-6)' ; - [PredictedStateVarianceSquareRoot,p] = chol(PredictedStateVariance,'lower') ; + [PredictedStateVarianceSquareRoot, p] = chol(PredictedStateVariance, 'lower'); if p - flag=1; - ProposalStateVector = zeros(number_of_state_variables,1) ; - Weights = 0.0 ; + flag = true; + ProposalStateVector = zeros(number_of_state_variables,1); + Weights = 0.0; return - end - Prior = probability2(PredictedStateMean,PredictedStateVarianceSquareRoot,ProposalStateVector) ; - Posterior = probability2(StateVectorMean,StateVectorVarianceSquareRoot,ProposalStateVector) ; - Likelihood = probability2(obs,H_lower_triangular_cholesky,measurement_equations(ProposalStateVector,ReducedForm,ThreadsOptions)) ; - Weights = SampleWeights.*Likelihood.*(Prior./Posterior) ; + end + Prior = probability2(PredictedStateMean, PredictedStateVarianceSquareRoot, ProposalStateVector); + Posterior = probability2(StateVectorMean, StateVectorVarianceSquareRoot, ProposalStateVector); + Likelihood = probability2(y, H_lower_triangular_cholesky, measurement_equations(ProposalStateVector, ReducedForm, ThreadsOptions, DynareOptions, Model)); + Weights = SampleWeights.*Likelihood.*(Prior./Posterior); end diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 87fb5cded..2bbb4a571 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -1,7 +1,22 @@ -function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOptions,ThreadsOptions) -% +function [LIK,lik] = conditional_particle_filter(ReducedForm, Y, s, ParticleOptions, ThreadsOptions, DynareOptions, Model) + % Evaluates the likelihood of a non-linear model with a particle filter -% - the proposal is built using the Kalman updating step for each particle. +% +% INPUTS +% - ReducedForm [structure] Matlab's structure describing the reduced form model. +% - Y [double] p×T matrix of (detrended) data, where p is the number of observed variables. +% - s [integer] scalar, likelihood evaluation starts at s (has to be smaller than T, the sample length provided in Y). +% - ParticlesOptions [struct] +% - ThreadsOptions [struct] +% - DynareOptions [struct] +% - Model [struct] +% +% OUTPUTS +% - LIK [double] scalar, likelihood +% - lik [double] (T-s+1)×1 vector, density of observations in each period. +% +% REMARKS +% - The proposal is built using the Kalman updating step for each particle. % - we need draws in the errors distributions % Whether we use Monte-Carlo draws from a multivariate gaussian distribution % as in Amisano & Tristani (JEDC 2010). @@ -19,25 +34,8 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOpt % - The use of the Kalman updating step may biais the proposal distribution since % it has been derived in a linear context and is implemented in a nonlinear % context. That is why particle resampling is performed. -% -% INPUTS -% reduced_form_model [structure] Matlab's structure describing the reduced form model. -% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. -% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. -% reduced_form_model.state.dr [structure] output of resol.m. -% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. -% start [integer] scalar, likelihood evaluation starts at 'start'. -% smolyak_accuracy [integer] scalar. -% -% OUTPUTS -% LIK [double] scalar, likelihood -% lik [double] vector, density of observations in each period. -% -% REFERENCES -% -% NOTES -% The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2017 Dynare Team + +% Copyright (C) 2009-2020 Dynare Team % % This file is part of Dynare. % @@ -54,26 +52,14 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm,Y,start,ParticleOpt % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr -% stephane DOT adjemian AT univ DASH lemans DOT fr - -persistent init_flag mf1 -persistent number_of_particles -persistent sample_size number_of_observed_variables - -% Set default -if isempty(start) - start = 1; +% Set default for third input argument. +if isempty(s) + s = 1; end -% Set persistent variables. -if isempty(init_flag) - mf1 = ReducedForm.mf1; - sample_size = size(Y,2); - number_of_observed_variables = length(mf1); - init_flag = 1; - number_of_particles = ParticleOptions.number_of_particles ; -end +T = size(Y,2); +p = length(ReducedForm.mf1); +n = ParticleOptions.number_of_particles; % Get covariance matrices Q = ReducedForm.Q; @@ -88,39 +74,37 @@ end % Get initial condition for the state vector. StateVectorMean = ReducedForm.StateVectorMean; StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; -state_variance_rank = size(StateVectorVarianceSquareRoot,2); +state_variance_rank = size(StateVectorVarianceSquareRoot, 2); Q_lower_triangular_cholesky = chol(Q)'; % Set seed for randn(). set_dynare_seed('default'); % Initialization of the likelihood. -normconst2 = sqrt( ((2*pi)^number_of_observed_variables)*prod(det(H)) ) ; -lik = NaN(sample_size,1); -LIK = NaN; -ks = 0 ; -StateParticles = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); -SampleWeights = ones(1,number_of_particles)/number_of_particles ; -for t=1:sample_size - obs=Y(:,t); - flag = zeros(number_of_particles) ; - parfor i=1:number_of_particles - [StateParticles(:,i),SampleWeights(i),flag(i)] = ... - conditional_filter_proposal(ReducedForm,obs,StateParticles(:,i),SampleWeights(i),Q_lower_triangular_cholesky,H_lower_triangular_cholesky,H,ParticleOptions,ThreadsOptions,normconst2) ; +lik = NaN(T, 1); +ks = 0; +StateParticles = bsxfun(@plus, StateVectorVarianceSquareRoot*randn(state_variance_rank, n), StateVectorMean); +SampleWeights = ones(1, n)/n; + +for t=1:T + flags = false(n, 1); + for i=1:n + [StateParticles(:,i), SampleWeights(i), flags(i)] = ... + conditional_filter_proposal(ReducedForm, Y(:,t), StateParticles(:,i), SampleWeights(i), Q_lower_triangular_cholesky, H_lower_triangular_cholesky, H, ParticleOptions, ThreadsOptions, DynareOptions, Model); end - if sum(flag)~=0 - LIK=-Inf; - lik(t)=-Inf; - return - end - SumSampleWeights = sum(SampleWeights) ; - lik(t) = log(SumSampleWeights) ; - SampleWeights = SampleWeights./SumSampleWeights ; - if (ParticleOptions.resampling.status.generic && neff(SampleWeights) Date: Sat, 15 Feb 2020 16:50:32 +0100 Subject: [PATCH 078/101] Allow k order approximation in online filter (mode_compute=11). Ref. dynare#1673 --- src/online_auxiliary_filter.m | 70 ++++++++++++++++++----------- src/solve_model_for_online_filter.m | 15 ++++--- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 18f762ec9..6acadc608 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -64,7 +64,7 @@ StateVectorMean = ReducedForm.StateVectorMean; StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); -if pruning +if DynareOptions.order<3 && pruning StateVectors_ = StateVectors; end @@ -123,19 +123,29 @@ for t=1:sample_size steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; % Set local state space model (second-order approximation). - constant = ReducedForm.constant; - ghx = ReducedForm.ghx; - ghu = ReducedForm.ghu; - ghxx = ReducedForm.ghxx; - ghuu = ReducedForm.ghuu; - ghxu = ReducedForm.ghxu; - % particle likelihood contribution - yhat = bsxfun(@minus,StateVectors(:,i),state_variables_steady_state); - if pruning - yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); - [tmp, ~] = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); + if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; else - tmp = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + constant = ReducedForm.constant; + % Set local state space model (first-order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + % Set local state space model (second-order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; + end + % particle likelihood contribution + yhat = bsxfun(@minus, StateVectors(:,i), state_variables_steady_state); + if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, 1), dr, Model, DynareOptions); + else + if pruning + yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); + [tmp, ~] = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); + else + tmp = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + end end PredictionError = bsxfun(@minus,Y(t,:)', tmp(mf1,:)); % Replace Gaussian density with a Student density with 3 degrees of freedom for fat tails. @@ -148,7 +158,7 @@ for t=1:sample_size indx = resample(0, tau_tilde', DynareOptions.particle); StateVectors = StateVectors(:,indx); xparam = fore_xparam(:,indx); - if pruning + if DynareOptions.order>=3 && pruning StateVectors_ = StateVectors_(:,indx); end w_stage1 = weights(indx)./tau_tilde(indx); @@ -167,22 +177,32 @@ for t=1:sample_size steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; % Set local state space model (second order approximation). - constant = ReducedForm.constant; - ghx = ReducedForm.ghx; - ghu = ReducedForm.ghu; - ghxx = ReducedForm.ghxx; - ghuu = ReducedForm.ghuu; - ghxu = ReducedForm.ghxu; + if ReducedForm.use_k_order_solver + dr = ReducedForm.dr; + else + constant = ReducedForm.constant; + % Set local state space model (first-order approximation). + ghx = ReducedForm.ghx; + ghu = ReducedForm.ghu; + % Set local state space model (second-order approximation). + ghxx = ReducedForm.ghxx; + ghuu = ReducedForm.ghuu; + ghxu = ReducedForm.ghxu; + end % Get covariance matrices and structural shocks epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations, 1); % compute particles likelihood contribution yhat = bsxfun(@minus,StateVectors(:,i), state_variables_steady_state); - if pruning - yhat_ = bsxfun(@minus,StateVectors_(:,i), state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); - StateVectors_(:,i) = tmp_(mf0,:); + if ReducedForm.use_k_order_solver + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); else - tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + if pruning + yhat_ = bsxfun(@minus,StateVectors_(:,i), state_variables_steady_state); + [tmp, tmp_] = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); + StateVectors_(:,i) = tmp_(mf0,:); + else + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + end end StateVectors(:,i) = tmp(mf0,:); PredictionError = bsxfun(@minus,Y(t,:)', tmp(mf1,:)); diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 4df219d87..332378d5a 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -155,12 +155,17 @@ if nargout>4 ReducedForm.ghx = dr.ghx(restrict_variables_idx,:); ReducedForm.ghu = dr.ghu(restrict_variables_idx,:); ReducedForm.steadystate = dr.ys(dr.order_var(restrict_variables_idx)); - if DynareOptions.order>1 + if DynareOptions.order==2 + ReducedForm.use_k_order_solver = false; ReducedForm.ghxx = dr.ghxx(restrict_variables_idx,:); ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); + elseif DynareOptions.order>=3 + ReducedForm.use_k_order_solver = true; + ReducedForm.dr = dr; else + ReducedForm.use_k_order_solver = false; ReducedForm.ghxx = zeros(size(restrict_variables_idx,1),size(dr.kstate,2)); ReducedForm.ghuu = zeros(size(restrict_variables_idx,1),size(dr.ghu,2)); ReducedForm.ghxu = zeros(size(restrict_variables_idx,1),size(dr.ghx,2)); @@ -177,19 +182,19 @@ end if setinitialcondition switch DynareOptions.particle.initialization case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. - StateVectorMean = ReducedForm.constant(mf0); + StateVectorMean = ReducedForm.state_variables_steady_state;%.constant(mf0); StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',DynareOptions.lyapunov_fixed_point_tol,DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold); case 2% Initial state vector covariance is a monte-carlo based estimate of the ergodic variance (consistent with a k-order Taylor-approximation of the model). - StateVectorMean = ReducedForm.constant(mf0); + StateVectorMean = ReducedForm.state_variables_steady_state;%.constant(mf0); old_DynareOptionsperiods = DynareOptions.periods; DynareOptions.periods = 5000; - y_ = simult(oo_.steady_state, dr,Model,DynareOptions,DynareResults); + y_ = simult(oo_.steady_state, dr, Model, DynareOptions, DynareResults); y_ = y_(state_variables_idx,2001:5000); StateVectorVariance = cov(y_'); DynareOptions.periods = old_DynareOptionsperiods; clear('old_DynareOptionsperiods','y_'); case 3% Initial state vector covariance is a diagonal matrix. - StateVectorMean = ReducedForm.constant(mf0); + StateVectorMean = ReducedForm.state_variables_steady_state;%.constant(mf0); StateVectorVariance = DynareOptions.particle.initial_state_prior_std*eye(number_of_state_variables); otherwise error('Unknown initialization option!') From c440779a11e3ff75bfca0ab1cf43372ba52a677a Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Wed, 17 Jun 2020 20:32:40 +0200 Subject: [PATCH 079/101] Consistently use LaTeX labels in figures instead of relying on psfrag --- src/DSMH_sampler.m | 18 +++++----------- src/Herbst_Schorfheide_sampler.m | 18 +++++----------- src/online_auxiliary_filter.m | 36 +++++++++----------------------- 3 files changed, 20 insertions(+), 52 deletions(-) diff --git a/src/DSMH_sampler.m b/src/DSMH_sampler.m index d44a43f50..3e3732717 100644 --- a/src/DSMH_sampler.m +++ b/src/DSMH_sampler.m @@ -132,21 +132,16 @@ plt = 1 ; subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) %kk = (plt-1)*nstar+k; [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); - if TeX - if isempty(NAMES) - NAMES = name; - TeXNAMES = texname; - else - NAMES = char(NAMES,name); - TeXNAMES = char(TeXNAMES,texname); - end - end optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.dsmh.number_of_particles,bandwidth,kernel_function); [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... options_.dsmh.number_of_particles,optimal_bandwidth,kernel_function); plot(density(:,1),density(:,2)); hold on - title(name,'interpreter','none') + if TeX + title(texname,'interpreter','latex') + else + title(name,'interpreter','none') + end hold off axis tight drawnow @@ -155,9 +150,6 @@ plt = 1 ; if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); - for jj = 1:min(nstar,length(x)-(plt-1)*nstar) - fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); - end fprintf(fidTeX,'\\centering \n'); fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',M_.fname,int2str(plt)); fprintf(fidTeX,'\\caption{ParametersDensities.}'); diff --git a/src/Herbst_Schorfheide_sampler.m b/src/Herbst_Schorfheide_sampler.m index 3c6482919..cc5160683 100644 --- a/src/Herbst_Schorfheide_sampler.m +++ b/src/Herbst_Schorfheide_sampler.m @@ -160,21 +160,16 @@ plt = 1 ; subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) %kk = (plt-1)*nstar+k; [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); - if TeX - if isempty(NAMES) - NAMES = name; - TeXNAMES = texname; - else - NAMES = char(NAMES,name); - TeXNAMES = char(TeXNAMES,texname); - end - end optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.HSsmc.nparticles,bandwidth,kernel_function); [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... options_.HSsmc.nparticles,optimal_bandwidth,kernel_function); plot(density(:,1),density(:,2)); hold on - title(name,'interpreter','none') + if TeX + title(texname,'interpreter','latex') + else + title(name,'interpreter','none') + end hold off axis tight drawnow @@ -183,9 +178,6 @@ plt = 1 ; if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); - for jj = 1:min(nstar,length(x)-(plt-1)*nstar) - fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); - end fprintf(fidTeX,'\\centering \n'); fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',M_.fname,int2str(plt)); fprintf(fidTeX,'\\caption{ParametersDensities.}'); diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 6acadc608..c7df9d805 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -306,21 +306,16 @@ for plt = 1:nbplt for k=1:length(pmean) subplot(nr,nc,k) [name,texname] = get_the_name(k,TeX,Model,EstimatedParameters,DynareOptions); - if TeX - if isempty(NAMES) - NAMES = name; - TeXNAMES = texname; - else - NAMES = char(NAMES,name); - TeXNAMES = char(TeXNAMES,texname); - end - end % Draw the surface for an interval containing 95% of the particles. shade(1:sample_size, ub95_xparam(k,:)', 1:sample_size, lb95_xparam(k,:)', 'FillType',[1 2], 'LineStyle', 'none', 'Marker', 'none') hold on % Draw the mean of particles. plot(1:sample_size, mean_xparam(k,:), '-k', 'linewidth', 2) - title(name,'interpreter','none') + if TeX + title(texname,'interpreter','latex') + else + title(name,'interpreter','none') + end hold off axis tight drawnow @@ -329,9 +324,6 @@ for plt = 1:nbplt if TeX % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); - for jj = 1:length(x) - fprintf(fidTeX,'\\psfrag{%s}[1][][0.5][0]{%s}\n',deblank(NAMES(jj,:)),deblank(TeXNAMES(jj,:))); - end fprintf(fidTeX,'\\centering \n'); fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParamTraj%s}\n',Model.fname,int2str(plt)); fprintf(fidTeX,'\\caption{Parameters trajectories.}'); @@ -354,21 +346,16 @@ for plt = 1:nbplt for k=1:length(pmean) subplot(nr,nc,k) [name,texname] = get_the_name(k,TeX,Model,EstimatedParameters,DynareOptions); - if TeX - if isempty(NAMES) - NAMES = name; - TeXNAMES = texname; - else - NAMES = char(NAMES,name); - TeXNAMES = char(TeXNAMES,texname); - end - end optimal_bandwidth = mh_optimal_bandwidth(xparam(k,:)',number_of_particles,bandwidth,kernel_function); [density(:,1),density(:,2)] = kernel_density_estimate(xparam(k,:)', number_of_grid_points, ... number_of_particles, optimal_bandwidth, kernel_function); plot(density(:,1), density(:,2)); hold on - title(name, 'interpreter', 'none') + if TeX + title(texname,'interpreter','latex') + else + title(name,'interpreter','none') + end hold off axis tight drawnow @@ -377,9 +364,6 @@ for plt = 1:nbplt if TeX % TeX eps loader file fprintf(fidTeX, '\\begin{figure}[H]\n'); - for jj = 1:length(x) - fprintf(fidTeX, '\\psfrag{%s}[1][][0.5][0]{%s}\n', deblank(NAMES(jj,:)), deblank(TeXNAMES(jj,:))); - end fprintf(fidTeX,'\\centering \n'); fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',Model.fname,int2str(plt)); fprintf(fidTeX,'\\caption{ParametersDensities.}'); From 178eaceb9cdeae4d868e28300adce2da54e6eb83 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Thu, 18 Jun 2020 13:14:00 +0200 Subject: [PATCH 080/101] Fix eps-TeX-loaders --- src/DSMH_sampler.m | 6 +++--- src/Herbst_Schorfheide_sampler.m | 6 +++--- src/online_auxiliary_filter.m | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/DSMH_sampler.m b/src/DSMH_sampler.m index 3e3732717..99307013f 100644 --- a/src/DSMH_sampler.m +++ b/src/DSMH_sampler.m @@ -147,12 +147,12 @@ plt = 1 ; drawnow end dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); - if TeX + if TeX && any(strcmp('eps',cellstr(options_.graph_format))) % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',M_.fname,int2str(plt)); - fprintf(fidTeX,'\\caption{ParametersDensities.}'); + fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{Parameter densities based on the Dynamic Striated Metropolis-Hastings algorithm.}'); fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); fprintf(fidTeX,'\\end{figure}\n'); fprintf(fidTeX,' \n'); diff --git a/src/Herbst_Schorfheide_sampler.m b/src/Herbst_Schorfheide_sampler.m index cc5160683..03323a0d9 100644 --- a/src/Herbst_Schorfheide_sampler.m +++ b/src/Herbst_Schorfheide_sampler.m @@ -175,12 +175,12 @@ plt = 1 ; drawnow end dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); - if TeX + if TeX && any(strcmp('eps',cellstr(options_.graph_format))) % TeX eps loader file fprintf(fidTeX,'\\begin{figure}[H]\n'); fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',M_.fname,int2str(plt)); - fprintf(fidTeX,'\\caption{ParametersDensities.}'); + fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{Parameter densities based on the Herbst/Schorfheide sampler.}'); fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); fprintf(fidTeX,'\\end{figure}\n'); fprintf(fidTeX,' \n'); diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index c7df9d805..0da8e48fa 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -361,13 +361,13 @@ for plt = 1:nbplt drawnow end dyn_saveas(hh,[ Model.fname '_param_density' int2str(plt) ],DynareOptions.nodisplay,DynareOptions.graph_format); - if TeX + if TeX && any(strcmp('eps',cellstr(DynareOptions.graph_format))) % TeX eps loader file fprintf(fidTeX, '\\begin{figure}[H]\n'); fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[scale=0.5]{%s_ParametersDensities%s}\n',Model.fname,int2str(plt)); - fprintf(fidTeX,'\\caption{ParametersDensities.}'); - fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); + fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/nc,1),M_.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{Parameter densities based on the Liu/West particle filter.}'); + fprintf(fidTeX,'\\label{Fig:ParameterDensities:%s}\n',int2str(plt)); fprintf(fidTeX,'\\end{figure}\n'); fprintf(fidTeX,' \n'); end From 3dca797ba8fb3d318dd65335ec0199ef6a6851d9 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Fri, 13 Nov 2020 11:35:44 +0100 Subject: [PATCH 081/101] auxiliary_particle_filter.m: set undefined variable Closes https://git.dynare.org/Dynare/dynare/-/issues/1718 --- src/auxiliary_particle_filter.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 905a569d2..737d1a6da 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -134,6 +134,7 @@ for t=1:sample_size if (ParticleOptions.resampling.status.generic && neff(weights) Date: Tue, 26 Jan 2021 09:10:55 +0100 Subject: [PATCH 082/101] solve_model_for_online_filter.m: fix reduced form dimensions for oder=2 matrices at order=1 --- src/solve_model_for_online_filter.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 332378d5a..fbfcb05b6 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -165,11 +165,13 @@ if nargout>4 ReducedForm.use_k_order_solver = true; ReducedForm.dr = dr; else + n_states=size(dr.ghx,2); + n_shocks=size(dr.ghu,2); ReducedForm.use_k_order_solver = false; - ReducedForm.ghxx = zeros(size(restrict_variables_idx,1),size(dr.kstate,2)); - ReducedForm.ghuu = zeros(size(restrict_variables_idx,1),size(dr.ghu,2)); - ReducedForm.ghxu = zeros(size(restrict_variables_idx,1),size(dr.ghx,2)); - ReducedForm.constant = ReducedForm.steadystate ; + ReducedForm.ghxx = zeros(size(restrict_variables_idx,1),n_states^2); + ReducedForm.ghuu = zeros(size(restrict_variables_idx,1),n_shocks^2); + ReducedForm.ghxu = zeros(size(restrict_variables_idx,1),n_states*n_shocks); + ReducedForm.constant = ReducedForm.steadystate; end ReducedForm.state_variables_steady_state = dr.ys(dr.order_var(state_variables_idx)); ReducedForm.Q = Q; From 60f71f27205dfd2002cb3d37177eeab5e9362384 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Tue, 26 Jan 2021 09:14:34 +0100 Subject: [PATCH 083/101] Port state variance initialization fix from https://git.dynare.org/Dynare/dynare/-/commit/dab5d38068db477493eb5e7213c82d3e3a8b543c --- src/solve_model_for_online_filter.m | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index fbfcb05b6..7f046ace1 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -185,15 +185,22 @@ if setinitialcondition switch DynareOptions.particle.initialization case 1% Initial state vector covariance is the ergodic variance associated to the first order Taylor-approximation of the model. StateVectorMean = ReducedForm.state_variables_steady_state;%.constant(mf0); - StateVectorVariance = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',DynareOptions.lyapunov_fixed_point_tol,DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold); + [A,B] = kalman_transition_matrix(dr,dr.restrict_var_list,dr.restrict_columns,Model.exo_nbr); + StateVectorVariance2 = lyapunov_symm(ReducedForm.ghx(mf0,:),ReducedForm.ghu(mf0,:)*ReducedForm.Q*ReducedForm.ghu(mf0,:)',DynareOptions.lyapunov_fixed_point_tol,DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold); + StateVectorVariance = lyapunov_symm(A, B*ReducedForm.Q*B', DynareOptions.lyapunov_fixed_point_tol, ... + DynareOptions.qz_criterium, DynareOptions.lyapunov_complex_threshold, [], DynareOptions.debug); + StateVectorVariance = StateVectorVariance(mf0,mf0); case 2% Initial state vector covariance is a monte-carlo based estimate of the ergodic variance (consistent with a k-order Taylor-approximation of the model). StateVectorMean = ReducedForm.state_variables_steady_state;%.constant(mf0); old_DynareOptionsperiods = DynareOptions.periods; DynareOptions.periods = 5000; - y_ = simult(oo_.steady_state, dr, Model, DynareOptions, DynareResults); - y_ = y_(state_variables_idx,2001:5000); + old_DynareOptionspruning = DynareOptions.pruning; + DynareOptions.pruning = DynareOptions.particle.pruning; + y_ = simult(dr.ys, dr, Model, DynareOptions, DynareResults); + y_ = y_(dr.order_var(state_variables_idx),2001:DynareOptions.periods); StateVectorVariance = cov(y_'); DynareOptions.periods = old_DynareOptionsperiods; + DynareOptions.pruning = old_DynareOptionspruning; clear('old_DynareOptionsperiods','y_'); case 3% Initial state vector covariance is a diagonal matrix. StateVectorMean = ReducedForm.state_variables_steady_state;%.constant(mf0); From e685fa396f79bd57ef4e47e4e8aeba915bd7ecfc Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Tue, 26 Jan 2021 09:15:43 +0100 Subject: [PATCH 084/101] solve_model_for_online_filter.m: correct dimension of H matrix --- src/solve_model_for_online_filter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 7f046ace1..5afff5584 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -71,7 +71,7 @@ if EstimatedParameters.nvn end offset = offset+EstimatedParameters.nvn; else - H = zeros(size(DynareDataset.data, 1)); + H = zeros(size(DynareDataset.data, 2)); end % Get the off-diagonal elements of the covariance matrix for the structural innovations. Test if Q is positive definite. From 99aa1fc04b08c7917ba1198af4c186f4dcc278e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Wed, 9 Jun 2021 17:21:49 +0200 Subject: [PATCH 085/101] Use secure URL for link to GNU licenses --- LICENSE.md | 2 +- src/DSMH_initialization.m | 2 +- src/DSMH_sampler.m | 2 +- src/Herbst_Schorfheide_sampler.m | 2 +- src/SMC_samplers_initialization.m | 2 +- src/auxiliary_initialization.m | 2 +- src/auxiliary_particle_filter.m | 2 +- src/conditional_filter_proposal.m | 2 +- src/conditional_particle_filter.m | 2 +- src/fit_gaussian_mixture.m | 2 +- src/gaussian_densities.m | 2 +- src/gaussian_filter.m | 2 +- src/gaussian_filter_bank.m | 2 +- src/gaussian_mixture_densities.m | 2 +- src/gaussian_mixture_filter.m | 2 +- src/gaussian_mixture_filter_bank.m | 2 +- src/importance_sampling.m | 2 +- src/measurement_equations.m | 2 +- src/multivariate_smooth_resampling.m | 2 +- src/mykmeans.m | 2 +- src/neff.m | 2 +- src/nonlinear_kalman_filter.m | 2 +- src/online_auxiliary_filter.m | 2 +- src/probability.m | 2 +- src/probability2.m | 2 +- src/probability3.m | 2 +- src/resample.m | 2 +- src/residual_resampling.m | 2 +- src/sequential_importance_particle_filter.m | 2 +- src/solve_model_for_online_filter.m | 2 +- src/spherical_radial_sigma_points.m | 2 +- src/traditional_resampling.m | 2 +- src/univariate_smooth_resampling.m | 2 +- src/unscented_sigma_points.m | 2 +- 34 files changed, 34 insertions(+), 34 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 233611e8f..e9fbc2f98 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -13,4 +13,4 @@ The Dynare particles module is distributed under the GNU GPL: > GNU General Public License for more details. > > You should have received a copy of the GNU General Public License -> along with this program. If not, see . \ No newline at end of file +> along with this program. If not, see . \ No newline at end of file diff --git a/src/DSMH_initialization.m b/src/DSMH_initialization.m index 38e16da4e..a9b9ee1bd 100644 --- a/src/DSMH_initialization.m +++ b/src/DSMH_initialization.m @@ -45,7 +45,7 @@ function [ ix2, temperedlogpost, loglik, ModelName, MetropolisFolder, npar, Numb % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . %Initialize outputs ix2 = []; diff --git a/src/DSMH_sampler.m b/src/DSMH_sampler.m index 99307013f..967694759 100644 --- a/src/DSMH_sampler.m +++ b/src/DSMH_sampler.m @@ -52,7 +52,7 @@ function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_ % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . lambda = exp(bsxfun(@minus,options_.dsmh.H,1:1:options_.dsmh.H)/(options_.dsmh.H-1)*log(options_.dsmh.lambda1)); diff --git a/src/Herbst_Schorfheide_sampler.m b/src/Herbst_Schorfheide_sampler.m index 03323a0d9..b6b32a3bd 100644 --- a/src/Herbst_Schorfheide_sampler.m +++ b/src/Herbst_Schorfheide_sampler.m @@ -52,7 +52,7 @@ function Herbst_Schorfheide_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Create the tempering schedule diff --git a/src/SMC_samplers_initialization.m b/src/SMC_samplers_initialization.m index 765a7679c..7642f8761 100644 --- a/src/SMC_samplers_initialization.m +++ b/src/SMC_samplers_initialization.m @@ -46,7 +46,7 @@ function [ ix2, temperedlogpost, loglik, npar, NumberOfParticles, bayestopt_] = % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . %Initialize outputs ix2 = []; diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index 002a8038a..ac74204b0 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -17,7 +17,7 @@ function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,Par % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . persistent init_flag mf0 mf1 number_of_particles persistent number_of_observed_variables number_of_structural_innovations diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 737d1a6da..6a4e89feb 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -18,7 +18,7 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptio % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Set default if isempty(start) diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 741f8d487..3b6b65538 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -37,7 +37,7 @@ function [ProposalStateVector, Weights, flag] = conditional_filter_proposal(Redu % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . flag = false; diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index 2bbb4a571..a71d413ea 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -50,7 +50,7 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm, Y, s, ParticleOpti % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Set default for third input argument. if isempty(s) diff --git a/src/fit_gaussian_mixture.m b/src/fit_gaussian_mixture.m index 672c90e68..00970da6f 100644 --- a/src/fit_gaussian_mixture.m +++ b/src/fit_gaussian_mixture.m @@ -15,7 +15,7 @@ function [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(X,X_weights,St % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . [dim,Ndata] = size(X); M = size(StateMu,2) ; diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 64128cf58..4cc441d65 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -35,7 +35,7 @@ function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sq % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % proposal density proposal = probability2(mut_t, sqr_Pss_t_t, particles); diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index 29cc021e0..8119ffb9b 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -47,7 +47,7 @@ function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, Thr % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Set default if isempty(start) diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index 7932411c4..d7361207b 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -37,7 +37,7 @@ function [PredictedStateMean, PredictedStateVarianceSquareRoot, StateVectorMean, % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . if ReducedForm.use_k_order_solver dr = ReducedForm.dr; diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m index 9e4851093..8a12b102e 100644 --- a/src/gaussian_mixture_densities.m +++ b/src/gaussian_mixture_densities.m @@ -37,7 +37,7 @@ function IncrementalWeights = gaussian_mixture_densities(obs, StateMuPrior, Sta % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Compute the density of particles under the prior distribution [~, ~, prior] = probability(StateMuPrior, StateSqrtPPrior, StateWeightsPrior, StateParticles); diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index 65c16995d..0f4a8d180 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -51,7 +51,7 @@ function [LIK, lik] = gaussian_mixture_filter(ReducedForm, Y, start, ParticleOpt % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Set default if isempty(start) diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index fd80dd417..74b9dea47 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -39,7 +39,7 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . if ReducedForm.use_k_order_solver dr = ReducedForm.dr; diff --git a/src/importance_sampling.m b/src/importance_sampling.m index ae20b02a7..357854cc3 100644 --- a/src/importance_sampling.m +++ b/src/importance_sampling.m @@ -15,7 +15,7 @@ function State_Particles = importance_sampling(StateMuPost,StateSqrtPPost,StateW % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . [Xdim,Gsecond] = size(StateMuPost) ; u = rand(numP,1); diff --git a/src/measurement_equations.m b/src/measurement_equations.m index e450d1c11..87edc75fc 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -15,7 +15,7 @@ function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . mf1 = ReducedForm.mf1; if ReducedForm.use_k_order_solver diff --git a/src/multivariate_smooth_resampling.m b/src/multivariate_smooth_resampling.m index 01c9208a7..52e9411d6 100644 --- a/src/multivariate_smooth_resampling.m +++ b/src/multivariate_smooth_resampling.m @@ -53,7 +53,7 @@ function new_particles = multivariate_smooth_resampling(particles,weights) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr % stephane DOT adjemian AT univ DASH lemans DOT fr diff --git a/src/mykmeans.m b/src/mykmeans.m index c39afedb9..30f5b902a 100644 --- a/src/mykmeans.m +++ b/src/mykmeans.m @@ -15,7 +15,7 @@ function [c,SqrtVariance,Weights] = mykmeans(x,g,init,cod) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . [n,m] = size(x) ; indold = zeros(1,m) ; diff --git a/src/neff.m b/src/neff.m index e0fb4f70e..d6d80e464 100644 --- a/src/neff.m +++ b/src/neff.m @@ -16,6 +16,6 @@ function n = neff(w) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . n = 1/dot(w,w); \ No newline at end of file diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index 9f9d729c5..322eb6e6e 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -47,7 +47,7 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Set default if isempty(start) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 0da8e48fa..ebc98a3ab 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -36,7 +36,7 @@ function [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxili % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % Set seed for randn(). set_dynare_seed('default'); diff --git a/src/probability.m b/src/probability.m index 68efb3fa1..2368cbdca 100644 --- a/src/probability.m +++ b/src/probability.m @@ -15,7 +15,7 @@ function [prior,likelihood,C,posterior] = probability(mu,sqrtP,prior,X) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . [dim,nov] = size(X); M = size(mu,2) ; diff --git a/src/probability2.m b/src/probability2.m index 268cd0394..f9b4f0b9f 100644 --- a/src/probability2.m +++ b/src/probability2.m @@ -29,7 +29,7 @@ function [density] = probability2(mu,S,X) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . dim = size(X,1) ; normfact = bsxfun(@power,(2*pi),(dim/2)) ; diff --git a/src/probability3.m b/src/probability3.m index 710a84267..bafac9528 100644 --- a/src/probability3.m +++ b/src/probability3.m @@ -15,7 +15,7 @@ function [prior,likelihood,C,posterior] = probability3(mu,sqrtP,prior,X,X_weight % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . [dim,nov] = size(X); M = size(mu,2) ; diff --git a/src/resample.m b/src/resample.m index e29d62e4f..c9ac9cd78 100644 --- a/src/resample.m +++ b/src/resample.m @@ -51,7 +51,7 @@ function resampled_output = resample(particles,weights,ParticleOptions) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . defaultmethod = 1; % For residual based method set this variable equal to 0. diff --git a/src/residual_resampling.m b/src/residual_resampling.m index d4d250309..1b8752a2c 100644 --- a/src/residual_resampling.m +++ b/src/residual_resampling.m @@ -45,7 +45,7 @@ function return_resample = residual_resampling(particles,weights,noise) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % AUTHOR(S) frederic DOT karame AT univ DASH evry DOT fr % stephane DOT adjemian AT univ DASH lemans DOT fr diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 526ee825f..975ac1299 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -17,7 +17,7 @@ function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,P % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . persistent init_flag persistent mf0 mf1 diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 5afff5584..c80bc3f3d 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -35,7 +35,7 @@ function [info, Model, DynareOptions, DynareResults, ReducedForm] = ... % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . persistent init_flag restrict_variables_idx state_variables_idx mf0 mf1 number_of_state_variables diff --git a/src/spherical_radial_sigma_points.m b/src/spherical_radial_sigma_points.m index aeaf7d5c5..19e2634ab 100644 --- a/src/spherical_radial_sigma_points.m +++ b/src/spherical_radial_sigma_points.m @@ -30,7 +30,7 @@ function [nodes,weights] = spherical_radial_sigma_points(n) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . nodes = (sqrt(n)*([eye(n) -eye(n)]))' ; weights = (1/(2*n)) ; diff --git a/src/traditional_resampling.m b/src/traditional_resampling.m index ce6ed90c4..3dd27aba7 100644 --- a/src/traditional_resampling.m +++ b/src/traditional_resampling.m @@ -48,7 +48,7 @@ function return_resample = traditional_resampling(particles,weights,noise) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % AUTHOR(S) frederic DOT karame AT univ DASH evry DOT fr % stephane DOT adjemian AT univ DASH lemans DOT fr diff --git a/src/univariate_smooth_resampling.m b/src/univariate_smooth_resampling.m index 1a8d10439..aa8651538 100644 --- a/src/univariate_smooth_resampling.m +++ b/src/univariate_smooth_resampling.m @@ -49,7 +49,7 @@ function new_particles = univariate_smooth_resampling(weights,particles,number_o % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . % AUTHOR(S) frederic DOT karame AT univ DASH lemans DOT fr % stephane DOT adjemian AT univ DASH lemans DOT fr diff --git a/src/unscented_sigma_points.m b/src/unscented_sigma_points.m index 54c5b0b0d..53709af40 100644 --- a/src/unscented_sigma_points.m +++ b/src/unscented_sigma_points.m @@ -29,7 +29,7 @@ function [nodes,W_m,W_c] = unscented_sigma_points(n,ParticleOptions) % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . +% along with Dynare. If not, see . lambda = (ParticleOptions.unscented.alpha^2)*(n+ParticleOptions.unscented.kappa) - n ; nodes = [ zeros(n,1) ( sqrt(n+lambda).*([ eye(n) -eye(n)]) ) ]' ; From 6f791870b4f188c419055ecfcdccb9e585bdd863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ryuk=29?= Date: Tue, 15 Jun 2021 21:40:03 +0200 Subject: [PATCH 086/101] Fix online filter output. The plot showing the evolution, along the sample, of thye particles was crashing because of a missing function. --- src/online_auxiliary_filter.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index ebc98a3ab..c6e0e61db 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -21,7 +21,7 @@ function [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxili % - p975 [double] n×1 vector, 97.5 percent of the particles are below p975(i) for i=1,…,n. % - covariance [double] n×n matrix, covariance of the particles at the end of the sample. -% Copyright (C) 2013-2019 Dynare Team +% Copyright © 2013-2021 Dynare Team % % This file is part of Dynare. % @@ -307,8 +307,9 @@ for plt = 1:nbplt subplot(nr,nc,k) [name,texname] = get_the_name(k,TeX,Model,EstimatedParameters,DynareOptions); % Draw the surface for an interval containing 95% of the particles. - shade(1:sample_size, ub95_xparam(k,:)', 1:sample_size, lb95_xparam(k,:)', 'FillType',[1 2], 'LineStyle', 'none', 'Marker', 'none') + area(1:sample_size, ub95_xparam(k,:), 'FaceColor', [.9 .9 .9], 'BaseValue', min(lb95_xparam(k,:))); hold on + area(1:sample_size, lb95_xparam(k,:), 'FaceColor', [1 1 1], 'BaseValue', min(lb95_xparam(k,:))); % Draw the mean of particles. plot(1:sample_size, mean_xparam(k,:), '-k', 'linewidth', 2) if TeX From ec50899f7ae0fc61d1e2ae814b229a0977129b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ryuk=29?= Date: Tue, 15 Jun 2021 21:43:00 +0200 Subject: [PATCH 087/101] Fix call to fprint. --- src/online_auxiliary_filter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index c6e0e61db..37cbd1b5b 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -103,7 +103,7 @@ for t=1:sample_size if t>1 fprintf('\nSubsample with %s first observations.\n\n', int2str(t)) else - fprintf('\nSubsample with only the first observation.\n\n', int2str(t)) + fprintf('\nSubsample with only the first observation.\n\n') end % Moments of parameters particles distribution m_bar = xparam*(weights'); From e31e4a0626bcc8208b0cc649fffa8b8c1a3c76bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ryuk=29?= Date: Tue, 15 Jun 2021 21:43:14 +0200 Subject: [PATCH 088/101] Cosmetic change (removed useless square brackets). --- src/online_auxiliary_filter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 37cbd1b5b..5a245b364 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -271,7 +271,7 @@ for t=1:sample_size for l=1:size(xparam,1) str = sprintf('%s\n %5.4f \t\t %7.5f \t\t %5.4f', str, lb95_xparam(l,t), mean_xparam(l,t), ub95_xparam(l,t)); end - disp([str]) + disp(str) disp('') end From a5c2c4af4b4aeeb9f4a51860c244d790dac3b8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ryuk=29?= Date: Tue, 15 Jun 2021 21:44:08 +0200 Subject: [PATCH 089/101] Remove unused variables. --- src/online_auxiliary_filter.m | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 5a245b364..91c51f530 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -298,10 +298,6 @@ if TeX end for plt = 1:nbplt - if TeX - NAMES = []; - TeXNAMES = []; - end hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Trajectories'); for k=1:length(pmean) subplot(nr,nc,k) @@ -339,10 +335,6 @@ number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. bandwidth = 0; % Rule of thumb optimal bandwidth parameter. kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. for plt = 1:nbplt - if TeX - NAMES = []; - TeXNAMES = []; - end hh = dyn_figure(DynareOptions.nodisplay,'Name','Parameters Densities'); for k=1:length(pmean) subplot(nr,nc,k) From 648c825040322024c5e46f283328b29cf715ae48 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Tue, 22 Jun 2021 14:31:29 +0200 Subject: [PATCH 090/101] Remove redundant options output --- src/solve_model_for_online_filter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index c80bc3f3d..0b73d66dc 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -125,7 +125,7 @@ Model.H = H; %------------------------------------------------------------------------------ warning('off', 'MATLAB:nearlySingularMatrix') -[~, ~, ~, info, Model, DynareOptions, DynareResults] = ... +[~, ~, ~, info, Model, DynareResults] = ... dynare_resolve(Model, DynareOptions, DynareResults, 'restrict'); warning('on', 'MATLAB:nearlySingularMatrix') From 13fe81045362c902d37e9e16758b3d337241521a Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Wed, 21 Jul 2021 12:23:07 +0200 Subject: [PATCH 091/101] Alternative samplers: header fixes and indentation --- src/DSMH_sampler.m | 309 +++++++++++++++---------------- src/Herbst_Schorfheide_sampler.m | 198 ++++++++++---------- 2 files changed, 249 insertions(+), 258 deletions(-) diff --git a/src/DSMH_sampler.m b/src/DSMH_sampler.m index 967694759..9c522f2a1 100644 --- a/src/DSMH_sampler.m +++ b/src/DSMH_sampler.m @@ -1,15 +1,11 @@ function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) -% function DSMH_sampler(TargetFun,ProposalFun,xparam1,sampler_options,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) % Dynamic Striated Metropolis-Hastings algorithm. % % INPUTS % o TargetFun [char] string specifying the name of the objective % function (posterior kernel). -% o ProposalFun [char] string specifying the name of the proposal -% density % o xparam1 [double] (p*1) vector of parameters to be estimated (initial values). -% o sampler_options structure -% .invhess [double] (p*p) matrix, posterior covariance matrix (at the mode). % o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. % o dataset_ data structure % o dataset_info dataset info structure @@ -37,7 +33,7 @@ function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_ % Then the comments write here can be used for all the other pairs of % parallel functions and also for management functions. -% Copyright (C) 2006-2017 Dynare Team +% Copyright (C) 2006-2021 Dynare Team % % This file is part of Dynare. % @@ -56,7 +52,7 @@ function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_ lambda = exp(bsxfun(@minus,options_.dsmh.H,1:1:options_.dsmh.H)/(options_.dsmh.H-1)*log(options_.dsmh.lambda1)); -c = 0.055 ; +c = 0.055 ; % Step 0: Initialization of the sampler [ param, tlogpost_iminus1, loglik, npar, ~, bayestopt_] = ... @@ -65,24 +61,24 @@ c = 0.055 ; ESS = zeros(options_.dsmh.H,1) ; zhat = 1 ; -% The DSMH starts here - for i=2:options_.dsmh.H +% The DSMH starts here +for i=2:options_.dsmh.H disp(''); - disp('Tempered iteration'); - disp(i) ; - % Step 1: sort the densities and compute IS weigths + disp('Tempered iteration'); + disp(i) ; + % Step 1: sort the densities and compute IS weigths [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) ; [tlogpost_i,weights,zhat,ESS,mu,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) ; % Step 2: tune c_i c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); % Step 3: Metropolis step [param,tlogpost_iminus1,loglik] = mutation_DSMH(TargetFun,param,tlogpost_i,tlogpost_iminus1,loglik,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - end - +end + weights = exp(loglik*(lambda(end)-lambda(end-1))); weights = weights/sum(weights); indx_resmpl = smc_resampling(weights,rand(1,1),options_.dsmh.number_of_particles); -distrib_param = param(:,indx_resmpl); +distrib_param = param(:,indx_resmpl); mean_xparam = mean(distrib_param,2); %mat_var_cov = bsxfun(@minus,distrib_param,mean_xparam) ; @@ -123,134 +119,134 @@ kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform a plt = 1 ; %for plt = 1:nbplt, +if TeX + NAMES = []; + TeXNAMES = []; +end +hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); +for k=1:npar %min(nstar,npar-(plt-1)*nstar) + subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) + %kk = (plt-1)*nstar+k; + [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); + optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.dsmh.number_of_particles,bandwidth,kernel_function); + [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... + options_.dsmh.number_of_particles,optimal_bandwidth,kernel_function); + plot(density(:,1),density(:,2)); + hold on if TeX - NAMES = []; - TeXNAMES = []; - end - hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); - for k=1:npar %min(nstar,npar-(plt-1)*nstar) - subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) - %kk = (plt-1)*nstar+k; - [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); - optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.dsmh.number_of_particles,bandwidth,kernel_function); - [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... - options_.dsmh.number_of_particles,optimal_bandwidth,kernel_function); - plot(density(:,1),density(:,2)); - hold on - if TeX - title(texname,'interpreter','latex') - else - title(name,'interpreter','none') - end - hold off - axis tight - drawnow - end - dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); - if TeX && any(strcmp('eps',cellstr(options_.graph_format))) - % TeX eps loader file - fprintf(fidTeX,'\\begin{figure}[H]\n'); - fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt)); - fprintf(fidTeX,'\\caption{Parameter densities based on the Dynamic Striated Metropolis-Hastings algorithm.}'); - fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); - fprintf(fidTeX,'\\end{figure}\n'); - fprintf(fidTeX,' \n'); + title(texname,'interpreter','latex') + else + title(name,'interpreter','none') end + hold off + axis tight + drawnow +end +dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); +if TeX && any(strcmp('eps',cellstr(options_.graph_format))) + % TeX eps loader file + fprintf(fidTeX,'\\begin{figure}[H]\n'); + fprintf(fidTeX,'\\centering \n'); + fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt)); + fprintf(fidTeX,'\\caption{Parameter densities based on the Dynamic Striated Metropolis-Hastings algorithm.}'); + fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); + fprintf(fidTeX,'\\end{figure}\n'); + fprintf(fidTeX,' \n'); +end %end - -function [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) - [~,indx_ord] = sortrows(tlogpost_iminus1); - tlogpost_iminus1 = tlogpost_iminus1(indx_ord); - param = param(:,indx_ord); - loglik = loglik(indx_ord); -function [tlogpost_i,weights,zhat,ESS,mu,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) - if i==1 - tlogpost_i = tlogpost_iminus1 + loglik*lambda(i); - else - tlogpost_i = tlogpost_iminus1 + loglik*(lambda(i)-lambda(i-1)); - end - weights = exp(tlogpost_i-tlogpost_iminus1); - zhat = (mean(weights))*zhat ; - weights = weights/sum(weights); - ESS(i) = 1/sum(weights.^2); - % estimates of mean and variance - mu = param*weights; - z = bsxfun(@minus,param,mu); - Omega = z*diag(weights)*z'; - Omegachol = chol(Omega)'; +function [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) +[~,indx_ord] = sortrows(tlogpost_iminus1); +tlogpost_iminus1 = tlogpost_iminus1(indx_ord); +param = param(:,indx_ord); +loglik = loglik(indx_ord); + +function [tlogpost_i,weights,zhat,ESS,mu,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) +if i==1 + tlogpost_i = tlogpost_iminus1 + loglik*lambda(i); +else + tlogpost_i = tlogpost_iminus1 + loglik*(lambda(i)-lambda(i-1)); +end +weights = exp(tlogpost_i-tlogpost_iminus1); +zhat = (mean(weights))*zhat ; +weights = weights/sum(weights); +ESS(i) = 1/sum(weights.^2); +% estimates of mean and variance +mu = param*weights; +z = bsxfun(@minus,param,mu); +Omega = z*diag(weights)*z'; +Omegachol = chol(Omega)'; function c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) - disp('tuning c_i...'); - disp('Initial value ='); - disp(c) ; - npar = size(param,1); - lower_prob = (.5*(options_.dsmh.alpha0+options_.dsmh.alpha1))^5; - upper_prob = (.5*(options_.dsmh.alpha0+options_.dsmh.alpha1))^(1/5); - stop=0 ; - while stop==0 - acpt = 0.0; - indx_resmpl = smc_resampling(weights,rand(1,1),options_.dsmh.G); - param0 = param(:,indx_resmpl); - tlogpost0 = tlogpost_i(indx_resmpl); - for j=1:options_.dsmh.G - for l=1:options_.dsmh.K - validate = 0; - while validate == 0 - candidate = param0(:,j) + sqrt(c)*Omegachol*randn(npar,1); - if all(candidate >= mh_bounds.lb) && all(candidate <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; - if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; + validate= 0; + while validate==0 + candidate = param0(:,j) + sqrt(c)*Omegachol*randn(npar,1); + if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) + validate = 1; if u2= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; - if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) + validate = 1; + if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; - if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) + [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); + if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) + validate = 1; + if rand(1,1) Date: Wed, 12 Jan 2022 10:54:16 +0100 Subject: [PATCH 092/101] online_auxiliary_filter.m: fix infinite loop --- src/online_auxiliary_filter.m | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 91c51f530..2bf26e4b7 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -119,7 +119,7 @@ for t=1:sample_size % model resolution [info, Model, DynareOptions, DynareResults, ReducedForm] = ... solve_model_for_online_filter(false, fore_xparam(:,i), DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults); - if ~info + if ~info(1) steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; % Set local state space model (second-order approximation). @@ -166,13 +166,15 @@ for t=1:sample_size wtilde = zeros(1, number_of_particles); for i=1:number_of_particles info = 12042009; - while info + counter=0; + while info(1) && counter =bounds.lb) && all(candidate<=bounds.ub) % model resolution for new parameters particles [info, Model, DynareOptions, DynareResults, ReducedForm] = ... solve_model_for_online_filter(false, candidate, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults) ; - if ~info + if ~info(1) xparam(:,i) = candidate ; steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; @@ -209,6 +211,13 @@ for t=1:sample_size wtilde(i) = w_stage1(i)*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError), 1))); end end + if counter==DynareOptions.particle.liu_west_max_resampling_tries + fprintf('\nLiu & West particle filter: I haven''t been able to solve the model in %u tries.\n',DynareOptions.particle.liu_west_max_resampling_tries) + fprintf('Liu & West particle filter: The last error message was: %s\n',get_error_message(info)) + fprintf('Liu & West particle filter: You can try to increase liu_west_max_resampling_tries, but most\n') + fprintf('Liu & West particle filter: likely there is an issue with the model.\n') + error('Liu & West particle filter: unable to solve the model.') + end end end % normalization From d20be2c271b442d91bd36aea300e4837a066ae2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Fri, 4 Feb 2022 11:29:31 +0100 Subject: [PATCH 093/101] Update calling sequence of local_state_space_iteration_k for new Fortran version --- src/auxiliary_particle_filter.m | 9 +++++---- src/conditional_filter_proposal.m | 5 +++-- src/gaussian_filter_bank.m | 7 ++++--- src/gaussian_mixture_filter_bank.m | 7 ++++--- src/measurement_equations.m | 7 ++++--- src/nonlinear_kalman_filter.m | 7 ++++--- src/online_auxiliary_filter.m | 8 +++++--- src/sequential_importance_particle_filter.m | 7 ++++--- src/solve_model_for_online_filter.m | 5 +++-- 9 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 6a4e89feb..607400a5c 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -3,7 +3,7 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptio % Evaluates the likelihood of a nonlinear model with the auxiliary particle filter % allowing eventually resampling. % -% Copyright (C) 2011-2019 Dynare Team +% Copyright (C) 2011-2022 Dynare Team % % This file is part of Dynare (particles module). % @@ -42,6 +42,7 @@ number_of_particles = ParticleOptions.number_of_particles; if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else % Set local state space model (first order approximation). ghx = ReducedForm.ghx; @@ -96,7 +97,7 @@ for t=1:sample_size if ReducedForm.use_k_order_solver tmp = 0; for i=1:size(nodes) - tmp = tmp + nodes_weights(i)*local_state_space_iteration_k(yhat, nodes(i,:)'*ones(1,number_of_particles), dr, Model, DynareOptions); + tmp = tmp + nodes_weights(i)*local_state_space_iteration_k(yhat, nodes(i,:)'*ones(1,number_of_particles), dr, Model, DynareOptions, udr); end else tmp = 0; @@ -121,7 +122,7 @@ for t=1:sample_size StateVectors_ = tmp_(mf0,:); else if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); end @@ -144,4 +145,4 @@ for t=1:sample_size end end -LIK = -sum(lik(start:end)); \ No newline at end of file +LIK = -sum(lik(start:end)); diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 3b6b65538..47e53b5ac 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -22,7 +22,7 @@ function [ProposalStateVector, Weights, flag] = conditional_filter_proposal(Redu % - Weights % - flag -% Copyright © 2012-2020 Dynare Team +% Copyright © 2012-2022 Dynare Team % % This file is part of Dynare. % @@ -43,6 +43,7 @@ flag = false; if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else % Set local state space model (first-order approximation). ghx = ReducedForm.ghx; @@ -79,7 +80,7 @@ epsilon = Q_lower_triangular_cholesky*nodes'; yhat = repmat(StateVectors-state_variables_steady_state, 1, size(epsilon, 2)); if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); end diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index d7361207b..453f038d9 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -22,7 +22,7 @@ function [PredictedStateMean, PredictedStateVarianceSquareRoot, StateVectorMean, % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2017 Dynare Team +% Copyright (C) 2009-2022 Dynare Team % % This file is part of Dynare. % @@ -41,6 +41,7 @@ function [PredictedStateMean, PredictedStateVarianceSquareRoot, StateVectorMean, if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else % Set local state space model (first-order approximation). ghx = ReducedForm.ghx; @@ -81,7 +82,7 @@ StateVectors = sigma_points(1:number_of_state_variables,:); epsilon = sigma_points(number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations,:); yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); end @@ -116,4 +117,4 @@ else StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; -end \ No newline at end of file +end diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index 74b9dea47..18d52add2 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -24,7 +24,7 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2019 Dynare Team +% Copyright (C) 2009-2022 Dynare Team % % This file is part of Dynare. % @@ -43,6 +43,7 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else % Set local state space model (first-order approximation). ghx = ReducedForm.ghx; @@ -77,7 +78,7 @@ epsilon = bsxfun(@plus, StructuralShocksSqrtP*nodes3(:,number_of_state_variables StateVectors = bsxfun(@plus, StateSqrtP*nodes3(:,1:number_of_state_variables)', StateMu); yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); end @@ -123,4 +124,4 @@ StateSqrtPPrior = reduced_rank_cholesky(PredictedStateVariance)'; StateWeightsPrior = StateWeights*StructuralShocksWeights; StateMuPost = StateVectorMean; StateSqrtPPost = StateVectorVarianceSquareRoot; -StateWeightsPost = StateWeightsPrior*ObservationShocksWeights*data_lik_GM_g; \ No newline at end of file +StateWeightsPost = StateWeightsPrior*ObservationShocksWeights*data_lik_GM_g; diff --git a/src/measurement_equations.m b/src/measurement_equations.m index 87edc75fc..bee47b7a9 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -1,6 +1,6 @@ function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions, DynareOptions, Model) -% Copyright (C) 2013-2019 Dynare Team +% Copyright (C) 2013-2022 Dynare Team % % This file is part of Dynare. % @@ -20,6 +20,7 @@ function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions mf1 = ReducedForm.mf1; if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else ghx = ReducedForm.ghx(mf1,:); ghu = ReducedForm.ghu(mf1,:); @@ -32,8 +33,8 @@ state_variables_steady_state = ReducedForm.state_variables_steady_state; number_of_structural_innovations = length(ReducedForm.Q); yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, size(yhat,2)), dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, size(yhat,2)), dr, Model, DynareOptions, udr); measure = tmp(mf1,:); else measure = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); -end \ No newline at end of file +end diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index 322eb6e6e..c28cf9a27 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -32,7 +32,7 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2019 Dynare Team +% Copyright (C) 2009-2022 Dynare Team % % This file is part of Dynare. % @@ -56,6 +56,7 @@ end if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else % Set local state space model (first-order approximation). ghx = ReducedForm.ghx; @@ -116,7 +117,7 @@ for t=1:sample_size epsilon = sigma_points(number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations,:); yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); end @@ -161,4 +162,4 @@ for t=1:sample_size lik(t) = log( sum(probability2(Y(:,t),H_lower_triangular_cholesky,tmp(mf1,:)).*weights,1) ) ; end -LIK = -sum(lik(start:end)); \ No newline at end of file +LIK = -sum(lik(start:end)); diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 2bf26e4b7..bfb4383c5 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -21,7 +21,7 @@ function [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxili % - p975 [double] n×1 vector, 97.5 percent of the particles are below p975(i) for i=1,…,n. % - covariance [double] n×n matrix, covariance of the particles at the end of the sample. -% Copyright © 2013-2021 Dynare Team +% Copyright © 2013-2022 Dynare Team % % This file is part of Dynare. % @@ -125,6 +125,7 @@ for t=1:sample_size % Set local state space model (second-order approximation). if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else constant = ReducedForm.constant; % Set local state space model (first-order approximation). @@ -138,7 +139,7 @@ for t=1:sample_size % particle likelihood contribution yhat = bsxfun(@minus, StateVectors(:,i), state_variables_steady_state); if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, 1), dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, 1), dr, Model, DynareOptions, udr); else if pruning yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); @@ -181,6 +182,7 @@ for t=1:sample_size % Set local state space model (second order approximation). if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else constant = ReducedForm.constant; % Set local state space model (first-order approximation). @@ -196,7 +198,7 @@ for t=1:sample_size % compute particles likelihood contribution yhat = bsxfun(@minus,StateVectors(:,i), state_variables_steady_state); if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else if pruning yhat_ = bsxfun(@minus,StateVectors_(:,i), state_variables_steady_state); diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 975ac1299..0c629dad0 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -2,7 +2,7 @@ function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,P % Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). -% Copyright (C) 2011-2015 Dynare Team +% Copyright (C) 2011-2022 Dynare Team % % This file is part of Dynare (particles module). % @@ -51,6 +51,7 @@ end if ReducedForm.use_k_order_solver dr = ReducedForm.dr; + udr = ReducedForm.udr; else % Set local state space model (first order approximation). ghx = ReducedForm.ghx; @@ -106,7 +107,7 @@ for t=1:sample_size [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); else if ReducedForm.use_k_order_solver - tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions); + tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); end @@ -143,4 +144,4 @@ for t=1:sample_size end end -LIK = -sum(lik(start:end)); \ No newline at end of file +LIK = -sum(lik(start:end)); diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 0b73d66dc..aa26efbf7 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -20,7 +20,7 @@ function [info, Model, DynareOptions, DynareResults, ReducedForm] = ... % - DynareResults [struct] Dynare results (oo_). % - ReducedForm [struct] Reduced form model. -% Copyright (C) 2013-2019 Dynare Team +% Copyright (C) 2013-2022 Dynare Team % % This file is part of Dynare. % @@ -164,6 +164,7 @@ if nargout>4 elseif DynareOptions.order>=3 ReducedForm.use_k_order_solver = true; ReducedForm.dr = dr; + ReducedForm.udr = folded_to_unfolded_dr(dr, Model, DynareOptions); else n_states=size(dr.ghx,2); n_shocks=size(dr.ghu,2); @@ -210,4 +211,4 @@ if setinitialcondition end ReducedForm.StateVectorMean = StateVectorMean; ReducedForm.StateVectorVariance = StateVectorVariance; -end \ No newline at end of file +end From 494248828735d762052877abc264d305146c366f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= Date: Wed, 9 Mar 2022 17:21:02 +0100 Subject: [PATCH 094/101] Routines moved out of the submodule. --- src/DSMH_initialization.m | 118 ------------ src/DSMH_sampler.m | 301 ------------------------------ src/Herbst_Schorfheide_sampler.m | 245 ------------------------ src/SMC_samplers_initialization.m | 117 ------------ src/smc_resampling.m | 11 -- src/tempered_likelihood.m | 5 - 6 files changed, 797 deletions(-) delete mode 100644 src/DSMH_initialization.m delete mode 100644 src/DSMH_sampler.m delete mode 100644 src/Herbst_Schorfheide_sampler.m delete mode 100644 src/SMC_samplers_initialization.m delete mode 100644 src/smc_resampling.m delete mode 100644 src/tempered_likelihood.m diff --git a/src/DSMH_initialization.m b/src/DSMH_initialization.m deleted file mode 100644 index a9b9ee1bd..000000000 --- a/src/DSMH_initialization.m +++ /dev/null @@ -1,118 +0,0 @@ -function [ ix2, temperedlogpost, loglik, ModelName, MetropolisFolder, npar, NumberOfParticles, bayestopt_] = ... - DSMH_initialization(TargetFun, xparam1, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) -% function [ ix2, ilogpo2, ModelName, MetropolisFolder, FirstBlock, FirstLine, npar, NumberOfParticles, bayestopt_] = ... -% DSMH_initialization(TargetFun, xparam1, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) -% Dynamic Striated Metropolis-Hastings initialization. -% -% INPUTS -% o TargetFun [char] string specifying the name of the objective -% function (tempered posterior kernel and likelihood). -% o xparam1 [double] (p*1) vector of parameters to be estimated (initial values). -% o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. -% o dataset_ data structure -% o dataset_info dataset info structure -% o options_ options structure -% o M_ model structure -% o estim_params_ estimated parameters structure -% o bayestopt_ estimation options structure -% o oo_ outputs structure -% -% OUTPUTS -% o ix2 [double] (NumberOfParticles*npar) vector of starting points for different chains -% o ilogpo2 [double] (NumberOfParticles*1) vector of initial posterior values for different chains -% o iloglik2 [double] (NumberOfParticles*1) vector of initial likelihood values for different chains -% o ModelName [string] name of the mod-file -% o MetropolisFolder [string] path to the Metropolis subfolder -% o npar [scalar] number of parameters estimated -% o NumberOfParticles [scalar] Number of particles requested for the parameters distributions -% o bayestopt_ [structure] estimation options structure -% -% SPECIAL REQUIREMENTS -% None. - -% Copyright (C) 2006-2017 Dynare Team -% -% This file is part of Dynare. -% -% Dynare is free software: you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% Dynare is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with Dynare. If not, see . - -%Initialize outputs -ix2 = []; -ilogpo2 = []; -iloglik2 = []; -ModelName = []; -MetropolisFolder = []; -npar = []; -NumberOfParticles = []; - -ModelName = M_.fname; -if ~isempty(M_.bvar) - ModelName = [ModelName '_bvar']; -end - -MetropolisFolder = CheckPath('dsmh',M_.dname); -BaseName = [MetropolisFolder filesep ModelName]; - -NumberOfParticles = options_.dsmh.number_of_particles; %Number of particles for the parameters -npar = length(xparam1); - -% Here we start a new DS Metropolis-Hastings, previous draws are discarded. -disp('Estimation::dsmh: Initialization...') -% Delete old dsmh files if any... -files = dir([BaseName '_dsmh*_blck*.mat']); -%if length(files) -% delete([BaseName '_dsmh*_blck*.mat']); -% disp('Estimation::smc: Old dsmh-files successfully erased!') -%end -% Delete old log file. -file = dir([ MetropolisFolder '/dsmh.log']); -%if length(file) -% delete([ MetropolisFolder '/dsmh.log']); -% disp('Estimation::dsmh: Old dsmh.log file successfully erased!') -% disp('Estimation::dsmh: Creation of a new dsmh.log file.') -%end -fidlog = fopen([MetropolisFolder '/dsmh.log'],'w'); -fprintf(fidlog,'%% DSMH log file (Dynare).\n'); -fprintf(fidlog,['%% ' datestr(now,0) '.\n']); -fprintf(fidlog,' \n\n'); -fprintf(fidlog,'%% Session 1.\n'); -fprintf(fidlog,' \n'); -prior_draw(bayestopt_,options_.prior_trunc); -% Find initial values for the NumberOfParticles chains... -set_dynare_seed('default'); -fprintf(fidlog,[' Initial values of the parameters:\n']); -disp('Estimation::dsmh: Searching for initial values...'); -ix2 = zeros(npar,NumberOfParticles); -temperedlogpost = zeros(NumberOfParticles,1); -loglik = zeros(NumberOfParticles,1); -%stderr = sqrt(bsxfun(@power,mh_bounds.ub-mh_bounds.lb,2)/12)/10; -for j=1:NumberOfParticles - validate = 0; - while validate == 0 - candidate = prior_draw()'; -% candidate = xparam1(:) + 0.001*randn(npar,1);%bsxfun(@times,stderr,randn(npar,1)) ; - if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - ix2(:,j) = candidate ; - [temperedlogpost(j),loglik(j)] = tempered_likelihood(TargetFun,candidate,0.0,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglik(j)) % if returned log-density is Inf or Nan (penalized value) - validate = 1; - end - end - end -end -fprintf(fidlog,' \n'); -disp('Estimation::dsmh: Initial values found!') -skipline() - - diff --git a/src/DSMH_sampler.m b/src/DSMH_sampler.m deleted file mode 100644 index 9c522f2a1..000000000 --- a/src/DSMH_sampler.m +++ /dev/null @@ -1,301 +0,0 @@ -function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) -% function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) -% Dynamic Striated Metropolis-Hastings algorithm. -% -% INPUTS -% o TargetFun [char] string specifying the name of the objective -% function (posterior kernel). -% o xparam1 [double] (p*1) vector of parameters to be estimated (initial values). -% o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. -% o dataset_ data structure -% o dataset_info dataset info structure -% o options_ options structure -% o M_ model structure -% o estim_params_ estimated parameters structure -% o bayestopt_ estimation options structure -% o oo_ outputs structure -% -% SPECIAL REQUIREMENTS -% None. -% -% PARALLEL CONTEXT -% The most computationally intensive part of this function may be executed -% in parallel. The code suitable to be executed in -% parallel on multi core or cluster machine (in general a 'for' cycle) -% has been removed from this function and been placed in the posterior_sampler_core.m funtion. -% -% The DYNARE parallel packages comprise a i) set of pairs of Matlab functions that can be executed in -% parallel and called name_function.m and name_function_core.m and ii) a second set of functions used -% to manage the parallel computations. -% -% This function was the first function to be parallelized. Later, other -% functions have been parallelized using the same methodology. -% Then the comments write here can be used for all the other pairs of -% parallel functions and also for management functions. - -% Copyright (C) 2006-2021 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 . - - -lambda = exp(bsxfun(@minus,options_.dsmh.H,1:1:options_.dsmh.H)/(options_.dsmh.H-1)*log(options_.dsmh.lambda1)); -c = 0.055 ; - -% Step 0: Initialization of the sampler -[ param, tlogpost_iminus1, loglik, npar, ~, bayestopt_] = ... - SMC_samplers_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,options_.dsmh.number_of_particles); - -ESS = zeros(options_.dsmh.H,1) ; -zhat = 1 ; - -% The DSMH starts here -for i=2:options_.dsmh.H - disp(''); - disp('Tempered iteration'); - disp(i) ; - % Step 1: sort the densities and compute IS weigths - [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) ; - [tlogpost_i,weights,zhat,ESS,mu,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) ; - % Step 2: tune c_i - c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - % Step 3: Metropolis step - [param,tlogpost_iminus1,loglik] = mutation_DSMH(TargetFun,param,tlogpost_i,tlogpost_iminus1,loglik,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); -end - -weights = exp(loglik*(lambda(end)-lambda(end-1))); -weights = weights/sum(weights); -indx_resmpl = smc_resampling(weights,rand(1,1),options_.dsmh.number_of_particles); -distrib_param = param(:,indx_resmpl); - -mean_xparam = mean(distrib_param,2); -%mat_var_cov = bsxfun(@minus,distrib_param,mean_xparam) ; -%mat_var_cov = (mat_var_cov*mat_var_cov')/(options_.HSsmc.nparticles-1) ; -%std_xparam = sqrt(diag(mat_var_cov)) ; -lb95_xparam = zeros(npar,1) ; -ub95_xparam = zeros(npar,1) ; -for i=1:npar - temp = sortrows(distrib_param(i,:)') ; - lb95_xparam(i) = temp(0.025*options_.HSsmc.nparticles) ; - ub95_xparam(i) = temp(0.975*options_.HSsmc.nparticles) ; -end - -TeX = options_.TeX; - -str = sprintf(' Param. \t Lower Bound (95%%) \t Mean \t Upper Bound (95%%)'); -for l=1:npar - [name,~] = get_the_name(l,TeX,M_,estim_params_,options_); - str = sprintf('%s\n %s \t\t %5.4f \t\t %7.5f \t\t %5.4f', str, name, lb95_xparam(l), mean_xparam(l), ub95_xparam(l)); -end -disp([str]) -disp('') - -%% Plot parameters densities - -[nbplt,nr,nc,lr,lc,nstar] = pltorg(npar); - -if TeX - fidTeX = fopen([M_.fname '_param_density.tex'],'w'); - fprintf(fidTeX,'%% TeX eps-loader file generated by DSMH.m (Dynare).\n'); - fprintf(fidTeX,['%% ' datestr(now,0) '\n']); - fprintf(fidTeX,' \n'); -end - -number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. -bandwidth = 0; % Rule of thumb optimal bandwidth parameter. -kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. - -plt = 1 ; -%for plt = 1:nbplt, -if TeX - NAMES = []; - TeXNAMES = []; -end -hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); -for k=1:npar %min(nstar,npar-(plt-1)*nstar) - subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) - %kk = (plt-1)*nstar+k; - [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); - optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.dsmh.number_of_particles,bandwidth,kernel_function); - [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... - options_.dsmh.number_of_particles,optimal_bandwidth,kernel_function); - plot(density(:,1),density(:,2)); - hold on - if TeX - title(texname,'interpreter','latex') - else - title(name,'interpreter','none') - end - hold off - axis tight - drawnow -end -dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); -if TeX && any(strcmp('eps',cellstr(options_.graph_format))) - % TeX eps loader file - fprintf(fidTeX,'\\begin{figure}[H]\n'); - fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt)); - fprintf(fidTeX,'\\caption{Parameter densities based on the Dynamic Striated Metropolis-Hastings algorithm.}'); - fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); - fprintf(fidTeX,'\\end{figure}\n'); - fprintf(fidTeX,' \n'); -end -%end - -function [tlogpost_iminus1,loglik,param] = sort_matrices(tlogpost_iminus1,loglik,param) -[~,indx_ord] = sortrows(tlogpost_iminus1); -tlogpost_iminus1 = tlogpost_iminus1(indx_ord); -param = param(:,indx_ord); -loglik = loglik(indx_ord); - -function [tlogpost_i,weights,zhat,ESS,mu,Omegachol] = compute_IS_weights_and_moments(param,tlogpost_iminus1,loglik,lambda,i,zhat,ESS) -if i==1 - tlogpost_i = tlogpost_iminus1 + loglik*lambda(i); -else - tlogpost_i = tlogpost_iminus1 + loglik*(lambda(i)-lambda(i-1)); -end -weights = exp(tlogpost_i-tlogpost_iminus1); -zhat = (mean(weights))*zhat ; -weights = weights/sum(weights); -ESS(i) = 1/sum(weights.^2); -% estimates of mean and variance -mu = param*weights; -z = bsxfun(@minus,param,mu); -Omega = z*diag(weights)*z'; -Omegachol = chol(Omega)'; - -function c = tune_c(TargetFun,param,tlogpost_i,lambda,i,c,Omegachol,weights,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) -disp('tuning c_i...'); -disp('Initial value ='); -disp(c) ; -npar = size(param,1); -lower_prob = (.5*(options_.dsmh.alpha0+options_.dsmh.alpha1))^5; -upper_prob = (.5*(options_.dsmh.alpha0+options_.dsmh.alpha1))^(1/5); -stop=0 ; -while stop==0 - acpt = 0.0; - indx_resmpl = smc_resampling(weights,rand(1,1),options_.dsmh.G); - param0 = param(:,indx_resmpl); - tlogpost0 = tlogpost_i(indx_resmpl); - for j=1:options_.dsmh.G - for l=1:options_.dsmh.K - validate = 0; - while validate == 0 - candidate = param0(:,j) + sqrt(c)*Omegachol*randn(npar,1); - if all(candidate >= mh_bounds.lb) && all(candidate <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; - if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,lambda(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; - if u2. - - -% Create the tempering schedule -phi = bsxfun(@power,(bsxfun(@minus,1:1:options_.HSsmc.nphi,1)/(options_.HSsmc.nphi-1)),options_.HSsmc.lambda) ; -% tuning for MH algorithms matrices -zhat = 0 ; % normalization constant -csim = zeros(options_.HSsmc.nphi,1) ; % scale parameter -ESSsim = zeros(options_.HSsmc.nphi,1) ; % ESS -acptsim = zeros(options_.HSsmc.nphi,1) ; % average acceptance rate -% Step 0: Initialization of the sampler -[ param, tlogpost_i, loglik, npar, ~, bayestopt_] = ... - SMC_samplers_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,options_.HSsmc.nparticles); -weights = ones(options_.HSsmc.nparticles,1)/options_.HSsmc.nparticles ; -% The Herbst and Schorfheide sampler starts here -for i=2:options_.HSsmc.nphi - % (a) Correction - % incremental weights - incwt = exp((phi(i)-phi(i-1))*loglik) ; - % update weights - weights = bsxfun(@times,weights,incwt) ; - sum_weights = sum(weights) ; - zhat = zhat + log(sum_weights) ; - % normalize weights - weights = weights/sum_weights ; - % (b) Selection - ESSsim(i) = 1/sum(weights.^2) ; - if (ESSsim(i) < options_.HSsmc.nparticles/2) - indx_resmpl = smc_resampling(weights,rand(1,1),options_.HSsmc.nparticles) ; - param = param(:,indx_resmpl) ; - loglik = loglik(indx_resmpl) ; - tlogpost_i = tlogpost_i(indx_resmpl) ; - weights = ones(options_.HSsmc.nparticles,1)/options_.HSsmc.nparticles ; - end - % (c) Mutation - options_.HSsmc.c = options_.HSsmc.c*modified_logit(0.95,0.1,16.0,options_.HSsmc.acpt-options_.HSsmc.trgt) ; - % Calculate estimates of mean and variance - mu = param*weights ; - z = bsxfun(@minus,param,mu) ; - R = z*(bsxfun(@times,z',weights)) ; - Rchol = chol(R)' ; - % Mutation - if options_.HSsmc.option_mutation==1 - [param,tlogpost_i,loglik,options_.HSsmc.acpt] = mutation_RW(TargetFun,param,tlogpost_i,loglik,phi,i,options_.HSsmc.c*Rchol,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) ; - elseif options_.HSsmc.option_mutation==2 - inv_R = inv(options_.HSsmc.c^2*R) ; - Rdiagchol = sqrt(diag(R)) ; - [param,tlogpost_i,loglik,options_.HSsmc.acpt] = mutation_Mixture(TargetFun,param,tlogpost_i,loglik,phi,i,options_.HSsmc.c*Rchol,options_.HSsmc.c*Rdiagchol,inv_R,mu,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) ; - end - acptsim(i) = options_.HSsmc.acpt ; - csim(i) = options_.HSsmc.c ; - % print information - fprintf(' Iteration = %5.0f / %5.0f \n', i, options_.HSsmc.nphi); - fprintf(' phi = %5.4f \n', phi(i)); - fprintf(' Neff = %5.4f \n', ESSsim(i)); - fprintf(' %accept. = %5.4f \n', acptsim(i)); -end -indx_resmpl = smc_resampling(weights,rand(1,1),options_.HSsmc.nparticles); -distrib_param = param(:,indx_resmpl); -fprintf(' Log_lik = %5.4f \n', zhat); - -mean_xparam = mean(distrib_param,2); -%mat_var_cov = bsxfun(@minus,distrib_param,mean_xparam) ; -%mat_var_cov = (mat_var_cov*mat_var_cov')/(options_.HSsmc.nparticles-1) ; -%std_xparam = sqrt(diag(mat_var_cov)) ; -lb95_xparam = zeros(npar,1) ; -ub95_xparam = zeros(npar,1) ; -for i=1:npar - temp = sortrows(distrib_param(i,:)') ; - lb95_xparam(i) = temp(0.025*options_.HSsmc.nparticles) ; - ub95_xparam(i) = temp(0.975*options_.HSsmc.nparticles) ; -end - -TeX = options_.TeX; - -str = sprintf(' Param. \t Lower Bound (95%%) \t Mean \t Upper Bound (95%%)'); -for l=1:npar - [name,~] = get_the_name(l,TeX,M_,estim_params_,options_); - str = sprintf('%s\n %s \t\t %5.4f \t\t %7.5f \t\t %5.4f', str, name, lb95_xparam(l), mean_xparam(l), ub95_xparam(l)); -end -disp([str]) -disp('') - -%% Plot parameters densities - -[nbplt,nr,nc,lr,lc,nstar] = pltorg(npar); - -if TeX - fidTeX = fopen([M_.fname '_param_density.tex'],'w'); - fprintf(fidTeX,'%% TeX eps-loader file generated by DSMH.m (Dynare).\n'); - fprintf(fidTeX,['%% ' datestr(now,0) '\n']); - fprintf(fidTeX,' \n'); -end - -number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. -bandwidth = 0; % Rule of thumb optimal bandwidth parameter. -kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. -plt = 1 ; -%for plt = 1:nbplt, -if TeX - NAMES = []; - TeXNAMES = []; -end -hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); -for k=1:npar %min(nstar,npar-(plt-1)*nstar) - subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) - %kk = (plt-1)*nstar+k; - [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); - optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.HSsmc.nparticles,bandwidth,kernel_function); - [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... - options_.HSsmc.nparticles,optimal_bandwidth,kernel_function); - plot(density(:,1),density(:,2)); - hold on - if TeX - title(texname,'interpreter','latex') - else - title(name,'interpreter','none') - end - hold off - axis tight - drawnow -end -dyn_saveas(hh,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format); -if TeX && any(strcmp('eps',cellstr(options_.graph_format))) - % TeX eps loader file - fprintf(fidTeX,'\\begin{figure}[H]\n'); - fprintf(fidTeX,'\\centering \n'); - fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt)); - fprintf(fidTeX,'\\caption{Parameter densities based on the Herbst/Schorfheide sampler.}'); - fprintf(fidTeX,'\\label{Fig:ParametersDensities:%s}\n',int2str(plt)); - fprintf(fidTeX,'\\end{figure}\n'); - fprintf(fidTeX,' \n'); -end -%end - -function [param,tlogpost_i,loglik,acpt] = mutation_RW(TargetFun,param,tlogpost_i,loglik,phi,i,cRchol,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) -acpt = 0.0 ; -tlogpost_i = tlogpost_i + (phi(i)-phi(i-1))*loglik ; -for j=1:options_.HSsmc.nparticles - validate= 0; - while validate==0 - candidate = param(:,j) + cRchol*randn(size(param,1),1) ; - if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; - if rand(1,1)= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - [tlogpostx,loglikx] = tempered_likelihood(TargetFun,candidate,phi(i),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglikx) % if returned log-density is not Inf or Nan (penalized value) - validate = 1; - if rand(1,1). - -%Initialize outputs -ix2 = []; -ilogpo2 = []; -iloglik2 = []; -ModelName = []; -MetropolisFolder = []; -npar = []; - -ModelName = M_.fname; -if ~isempty(M_.bvar) - ModelName = [ModelName '_bvar']; -end - -MetropolisFolder = CheckPath('dsmh',M_.dname); -BaseName = [MetropolisFolder filesep ModelName]; - -npar = length(xparam1); - -% Here we start a new DS Metropolis-Hastings, previous draws are discarded. -disp('Estimation:: Initialization...') -% Delete old dsmh files if any... -files = dir([BaseName '_dsmh*_blck*.mat']); -%if length(files) -% delete([BaseName '_dsmh*_blck*.mat']); -% disp('Estimation::smc: Old dsmh-files successfully erased!') -%end -% Delete old log file. -file = dir([ MetropolisFolder '/dsmh.log']); -%if length(file) -% delete([ MetropolisFolder '/dsmh.log']); -% disp('Estimation::dsmh: Old dsmh.log file successfully erased!') -% disp('Estimation::dsmh: Creation of a new dsmh.log file.') -%end -fidlog = fopen([MetropolisFolder '/dsmh.log'],'w'); -fprintf(fidlog,'%% DSMH log file (Dynare).\n'); -fprintf(fidlog,['%% ' datestr(now,0) '.\n']); -fprintf(fidlog,' \n\n'); -fprintf(fidlog,'%% Session 1.\n'); -fprintf(fidlog,' \n'); -prior_draw(bayestopt_,options_.prior_trunc); -% Find initial values for the NumberOfParticles chains... -set_dynare_seed('default'); -fprintf(fidlog,[' Initial values of the parameters:\n']); -disp('Estimation::dsmh: Searching for initial values...'); -ix2 = zeros(npar,NumberOfParticles); -temperedlogpost = zeros(NumberOfParticles,1); -loglik = zeros(NumberOfParticles,1); -%stderr = sqrt(bsxfun(@power,mh_bounds.ub-mh_bounds.lb,2)/12)/10; -for j=1:NumberOfParticles - validate = 0; - while validate == 0 - candidate = prior_draw()'; -% candidate = xparam1(:) + 0.001*randn(npar,1);%bsxfun(@times,stderr,randn(npar,1)) ; - if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) - ix2(:,j) = candidate ; - [temperedlogpost(j),loglik(j)] = tempered_likelihood(TargetFun,candidate,0.0,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); - if isfinite(loglik(j)) % if returned log-density is Inf or Nan (penalized value) - validate = 1; - end - end - end -end -fprintf(fidlog,' \n'); -disp('Estimation:: Initial values found!') -skipline() - - diff --git a/src/smc_resampling.m b/src/smc_resampling.m deleted file mode 100644 index bac7eeac0..000000000 --- a/src/smc_resampling.m +++ /dev/null @@ -1,11 +0,0 @@ -function indx = smc_resampling(weights,noise,number) - indx = zeros(number,1); - cumweights = cumsum(weights); - randvec = (transpose(1:number)-1+noise(:))/number; - j = 1; - for i=1:number - while (randvec(i)>cumweights(j)) - j = j+1; - end - indx(i) = j; - end diff --git a/src/tempered_likelihood.m b/src/tempered_likelihood.m deleted file mode 100644 index 4af11080a..000000000 --- a/src/tempered_likelihood.m +++ /dev/null @@ -1,5 +0,0 @@ - function [tlogpostkern,loglik] = tempered_likelihood(TargetFun,xparam1,lambda,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_) - logpostkern = -feval(TargetFun,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_); - logprior = priordens(xparam1,bayestopt_.pshape,bayestopt_.p6,bayestopt_.p7,bayestopt_.p3,bayestopt_.p4); - loglik = logpostkern-logprior ; - tlogpostkern = lambda*loglik + logprior; From d71f8be6e777fd3e08f1ab2cb74bbf9621ad2d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Wed, 13 Apr 2022 14:47:52 +0200 Subject: [PATCH 095/101] Use Unicode copyright symbol (in UTF-8 encoding) in all source files It is now supported by the MATLAB editor (as of R2022a). --- src/auxiliary_initialization.m | 2 +- src/auxiliary_particle_filter.m | 2 +- src/conditional_particle_filter.m | 2 +- src/fit_gaussian_mixture.m | 2 +- src/gaussian_densities.m | 2 +- src/gaussian_filter.m | 2 +- src/gaussian_filter_bank.m | 2 +- src/gaussian_mixture_densities.m | 2 +- src/gaussian_mixture_filter.m | 2 +- src/gaussian_mixture_filter_bank.m | 2 +- src/importance_sampling.m | 2 +- src/measurement_equations.m | 2 +- src/multivariate_smooth_resampling.m | 2 +- src/mykmeans.m | 2 +- src/neff.m | 2 +- src/nonlinear_kalman_filter.m | 2 +- src/probability.m | 2 +- src/probability2.m | 2 +- src/probability3.m | 2 +- src/resample.m | 2 +- src/residual_resampling.m | 2 +- src/sequential_importance_particle_filter.m | 2 +- src/solve_model_for_online_filter.m | 2 +- src/spherical_radial_sigma_points.m | 2 +- src/traditional_resampling.m | 2 +- src/univariate_smooth_resampling.m | 2 +- src/unscented_sigma_points.m | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index ac74204b0..8355e75ab 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -2,7 +2,7 @@ function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,Par % Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. -% Copyright (C) 2011-2017 Dynare Team +% Copyright © 2011-2017 Dynare Team % % This file is part of Dynare (particles module). % diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 607400a5c..2caa3e919 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -3,7 +3,7 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptio % Evaluates the likelihood of a nonlinear model with the auxiliary particle filter % allowing eventually resampling. % -% Copyright (C) 2011-2022 Dynare Team +% Copyright © 2011-2022 Dynare Team % % This file is part of Dynare (particles module). % diff --git a/src/conditional_particle_filter.m b/src/conditional_particle_filter.m index a71d413ea..db204dc85 100644 --- a/src/conditional_particle_filter.m +++ b/src/conditional_particle_filter.m @@ -35,7 +35,7 @@ function [LIK,lik] = conditional_particle_filter(ReducedForm, Y, s, ParticleOpti % it has been derived in a linear context and is implemented in a nonlinear % context. That is why particle resampling is performed. -% Copyright (C) 2009-2020 Dynare Team +% Copyright © 2009-2020 Dynare Team % % This file is part of Dynare. % diff --git a/src/fit_gaussian_mixture.m b/src/fit_gaussian_mixture.m index 00970da6f..9836fa59e 100644 --- a/src/fit_gaussian_mixture.m +++ b/src/fit_gaussian_mixture.m @@ -1,6 +1,6 @@ function [StateMu,StateSqrtP,StateWeights] = fit_gaussian_mixture(X,X_weights,StateMu,StateSqrtP,StateWeights,crit,niters,check) -% Copyright (C) 2013-2017 Dynare Team +% Copyright © 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_densities.m b/src/gaussian_densities.m index 4cc441d65..727d083c4 100644 --- a/src/gaussian_densities.m +++ b/src/gaussian_densities.m @@ -20,7 +20,7 @@ function IncrementalWeights = gaussian_densities(obs,mut_t,sqr_Pss_t_t,st_t_1,sq % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2019 Dynare Team +% Copyright © 2009-2019 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_filter.m b/src/gaussian_filter.m index 8119ffb9b..9b1b29e4c 100644 --- a/src/gaussian_filter.m +++ b/src/gaussian_filter.m @@ -32,7 +32,7 @@ function [LIK,lik] = gaussian_filter(ReducedForm, Y, start, ParticleOptions, Thr % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2019 Dynare Team +% Copyright © 2009-2019 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index 453f038d9..6108ab21d 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -22,7 +22,7 @@ function [PredictedStateMean, PredictedStateVarianceSquareRoot, StateVectorMean, % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2022 Dynare Team +% Copyright © 2009-2022 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_mixture_densities.m b/src/gaussian_mixture_densities.m index 8a12b102e..0cf9dd79e 100644 --- a/src/gaussian_mixture_densities.m +++ b/src/gaussian_mixture_densities.m @@ -22,7 +22,7 @@ function IncrementalWeights = gaussian_mixture_densities(obs, StateMuPrior, Sta % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2019 Dynare Team +% Copyright © 2009-2019 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_mixture_filter.m b/src/gaussian_mixture_filter.m index 0f4a8d180..e06461b85 100644 --- a/src/gaussian_mixture_filter.m +++ b/src/gaussian_mixture_filter.m @@ -36,7 +36,7 @@ function [LIK, lik] = gaussian_mixture_filter(ReducedForm, Y, start, ParticleOpt % % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2017 Dynare Team +% Copyright © 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index 18d52add2..88d3628b8 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -24,7 +24,7 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2022 Dynare Team +% Copyright © 2009-2022 Dynare Team % % This file is part of Dynare. % diff --git a/src/importance_sampling.m b/src/importance_sampling.m index 357854cc3..d477f9f50 100644 --- a/src/importance_sampling.m +++ b/src/importance_sampling.m @@ -1,6 +1,6 @@ function State_Particles = importance_sampling(StateMuPost,StateSqrtPPost,StateWeightsPost,numP) -% Copyright (C) 2013-2017 Dynare Team +% Copyright © 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/measurement_equations.m b/src/measurement_equations.m index bee47b7a9..4e11dd064 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -1,6 +1,6 @@ function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions, DynareOptions, Model) -% Copyright (C) 2013-2022 Dynare Team +% Copyright © 2013-2022 Dynare Team % % This file is part of Dynare. % diff --git a/src/multivariate_smooth_resampling.m b/src/multivariate_smooth_resampling.m index 52e9411d6..a83d348c2 100644 --- a/src/multivariate_smooth_resampling.m +++ b/src/multivariate_smooth_resampling.m @@ -38,7 +38,7 @@ function new_particles = multivariate_smooth_resampling(particles,weights) %! @end deftypefn %@eod: -% Copyright (C) 2012-2017 Dynare Team +% Copyright © 2012-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/mykmeans.m b/src/mykmeans.m index 30f5b902a..e7c424b00 100644 --- a/src/mykmeans.m +++ b/src/mykmeans.m @@ -1,6 +1,6 @@ function [c,SqrtVariance,Weights] = mykmeans(x,g,init,cod) -% Copyright (C) 2013-2017 Dynare Team +% Copyright © 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/neff.m b/src/neff.m index d6d80e464..bd428fcd1 100644 --- a/src/neff.m +++ b/src/neff.m @@ -1,7 +1,7 @@ function n = neff(w) % Evaluates the criterion for resampling -% Copyright (C) 2013-2014 Dynare Team +% Copyright © 2013-2014 Dynare Team % % This file is part of Dynare. % diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index c28cf9a27..9decb3225 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -32,7 +32,7 @@ function [LIK,lik] = nonlinear_kalman_filter(ReducedForm, Y, start, ParticleOpti % NOTES % The vector "lik" is used to evaluate the jacobian of the likelihood. -% Copyright (C) 2009-2022 Dynare Team +% Copyright © 2009-2022 Dynare Team % % This file is part of Dynare. % diff --git a/src/probability.m b/src/probability.m index 2368cbdca..a934b48d8 100644 --- a/src/probability.m +++ b/src/probability.m @@ -1,6 +1,6 @@ function [prior,likelihood,C,posterior] = probability(mu,sqrtP,prior,X) -% Copyright (C) 2013-2017 Dynare Team +% Copyright © 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/probability2.m b/src/probability2.m index f9b4f0b9f..e37cfe3d1 100644 --- a/src/probability2.m +++ b/src/probability2.m @@ -14,7 +14,7 @@ function [density] = probability2(mu,S,X) % % NOTES % -% Copyright (C) 2009-2017 Dynare Team +% Copyright © 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/probability3.m b/src/probability3.m index bafac9528..18dc442b8 100644 --- a/src/probability3.m +++ b/src/probability3.m @@ -1,6 +1,6 @@ function [prior,likelihood,C,posterior] = probability3(mu,sqrtP,prior,X,X_weights) -% Copyright (C) 2013-2017 Dynare Team +% Copyright © 2013-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/resample.m b/src/resample.m index c9ac9cd78..fc50173c2 100644 --- a/src/resample.m +++ b/src/resample.m @@ -36,7 +36,7 @@ function resampled_output = resample(particles,weights,ParticleOptions) %! @end deftypefn %@eod: -% Copyright (C) 2011-2014 Dynare Team +% Copyright © 2011-2014 Dynare Team % % This file is part of Dynare. % diff --git a/src/residual_resampling.m b/src/residual_resampling.m index 1b8752a2c..ee0ccf9ee 100644 --- a/src/residual_resampling.m +++ b/src/residual_resampling.m @@ -30,7 +30,7 @@ function return_resample = residual_resampling(particles,weights,noise) %! @end deftypefn %@eod: -% Copyright (C) 2011-2017 Dynare Team +% Copyright © 2011-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 0c629dad0..ab841009c 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -2,7 +2,7 @@ function [LIK,lik] = sequential_importance_particle_filter(ReducedForm,Y,start,P % Evaluates the likelihood of a nonlinear model with a particle filter (optionally with resampling). -% Copyright (C) 2011-2022 Dynare Team +% Copyright © 2011-2022 Dynare Team % % This file is part of Dynare (particles module). % diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index aa26efbf7..7f65649bc 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -20,7 +20,7 @@ function [info, Model, DynareOptions, DynareResults, ReducedForm] = ... % - DynareResults [struct] Dynare results (oo_). % - ReducedForm [struct] Reduced form model. -% Copyright (C) 2013-2022 Dynare Team +% Copyright © 2013-2022 Dynare Team % % This file is part of Dynare. % diff --git a/src/spherical_radial_sigma_points.m b/src/spherical_radial_sigma_points.m index 19e2634ab..756cac28f 100644 --- a/src/spherical_radial_sigma_points.m +++ b/src/spherical_radial_sigma_points.m @@ -15,7 +15,7 @@ function [nodes,weights] = spherical_radial_sigma_points(n) % % NOTES % -% Copyright (C) 2009-2017 Dynare Team +% Copyright © 2009-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/traditional_resampling.m b/src/traditional_resampling.m index 3dd27aba7..ab9089c8c 100644 --- a/src/traditional_resampling.m +++ b/src/traditional_resampling.m @@ -33,7 +33,7 @@ function return_resample = traditional_resampling(particles,weights,noise) %! @end deftypefn %@eod: -% Copyright (C) 2011-2017 Dynare Team +% Copyright © 2011-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/univariate_smooth_resampling.m b/src/univariate_smooth_resampling.m index aa8651538..6661d8f0d 100644 --- a/src/univariate_smooth_resampling.m +++ b/src/univariate_smooth_resampling.m @@ -34,7 +34,7 @@ function new_particles = univariate_smooth_resampling(weights,particles,number_o %! @end deftypefn %@eod: -% Copyright (C) 2012-2017 Dynare Team +% Copyright © 2012-2017 Dynare Team % % This file is part of Dynare. % diff --git a/src/unscented_sigma_points.m b/src/unscented_sigma_points.m index 53709af40..9ff7a27e8 100644 --- a/src/unscented_sigma_points.m +++ b/src/unscented_sigma_points.m @@ -14,7 +14,7 @@ function [nodes,W_m,W_c] = unscented_sigma_points(n,ParticleOptions) % % NOTES % -% Copyright (C) 2009-2017 Dynare Team +% Copyright © 2009-2017 Dynare Team % % This file is part of Dynare. % From 363056a3d1af9e57b902c4606f1cd97a46711915 Mon Sep 17 00:00:00 2001 From: Normann Rion Date: Mon, 19 Sep 2022 06:53:13 +0100 Subject: [PATCH 096/101] Fix online_particle_filter.m: wrong condition for pruning in terms of order selection --- src/online_auxiliary_filter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index bfb4383c5..eefd163bb 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -159,7 +159,7 @@ for t=1:sample_size indx = resample(0, tau_tilde', DynareOptions.particle); StateVectors = StateVectors(:,indx); xparam = fore_xparam(:,indx); - if DynareOptions.order>=3 && pruning + if pruning StateVectors_ = StateVectors_(:,indx); end w_stage1 = weights(indx)./tau_tilde(indx); From 25401abeb8459d8ed0be9f07b7fb1549ea3bf3c8 Mon Sep 17 00:00:00 2001 From: Normann Rion Date: Mon, 19 Sep 2022 15:16:29 +0200 Subject: [PATCH 097/101] Fix auxiliary_particle_filter.m: strange iteration range `for i=1:size(nodes)` All hunks depending on this loop amended --- src/auxiliary_particle_filter.m | 55 +++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 2caa3e919..2d3b00112 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -24,6 +24,8 @@ function [LIK,lik] = auxiliary_particle_filter(ReducedForm,Y,start,ParticleOptio if isempty(start) start = 1; end +% Get perturbation order +order = DynareOptions.order; % Set flag for prunning pruning = ParticleOptions.pruning; @@ -36,6 +38,7 @@ state_variables_steady_state = ReducedForm.state_variables_steady_state; mf0 = ReducedForm.mf0; mf1 = ReducedForm.mf1; sample_size = size(Y,2); +number_of_state_variables = length(mf0); number_of_observed_variables = length(mf1); number_of_structural_innovations = length(ReducedForm.Q); number_of_particles = ParticleOptions.number_of_particles; @@ -76,33 +79,32 @@ weights = ones(1,number_of_particles)/number_of_particles ; StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); %StateVectors = bsxfun(@plus,zeros(state_variance_rank,number_of_particles),StateVectorMean); if pruning - StateVectors_ = StateVectors; + if order == 2 + StateVectors_ = StateVectors; + state_variables_steady_state_ = state_variables_steady_state; + mf0_ = mf0; + else + error('Pruning is not available for orders > 2'); + end end -nodes = zeros(1,number_of_structural_innovations) ; -nodes_weights = ones(number_of_structural_innovations,1) ; - for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); if pruning - yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); - tmp = 0 ; - tmp_ = 0 ; - for i=1:size(nodes) - [tmp1, tmp1_] = local_state_space_iteration_2(yhat,nodes(i,:)'*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); - tmp = tmp + nodes_weights(i)*tmp1 ; - tmp_ = tmp_ + nodes_weights(i)*tmp1_ ; + yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state_); + if order == 2 + [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + else + error('Pruning is not available for orders > 2'); end else if ReducedForm.use_k_order_solver - tmp = 0; - for i=1:size(nodes) - tmp = tmp + nodes_weights(i)*local_state_space_iteration_k(yhat, nodes(i,:)'*ones(1,number_of_particles), dr, Model, DynareOptions, udr); - end + tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations,number_of_particles), dr, Model, DynareOptions, udr); else - tmp = 0; - for i=1:size(nodes) - tmp = tmp + nodes_weights(i)*local_state_space_iteration_2(yhat,nodes(i,:)'*ones(1,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + else + error('Order > 2: use_k_order_solver should be set to true'); end end end @@ -118,13 +120,21 @@ for t=1:sample_size weights_stage_1 = weights(indx)./tau_tilde(indx) ; epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning - [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); - StateVectors_ = tmp_(mf0,:); + if order == 2 + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + else + error('Pruning is not available for orders > 2'); + end + StateVectors_ = tmp_(mf0_,:); else if ReducedForm.use_k_order_solver tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else - tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + else + error('Order > 2: use_k_order_solver should be set to true'); + end end end StateVectors = tmp(mf0,:); @@ -135,9 +145,8 @@ for t=1:sample_size if (ParticleOptions.resampling.status.generic && neff(weights) Date: Mon, 19 Sep 2022 15:43:10 +0200 Subject: [PATCH 098/101] Amends particle filters to use the local_state_space_iteration_3 mex --- src/auxiliary_initialization.m | 20 ++++- src/auxiliary_particle_filter.m | 33 ++++++-- src/conditional_filter_proposal.m | 19 ++++- src/gaussian_filter_bank.m | 19 ++++- src/gaussian_mixture_filter_bank.m | 19 ++++- src/measurement_equations.m | 17 +++- src/nonlinear_kalman_filter.m | 17 +++- src/online_auxiliary_filter.m | 90 ++++++++++++++++++--- src/sequential_importance_particle_filter.m | 47 +++++++++-- 9 files changed, 254 insertions(+), 27 deletions(-) diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index 8355e75ab..3e279117b 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -2,7 +2,7 @@ function initial_distribution = auxiliary_initialization(ReducedForm,Y,start,Par % Evaluates the likelihood of a nonlinear model with a particle filter allowing eventually resampling. -% Copyright © 2011-2017 Dynare Team +% Copyright © 2011-2022 Dynare Team % % This file is part of Dynare (particles module). % @@ -45,6 +45,8 @@ if isempty(init_flag) init_flag = 1; end +order = DynareOptions.order; + % Set local state space model (first order approximation). ghx = ReducedForm.ghx; ghu = ReducedForm.ghu; @@ -52,6 +54,14 @@ ghu = ReducedForm.ghu; ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; +if (order == 3) + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; +end % Get covariance matrices Q = ReducedForm.Q; @@ -87,7 +97,13 @@ yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); % yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); % [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); %else -tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +if (order == 2) + tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); +elseif (order == 3) + tmp = local_state_space_iteration_3(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,ThreadsOptions.local_state_space_iteration_3); +else + error('Orders > 3 not allowed'); +end %end PredictedObservedMean = weights*(tmp(mf1,:)'); PredictionError = bsxfun(@minus,Y(:,t),tmp(mf1,:)); diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index 2d3b00112..b84eca837 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -54,6 +54,15 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if (order == 3) + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end end % Get covariance matrices @@ -83,8 +92,14 @@ if pruning StateVectors_ = StateVectors; state_variables_steady_state_ = state_variables_steady_state; mf0_ = mf0; + elseif order == 3 + StateVectors_ = repmat(StateVectors,2,1); + state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); + mf0_ = repmat(mf0,1,2); + mask = number_of_state_variables+1:2*number_of_state_variables; + mf0_(mask) = mf0_(mask)+size(ghx,1); else - error('Pruning is not available for orders > 2'); + error('Pruning is not available for orders > 3'); end end @@ -94,8 +109,10 @@ for t=1:sample_size yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state_); if order == 2 [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + [tmp, tmp_] = local_state_space_iteration_3(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_3); else - error('Pruning is not available for orders > 2'); + error('Pruning is not available for orders > 3'); end else if ReducedForm.use_k_order_solver @@ -103,8 +120,10 @@ for t=1:sample_size else if order == 2 tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,ThreadsOptions.local_state_space_iteration_3); else - error('Order > 2: use_k_order_solver should be set to true'); + error('Order > 3: use_k_order_solver should be set to true'); end end end @@ -122,8 +141,10 @@ for t=1:sample_size if pruning if order == 2 [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + [tmp, tmp_] = local_state_space_iteration_3(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_3); else - error('Pruning is not available for orders > 2'); + error('Pruning is not available for orders > 3'); end StateVectors_ = tmp_(mf0_,:); else @@ -132,8 +153,10 @@ for t=1:sample_size else if order == 2 tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); else - error('Order > 2: use_k_order_solver should be set to true'); + error('Order > 3: use_k_order_solver should be set to true'); end end end diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 47e53b5ac..45d7886ae 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -41,6 +41,8 @@ function [ProposalStateVector, Weights, flag] = conditional_filter_proposal(Redu flag = false; +order = DynareOptions.order; + if ReducedForm.use_k_order_solver dr = ReducedForm.dr; udr = ReducedForm.udr; @@ -52,6 +54,15 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if order == 3 + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end end constant = ReducedForm.constant; @@ -82,7 +93,13 @@ yhat = repmat(StateVectors-state_variables_steady_state, 1, size(epsilon, 2)); if ReducedForm.use_k_order_solver tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else - tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + else + error('Order > 3: use_k_order_solver should be set to true'); + end end PredictedStateMean = tmp(mf0,:)*weights; diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index 6108ab21d..d7a649fa4 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -39,6 +39,8 @@ function [PredictedStateMean, PredictedStateVarianceSquareRoot, StateVectorMean, % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +order = DynareOptions.order; + if ReducedForm.use_k_order_solver dr = ReducedForm.dr; udr = ReducedForm.udr; @@ -50,6 +52,15 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if order == 3 + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end end constant = ReducedForm.constant; @@ -84,7 +95,13 @@ yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); if ReducedForm.use_k_order_solver tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else - tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + else + error('Order > 3: use_k_order_solver should be set to true'); + end end PredictedStateMean = tmp(mf0,:)*weights; diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index 88d3628b8..69e3eb613 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -41,6 +41,8 @@ function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPP % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +order = DynareOptions.order; + if ReducedForm.use_k_order_solver dr = ReducedForm.dr; udr = ReducedForm.udr; @@ -52,6 +54,15 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if order == 3 + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end end constant = ReducedForm.constant; @@ -80,7 +91,13 @@ yhat = bsxfun(@minus, StateVectors, state_variables_steady_state); if ReducedForm.use_k_order_solver tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else - tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + else + error('Order > 3: use_k_order_solver should be set to true'); + end end PredictedStateMean = tmp(mf0,:)*weights3; PredictedObservedMean = tmp(mf1,:)*weights3; diff --git a/src/measurement_equations.m b/src/measurement_equations.m index 4e11dd064..477cc1782 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -17,6 +17,7 @@ function measure = measurement_equations(StateVectors,ReducedForm,ThreadsOptions % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +order = DynareOptions.order; mf1 = ReducedForm.mf1; if ReducedForm.use_k_order_solver dr = ReducedForm.dr; @@ -27,6 +28,14 @@ else ghxx = ReducedForm.ghxx(mf1,:); ghuu = ReducedForm.ghuu(mf1,:); ghxu = ReducedForm.ghxu(mf1,:); + if order == 3 + ghxxx = ReducedForm.ghxxx(mf1,:); + ghuuu = ReducedForm.ghuuu(mf1,:); + ghxxu = ReducedForm.ghxxu(mf1,:); + ghxuu = ReducedForm.ghxuu(mf1,:); + ghxss = ReducedForm.ghxss(mf1,:); + ghuss = ReducedForm.ghuss(mf1,:); + end end constant = ReducedForm.constant(mf1,:); state_variables_steady_state = ReducedForm.state_variables_steady_state; @@ -36,5 +45,11 @@ if ReducedForm.use_k_order_solver tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, size(yhat,2)), dr, Model, DynareOptions, udr); measure = tmp(mf1,:); else - measure = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + if order == 2 + measure = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + measure = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + else + error('Order > 3: use_k_order_solver should be set to true'); + end end diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index 9decb3225..d46c0cd7e 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -54,6 +54,8 @@ if isempty(start) start = 1; end +order = DynareOptions.order; + if ReducedForm.use_k_order_solver dr = ReducedForm.dr; udr = ReducedForm.udr; @@ -65,6 +67,15 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if (order == 3) + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end end constant = ReducedForm.constant; @@ -119,7 +130,11 @@ for t=1:sample_size if ReducedForm.use_k_order_solver tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else - tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + end end PredictedStateMean = tmp(mf0,:)*weights ; PredictedObservedMean = tmp(mf1,:)*weights; diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index eefd163bb..8d0745514 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -49,6 +49,7 @@ bounds = prior_bounds(BayesInfo, DynareOptions.prior_trunc); % Reset bounds as l % initialization of state particles [~, Model, DynareOptions, DynareResults, ReducedForm] = solve_model_for_online_filter(true, xparam1, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults); +order = DynareOptions.order; mf0 = ReducedForm.mf0; mf1 = ReducedForm.mf1; number_of_particles = DynareOptions.particle.number_of_particles; @@ -64,8 +65,14 @@ StateVectorMean = ReducedForm.StateVectorMean; StateVectorVarianceSquareRoot = chol(ReducedForm.StateVectorVariance)'; state_variance_rank = size(StateVectorVarianceSquareRoot,2); StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); -if DynareOptions.order<3 && pruning - StateVectors_ = StateVectors; +if pruning + if order == 2 + StateVectors_ = StateVectors; + elseif order == 3 + StateVectors_ = repmat(StateVectors,2,1); + else + error('Pruning is not available for orders > 3'); + end end % parameters for the Liu & West filter @@ -135,6 +142,25 @@ for t=1:sample_size ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if (order == 3) + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end + if pruning + if order == 2 + state_variables_steady_state_ = state_variables_steady_state; + elseif order == 3 + state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); + else + error('Pruning is not available for orders > 3'); + end + end + end % particle likelihood contribution yhat = bsxfun(@minus, StateVectors(:,i), state_variables_steady_state); @@ -142,10 +168,22 @@ for t=1:sample_size tmp = local_state_space_iteration_k(yhat, zeros(number_of_structural_innovations, 1), dr, Model, DynareOptions, udr); else if pruning - yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state); - [tmp, ~] = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); + yhat_ = bsxfun(@minus,StateVectors_(:,i),state_variables_steady_state_); + if order == 2 + [tmp, ~] = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); + elseif order == 3 + [tmp, ~] = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_3); + else + error('Pruning is not available for orders > 3'); + end else - tmp = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, DynareOptions.threads.local_state_space_iteration_3); + else + error('Order > 3: use_k_order_solver should be set to true'); + end end end PredictionError = bsxfun(@minus,Y(t,:)', tmp(mf1,:)); @@ -192,6 +230,28 @@ for t=1:sample_size ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if (order == 3) + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end + if pruning + if order == 2 + state_variables_steady_state_ = state_variables_steady_state; + mf0_ = mf0; + elseif order == 3 + state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); + mf0_ = repmat(mf0,1,2); + mask = number_of_state_variables+1:2*number_of_state_variables; + mf0_(mask) = mf0_(mask)+size(ghx,1); + else + error('Pruning is not available for orders > 3'); + end + end end % Get covariance matrices and structural shocks epsilon = chol(ReducedForm.Q)'*randn(number_of_structural_innovations, 1); @@ -201,11 +261,23 @@ for t=1:sample_size tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else if pruning - yhat_ = bsxfun(@minus,StateVectors_(:,i), state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); - StateVectors_(:,i) = tmp_(mf0,:); + yhat_ = bsxfun(@minus,StateVectors_(:,i), state_variables_steady_state_); + if order == 2 + [tmp, tmp_] = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); + elseif order == 3 + [tmp, tmp_] = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_3); + else + error('Pruning is not available for orders > 3'); + end + StateVectors_(:,i) = tmp_(mf0_,:); else - tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, DynareOptions.threads.local_state_space_iteration_3); + else + error('Order > 3: use_k_order_solver should be set to true'); + end end end StateVectors(:,i) = tmp(mf0,:); diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index ab841009c..4c9c8313e 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -37,6 +37,8 @@ steadystate = ReducedForm.steadystate; constant = ReducedForm.constant; state_variables_steady_state = ReducedForm.state_variables_steady_state; +order = DynareOptions.order; + % Set persistent variables (if needed). if isempty(init_flag) mf0 = ReducedForm.mf0; @@ -61,6 +63,15 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + if order == 3 + % Set local state space model (third order approximation). + ghxxx = ReducedForm.ghxxx; + ghuuu = ReducedForm.ghuuu; + ghxxu = ReducedForm.ghxxu; + ghxuu = ReducedForm.ghxuu; + ghxss = ReducedForm.ghxss; + ghuss = ReducedForm.ghuss; + end end % Get covariance matrices. @@ -95,7 +106,19 @@ set_dynare_seed('default'); weights = ones(1,number_of_particles)/number_of_particles ; StateVectors = bsxfun(@plus,StateVectorVarianceSquareRoot*randn(state_variance_rank,number_of_particles),StateVectorMean); if pruning - StateVectors_ = StateVectors; + if order == 2 + StateVectors_ = StateVectors; + state_variables_steady_state_ = state_variables_steady_state; + mf0_ = mf0; + elseif order == 3 + StateVectors_ = repmat(StateVectors,2,1); + state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); + mf0_ = repmat(mf0,1,2); + mask = number_of_state_variables+1:2*number_of_state_variables; + mf0_(mask) = mf0_(mask)+size(ghx,1); + else + error('Pruning is not available for orders > 3'); + end end % Loop over observations @@ -103,13 +126,25 @@ for t=1:sample_size yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); epsilon = Q_lower_triangular_cholesky*randn(number_of_structural_innovations,number_of_particles); if pruning - yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state); - [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + yhat_ = bsxfun(@minus,StateVectors_,state_variables_steady_state_); + if order == 2 + [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + [tmp, tmp_] = local_state_space_iteration_3(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_3); + else + error('Pruning is not available for orders > 3'); + end else if ReducedForm.use_k_order_solver tmp = local_state_space_iteration_k(yhat, epsilon, dr, Model, DynareOptions, udr); else - tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + if order == 2 + tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); + elseif order == 3 + tmp = local_state_space_iteration_3(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,ThreadsOptions.local_state_space_iteration_3); + else + error('Order > 3: use_k_order_solver should be set to true'); + end end end %PredictedObservedMean = tmp(mf1,:)*transpose(weights); @@ -129,7 +164,7 @@ for t=1:sample_size weights = wtilde/sum(wtilde); if (ParticleOptions.resampling.status.generic && neff(weights) Date: Wed, 26 Apr 2023 10:06:30 +0200 Subject: [PATCH 099/101] Use new prior draw interface. --- src/online_auxiliary_filter.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 8d0745514..16bf903e9 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -81,11 +81,11 @@ b_square = 1-small_a*small_a; % Initialization of parameter particles xparam = zeros(number_of_parameters,number_of_particles); -prior_draw(BayesInfo,DynareOptions.prior_trunc); +Prior = dprior(BayesInfo, DynareOptions.prior_trunc); for i=1:number_of_particles info = 12042009; while info - candidate = prior_draw()'; + candidate = Prior.draw(); [info, Model, DynareOptions, DynareResults] = solve_model_for_online_filter(false, xparam1, DynareDataset, DynareOptions, Model, EstimatedParameters, BayesInfo, bounds, DynareResults); if ~info xparam(:,i) = candidate(:); From 558990e447ad830d738c6542cc3436ebf6745523 Mon Sep 17 00:00:00 2001 From: Normann Rion Date: Sat, 1 Jul 2023 16:43:48 +0200 Subject: [PATCH 100/101] Amends the various filters to fit the fixed version of local_state_space_iteration_3 See MR !2144 for more details --- src/auxiliary_initialization.m | 4 +++- src/auxiliary_particle_filter.m | 21 +++++++++-------- src/conditional_filter_proposal.m | 4 +++- src/gaussian_filter_bank.m | 4 +++- src/gaussian_mixture_filter_bank.m | 4 +++- src/measurement_equations.m | 4 +++- src/nonlinear_kalman_filter.m | 4 +++- src/online_auxiliary_filter.m | 25 ++++++++++++--------- src/sequential_importance_particle_filter.m | 19 +++++++++------- src/solve_model_for_online_filter.m | 1 + 10 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/auxiliary_initialization.m b/src/auxiliary_initialization.m index 3e279117b..e05741052 100644 --- a/src/auxiliary_initialization.m +++ b/src/auxiliary_initialization.m @@ -33,6 +33,7 @@ end % Get steady state and mean. %steadystate = ReducedForm.steadystate; constant = ReducedForm.constant; +ss = ReducedForm.ys; state_variables_steady_state = ReducedForm.state_variables_steady_state; % Set persistent variables. @@ -54,6 +55,7 @@ ghu = ReducedForm.ghu; ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; +ghs2 = ReducedForm.ghs2; if (order == 3) ghxxx = ReducedForm.ghxxx; ghuuu = ReducedForm.ghuuu; @@ -100,7 +102,7 @@ yhat = bsxfun(@minus,StateVectors,state_variables_steady_state); if (order == 2) tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); elseif (order == 3) - tmp = local_state_space_iteration_3(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations,number_of_particles), ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ss, options_.threads.local_state_space_iteration_3, false); else error('Orders > 3 not allowed'); end diff --git a/src/auxiliary_particle_filter.m b/src/auxiliary_particle_filter.m index b84eca837..21caa73bd 100644 --- a/src/auxiliary_particle_filter.m +++ b/src/auxiliary_particle_filter.m @@ -54,6 +54,7 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if (order == 3) % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -93,11 +94,13 @@ if pruning state_variables_steady_state_ = state_variables_steady_state; mf0_ = mf0; elseif order == 3 - StateVectors_ = repmat(StateVectors,2,1); - state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); - mf0_ = repmat(mf0,1,2); - mask = number_of_state_variables+1:2*number_of_state_variables; - mf0_(mask) = mf0_(mask)+size(ghx,1); + StateVectors_ = repmat(StateVectors,3,1); + state_variables_steady_state_ = repmat(state_variables_steady_state,3,1); + mf0_ = repmat(mf0,1,3); + mask2 = number_of_state_variables+1:2*number_of_state_variables; + mask3 = 2*number_of_state_variables+1:3*number_of_state_variables; + mf0_(mask2) = mf0_(mask2)+size(ghx,1); + mf0_(mask3) = mf0_(mask3)+2*size(ghx,1); else error('Pruning is not available for orders > 3'); end @@ -110,7 +113,7 @@ for t=1:sample_size if order == 2 [tmp, tmp_] = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - [tmp, tmp_] = local_state_space_iteration_3(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_3); + [tmp, tmp_] = local_state_space_iteration_3(yhat_, zeros(number_of_structural_innovations,number_of_particles), ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, pruning); else error('Pruning is not available for orders > 3'); end @@ -121,7 +124,7 @@ for t=1:sample_size if order == 2 tmp = local_state_space_iteration_2(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat,zeros(number_of_structural_innovations,number_of_particles),ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations,number_of_particles), ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, pruning); else error('Order > 3: use_k_order_solver should be set to true'); end @@ -142,7 +145,7 @@ for t=1:sample_size if order == 2 [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - [tmp, tmp_] = local_state_space_iteration_3(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_3); + [tmp, tmp_] = local_state_space_iteration_3(yhat_, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, pruning); else error('Pruning is not available for orders > 3'); end @@ -154,7 +157,7 @@ for t=1:sample_size if order == 2 tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, pruning); else error('Order > 3: use_k_order_solver should be set to true'); end diff --git a/src/conditional_filter_proposal.m b/src/conditional_filter_proposal.m index 45d7886ae..4d60a4435 100644 --- a/src/conditional_filter_proposal.m +++ b/src/conditional_filter_proposal.m @@ -54,6 +54,7 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if order == 3 % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -66,6 +67,7 @@ else end constant = ReducedForm.constant; +steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; mf0 = ReducedForm.mf0; @@ -96,7 +98,7 @@ else if order == 2 tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, false); else error('Order > 3: use_k_order_solver should be set to true'); end diff --git a/src/gaussian_filter_bank.m b/src/gaussian_filter_bank.m index d7a649fa4..17ae110cc 100644 --- a/src/gaussian_filter_bank.m +++ b/src/gaussian_filter_bank.m @@ -52,6 +52,7 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if order == 3 % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -64,6 +65,7 @@ else end constant = ReducedForm.constant; +steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; mf0 = ReducedForm.mf0; @@ -98,7 +100,7 @@ else if order == 2 tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, false); else error('Order > 3: use_k_order_solver should be set to true'); end diff --git a/src/gaussian_mixture_filter_bank.m b/src/gaussian_mixture_filter_bank.m index 69e3eb613..acbe77f2b 100644 --- a/src/gaussian_mixture_filter_bank.m +++ b/src/gaussian_mixture_filter_bank.m @@ -54,6 +54,7 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if order == 3 % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -66,6 +67,7 @@ else end constant = ReducedForm.constant; +steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; mf0 = ReducedForm.mf0; @@ -94,7 +96,7 @@ else if order == 2 tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, false); else error('Order > 3: use_k_order_solver should be set to true'); end diff --git a/src/measurement_equations.m b/src/measurement_equations.m index 477cc1782..8ed06349d 100644 --- a/src/measurement_equations.m +++ b/src/measurement_equations.m @@ -28,6 +28,7 @@ else ghxx = ReducedForm.ghxx(mf1,:); ghuu = ReducedForm.ghuu(mf1,:); ghxu = ReducedForm.ghxu(mf1,:); + ghs2 = ReducedForm.ghs2(mf1,:); if order == 3 ghxxx = ReducedForm.ghxxx(mf1,:); ghuuu = ReducedForm.ghuuu(mf1,:); @@ -37,6 +38,7 @@ else ghuss = ReducedForm.ghuss(mf1,:); end end +steadystate = ReducedForm.steadystate(mf1,:); constant = ReducedForm.constant(mf1,:); state_variables_steady_state = ReducedForm.state_variables_steady_state; number_of_structural_innovations = length(ReducedForm.Q); @@ -48,7 +50,7 @@ else if order == 2 measure = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - measure = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + measure = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, size(yhat,2)), ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, false); else error('Order > 3: use_k_order_solver should be set to true'); end diff --git a/src/nonlinear_kalman_filter.m b/src/nonlinear_kalman_filter.m index d46c0cd7e..ccae0731d 100644 --- a/src/nonlinear_kalman_filter.m +++ b/src/nonlinear_kalman_filter.m @@ -67,6 +67,7 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if (order == 3) % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -79,6 +80,7 @@ else end constant = ReducedForm.constant; +steadystate = ReducedForm.steadystate; state_variables_steady_state = ReducedForm.state_variables_steady_state; mf0 = ReducedForm.mf0; @@ -133,7 +135,7 @@ for t=1:sample_size if order == 2 tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, false); end end PredictedStateMean = tmp(mf0,:)*weights ; diff --git a/src/online_auxiliary_filter.m b/src/online_auxiliary_filter.m index 16bf903e9..bbfb21e3e 100644 --- a/src/online_auxiliary_filter.m +++ b/src/online_auxiliary_filter.m @@ -69,7 +69,7 @@ if pruning if order == 2 StateVectors_ = StateVectors; elseif order == 3 - StateVectors_ = repmat(StateVectors,2,1); + StateVectors_ = repmat(StateVectors,3,1); else error('Pruning is not available for orders > 3'); end @@ -134,6 +134,7 @@ for t=1:sample_size dr = ReducedForm.dr; udr = ReducedForm.udr; else + steadystate = ReducedForm.steadystate; constant = ReducedForm.constant; % Set local state space model (first-order approximation). ghx = ReducedForm.ghx; @@ -142,6 +143,7 @@ for t=1:sample_size ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if (order == 3) % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -155,7 +157,7 @@ for t=1:sample_size if order == 2 state_variables_steady_state_ = state_variables_steady_state; elseif order == 3 - state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); + state_variables_steady_state_ = repmat(state_variables_steady_state,3,1); else error('Pruning is not available for orders > 3'); end @@ -172,7 +174,7 @@ for t=1:sample_size if order == 2 [tmp, ~] = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); elseif order == 3 - [tmp, ~] = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_3); + [tmp, tmp_] = local_state_space_iteration_3(yhat_, zeros(number_of_structural_innovations, 1), ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, DynareOptions.threads.local_state_space_iteration_3, pruning); else error('Pruning is not available for orders > 3'); end @@ -180,7 +182,7 @@ for t=1:sample_size if order == 2 tmp = local_state_space_iteration_2(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, DynareOptions.threads.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, zeros(number_of_structural_innovations, 1), ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, DynareOptions.threads.local_state_space_iteration_3, pruning); else error('Order > 3: use_k_order_solver should be set to true'); end @@ -230,6 +232,7 @@ for t=1:sample_size ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if (order == 3) % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -244,10 +247,12 @@ for t=1:sample_size state_variables_steady_state_ = state_variables_steady_state; mf0_ = mf0; elseif order == 3 - state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); - mf0_ = repmat(mf0,1,2); - mask = number_of_state_variables+1:2*number_of_state_variables; - mf0_(mask) = mf0_(mask)+size(ghx,1); + state_variables_steady_state_ = repmat(state_variables_steady_state,3,1); + mf0_ = repmat(mf0,1,3); + mask2 = number_of_state_variables+1:2*number_of_state_variables; + mask3 = 2*number_of_state_variables+1:number_of_state_variables; + mf0_(mask2) = mf0_(mask2)+size(ghx,1); + mf0_(mask3) = mf0_(mask3)+2*size(ghx,1); else error('Pruning is not available for orders > 3'); end @@ -265,7 +270,7 @@ for t=1:sample_size if order == 2 [tmp, tmp_] = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_2); elseif order == 3 - [tmp, tmp_] = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, yhat_, steadystate, DynareOptions.threads.local_state_space_iteration_3); + [tmp, tmp_] = local_state_space_iteration_3(yhat_, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, DynareOptions.threads.local_state_space_iteration_3, pruning); else error('Pruning is not available for orders > 3'); end @@ -274,7 +279,7 @@ for t=1:sample_size if order == 2 tmp = local_state_space_iteration_2(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, DynareOptions.threads.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, constant, ghxx, ghuu, ghxu, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, DynareOptions.threads.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, DynareOptions.threads.local_state_space_iteration_3, pruning); else error('Order > 3: use_k_order_solver should be set to true'); end diff --git a/src/sequential_importance_particle_filter.m b/src/sequential_importance_particle_filter.m index 4c9c8313e..c69ded02f 100644 --- a/src/sequential_importance_particle_filter.m +++ b/src/sequential_importance_particle_filter.m @@ -63,6 +63,7 @@ else ghxx = ReducedForm.ghxx; ghuu = ReducedForm.ghuu; ghxu = ReducedForm.ghxu; + ghs2 = ReducedForm.ghs2; if order == 3 % Set local state space model (third order approximation). ghxxx = ReducedForm.ghxxx; @@ -111,11 +112,13 @@ if pruning state_variables_steady_state_ = state_variables_steady_state; mf0_ = mf0; elseif order == 3 - StateVectors_ = repmat(StateVectors,2,1); - state_variables_steady_state_ = repmat(state_variables_steady_state,2,1); - mf0_ = repmat(mf0,1,2); - mask = number_of_state_variables+1:2*number_of_state_variables; - mf0_(mask) = mf0_(mask)+size(ghx,1); + StateVectors_ = repmat(StateVectors,3,1); + state_variables_steady_state_ = repmat(state_variables_steady_state,3,1); + mf0_ = repmat(mf0,1,3); + mask2 = number_of_state_variables+1:2*number_of_state_variables; + mask3 = 2*number_of_state_variables+1:3*number_of_state_variables; + mf0_(mask2) = mf0_(mask2)+size(ghx,1); + mf0_(mask3) = mf0_(mask3)+2*size(ghx,1); else error('Pruning is not available for orders > 3'); end @@ -130,7 +133,7 @@ for t=1:sample_size if order == 2 [tmp, tmp_] = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - [tmp, tmp_] = local_state_space_iteration_3(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,yhat_,steadystate,ThreadsOptions.local_state_space_iteration_3); + [tmp, tmp_] = local_state_space_iteration_3(yhat_, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, pruning); else error('Pruning is not available for orders > 3'); end @@ -141,7 +144,7 @@ for t=1:sample_size if order == 2 tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ThreadsOptions.local_state_space_iteration_2); elseif order == 3 - tmp = local_state_space_iteration_3(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,ghxxx,ghuuu,ghxxu,ghxuu,ghxss,ghuss,ThreadsOptions.local_state_space_iteration_3); + tmp = local_state_space_iteration_3(yhat, epsilon, ghx, ghu, ghxx, ghuu, ghxu, ghs2, ghxxx, ghuuu, ghxxu, ghxuu, ghxss, ghuss, steadystate, ThreadsOptions.local_state_space_iteration_3, pruning); else error('Order > 3: use_k_order_solver should be set to true'); end @@ -166,7 +169,7 @@ for t=1:sample_size if pruning temp = resample([tmp(mf0,:)' tmp_(mf0_,:)'],weights',ParticleOptions); StateVectors = temp(:,1:number_of_state_variables)'; - StateVectors_ = temp(:,number_of_state_variables+1:2*number_of_state_variables)'; + StateVectors_ = temp(:,number_of_state_variables+1:end)'; else StateVectors = resample(tmp(mf0,:)',weights',ParticleOptions)'; end diff --git a/src/solve_model_for_online_filter.m b/src/solve_model_for_online_filter.m index 7f65649bc..92cbf4c74 100644 --- a/src/solve_model_for_online_filter.m +++ b/src/solve_model_for_online_filter.m @@ -161,6 +161,7 @@ if nargout>4 ReducedForm.ghuu = dr.ghuu(restrict_variables_idx,:); ReducedForm.ghxu = dr.ghxu(restrict_variables_idx,:); ReducedForm.constant = ReducedForm.steadystate + .5*dr.ghs2(restrict_variables_idx); + ReducedForm.ghs2 = dr.ghs2(restrict_variables_idx,:); elseif DynareOptions.order>=3 ReducedForm.use_k_order_solver = true; ReducedForm.dr = dr; From bb8724afa952679ce36112734551e97ff122d20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Ry=C3=BBk=29?= Date: Tue, 11 Jul 2023 22:56:47 +0200 Subject: [PATCH 101/101] Moved files. --- .gitignore | 4 - LICENSE.md | 16 - README.md | 6 - doc/Makefile | 177 ---------- doc/README.md | 19 - doc/make.bat | 242 ------------- doc/source/conf.py | 331 ------------------ doc/source/index.rst | 22 -- .../auxiliary_initialization.m | 0 .../auxiliary_particle_filter.m | 0 .../conditional_filter_proposal.m | 0 .../conditional_particle_filter.m | 0 .../fit_gaussian_mixture.m | 0 .../gaussian_densities.m | 0 {src => nonlinear-filters}/gaussian_filter.m | 0 .../gaussian_filter_bank.m | 0 .../gaussian_mixture_densities.m | 0 .../gaussian_mixture_filter.m | 0 .../gaussian_mixture_filter_bank.m | 0 .../importance_sampling.m | 0 .../measurement_equations.m | 0 .../multivariate_smooth_resampling.m | 0 {src => nonlinear-filters}/mykmeans.m | 0 {src => nonlinear-filters}/neff.m | 0 .../nonlinear_kalman_filter.m | 0 .../online_auxiliary_filter.m | 0 {src => nonlinear-filters}/probability.m | 0 {src => nonlinear-filters}/probability2.m | 0 {src => nonlinear-filters}/probability3.m | 0 {src => nonlinear-filters}/resample.m | 0 .../residual_resampling.m | 0 .../sequential_importance_particle_filter.m | 0 .../solve_model_for_online_filter.m | 0 .../spherical_radial_sigma_points.m | 0 .../traditional_resampling.m | 0 .../univariate_smooth_resampling.m | 0 .../unscented_sigma_points.m | 0 37 files changed, 817 deletions(-) delete mode 100644 .gitignore delete mode 100644 LICENSE.md delete mode 100644 README.md delete mode 100644 doc/Makefile delete mode 100644 doc/README.md delete mode 100644 doc/make.bat delete mode 100644 doc/source/conf.py delete mode 100644 doc/source/index.rst rename {src => nonlinear-filters}/auxiliary_initialization.m (100%) rename {src => nonlinear-filters}/auxiliary_particle_filter.m (100%) rename {src => nonlinear-filters}/conditional_filter_proposal.m (100%) rename {src => nonlinear-filters}/conditional_particle_filter.m (100%) rename {src => nonlinear-filters}/fit_gaussian_mixture.m (100%) rename {src => nonlinear-filters}/gaussian_densities.m (100%) rename {src => nonlinear-filters}/gaussian_filter.m (100%) rename {src => nonlinear-filters}/gaussian_filter_bank.m (100%) rename {src => nonlinear-filters}/gaussian_mixture_densities.m (100%) rename {src => nonlinear-filters}/gaussian_mixture_filter.m (100%) rename {src => nonlinear-filters}/gaussian_mixture_filter_bank.m (100%) rename {src => nonlinear-filters}/importance_sampling.m (100%) rename {src => nonlinear-filters}/measurement_equations.m (100%) rename {src => nonlinear-filters}/multivariate_smooth_resampling.m (100%) rename {src => nonlinear-filters}/mykmeans.m (100%) rename {src => nonlinear-filters}/neff.m (100%) rename {src => nonlinear-filters}/nonlinear_kalman_filter.m (100%) rename {src => nonlinear-filters}/online_auxiliary_filter.m (100%) rename {src => nonlinear-filters}/probability.m (100%) rename {src => nonlinear-filters}/probability2.m (100%) rename {src => nonlinear-filters}/probability3.m (100%) rename {src => nonlinear-filters}/resample.m (100%) rename {src => nonlinear-filters}/residual_resampling.m (100%) rename {src => nonlinear-filters}/sequential_importance_particle_filter.m (100%) rename {src => nonlinear-filters}/solve_model_for_online_filter.m (100%) rename {src => nonlinear-filters}/spherical_radial_sigma_points.m (100%) rename {src => nonlinear-filters}/traditional_resampling.m (100%) rename {src => nonlinear-filters}/univariate_smooth_resampling.m (100%) rename {src => nonlinear-filters}/unscented_sigma_points.m (100%) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 568b8034b..000000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*~ -*.mat -*.org -doc/build/* \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index e9fbc2f98..000000000 --- a/LICENSE.md +++ /dev/null @@ -1,16 +0,0 @@ -The Dynare particles module is distributed under the GNU GPL: - -> Copyright © 2014 Dynare Team -> -> This program is free software: you can redistribute it and/or modify -> it under the terms of the GNU General Public License as published by -> the Free Software Foundation, either version 3 of the License, or -> (at your option) any later version. -> -> This program is distributed in the hope that it will be useful, -> but WITHOUT ANY WARRANTY; without even the implied warranty of -> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -> GNU General Public License for more details. -> -> You should have received a copy of the GNU General Public License -> along with this program. If not, see . \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 31463754a..000000000 --- a/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# particless Dynare module - -This package, used in [Dynare](http://www.dynare.org), provides -nonlinear filtering algorithms. The documentation is available in the -[doc](https://git.dynare.org/Dynare/particles/tree/master/doc) -subfolder. diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index b1e0378a1..000000000 --- a/doc/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Particles.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Particles.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Particles" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Particles" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/README.md b/doc/README.md deleted file mode 100644 index 86f42ad85..000000000 --- a/doc/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Documentation for particles Dynare module - -The documentation is written with sphinx, so you need to have -[Python](https://www.python.org/) on your system with -[sphinx](http://sphinx-doc.org/). You also need to install the [Read -the docs](https://readthedocs.org/) theme and the sphinx matlab -domain, this can be done with pip in a terminal: - -``` - ~$ pip install sphinx_rtd_theme - ~$ pip install sphinxcontrib-matlab -``` - -To obtain the documentation as an html file in subfolder -```build/html``` you just have to use the provided Makefile: - -``` - ~$ make html -``` \ No newline at end of file diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index a61048826..000000000 --- a/doc/make.bat +++ /dev/null @@ -1,242 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source -set I18NSPHINXOPTS=%SPHINXOPTS% source -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Particles.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Particles.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index fe9915ab5..000000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,331 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Particles documentation build configuration file, created by -# sphinx-quickstart on Mon Nov 10 18:37:39 2014. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.mathjax', - 'sphinx.ext.ifconfig', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Particles' -copyright = u'2014, Stéphane Adjemian' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.0.0' -# The full version, including alpha/beta/rc tags. -release = '0.0.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Particlesdoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'Particles.tex', u'Particles Documentation', - u'Stéphane Adjemian', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'particles', u'Particles Documentation', - [u'Stéphane Adjemian'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'Particles', u'Particles Documentation', - u'Stéphane Adjemian', 'Particles', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -# -- Options for Epub output ---------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = u'Particles' -epub_author = u'Stéphane Adjemian' -epub_publisher = u'Stéphane Adjemian' -epub_copyright = u'2014, Stéphane Adjemian' - -# The basename for the epub file. It defaults to the project name. -#epub_basename = u'Particles' - -# The HTML theme for the epub output. Since the default themes are not optimized -# for small screen space, using the same theme for HTML and epub output is -# usually not wise. This defaults to 'epub', a theme designed to save visual -# space. -#epub_theme = 'epub' - -# The language of the text. It defaults to the language option -# or en if the language is not set. -#epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -#epub_identifier = '' - -# A unique identification for the text. -#epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -#epub_cover = () - -# A sequence of (type, uri, title) tuples for the guide element of content.opf. -#epub_guide = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_pre_files = [] - -# HTML files shat should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_post_files = [] - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] - -# The depth of the table of contents in toc.ncx. -#epub_tocdepth = 3 - -# Allow duplicate toc entries. -#epub_tocdup = True - -# Choose between 'default' and 'includehidden'. -#epub_tocscope = 'default' - -# Fix unsupported image types using the PIL. -#epub_fix_images = False - -# Scale large images. -#epub_max_image_width = 0 - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#epub_show_urls = 'inline' - -# If false, no index is generated. -#epub_use_index = True diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index b9be40976..000000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. Particles documentation master file, created by - sphinx-quickstart on Mon Nov 10 18:37:39 2014. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to Particles's documentation! -===================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/src/auxiliary_initialization.m b/nonlinear-filters/auxiliary_initialization.m similarity index 100% rename from src/auxiliary_initialization.m rename to nonlinear-filters/auxiliary_initialization.m diff --git a/src/auxiliary_particle_filter.m b/nonlinear-filters/auxiliary_particle_filter.m similarity index 100% rename from src/auxiliary_particle_filter.m rename to nonlinear-filters/auxiliary_particle_filter.m diff --git a/src/conditional_filter_proposal.m b/nonlinear-filters/conditional_filter_proposal.m similarity index 100% rename from src/conditional_filter_proposal.m rename to nonlinear-filters/conditional_filter_proposal.m diff --git a/src/conditional_particle_filter.m b/nonlinear-filters/conditional_particle_filter.m similarity index 100% rename from src/conditional_particle_filter.m rename to nonlinear-filters/conditional_particle_filter.m diff --git a/src/fit_gaussian_mixture.m b/nonlinear-filters/fit_gaussian_mixture.m similarity index 100% rename from src/fit_gaussian_mixture.m rename to nonlinear-filters/fit_gaussian_mixture.m diff --git a/src/gaussian_densities.m b/nonlinear-filters/gaussian_densities.m similarity index 100% rename from src/gaussian_densities.m rename to nonlinear-filters/gaussian_densities.m diff --git a/src/gaussian_filter.m b/nonlinear-filters/gaussian_filter.m similarity index 100% rename from src/gaussian_filter.m rename to nonlinear-filters/gaussian_filter.m diff --git a/src/gaussian_filter_bank.m b/nonlinear-filters/gaussian_filter_bank.m similarity index 100% rename from src/gaussian_filter_bank.m rename to nonlinear-filters/gaussian_filter_bank.m diff --git a/src/gaussian_mixture_densities.m b/nonlinear-filters/gaussian_mixture_densities.m similarity index 100% rename from src/gaussian_mixture_densities.m rename to nonlinear-filters/gaussian_mixture_densities.m diff --git a/src/gaussian_mixture_filter.m b/nonlinear-filters/gaussian_mixture_filter.m similarity index 100% rename from src/gaussian_mixture_filter.m rename to nonlinear-filters/gaussian_mixture_filter.m diff --git a/src/gaussian_mixture_filter_bank.m b/nonlinear-filters/gaussian_mixture_filter_bank.m similarity index 100% rename from src/gaussian_mixture_filter_bank.m rename to nonlinear-filters/gaussian_mixture_filter_bank.m diff --git a/src/importance_sampling.m b/nonlinear-filters/importance_sampling.m similarity index 100% rename from src/importance_sampling.m rename to nonlinear-filters/importance_sampling.m diff --git a/src/measurement_equations.m b/nonlinear-filters/measurement_equations.m similarity index 100% rename from src/measurement_equations.m rename to nonlinear-filters/measurement_equations.m diff --git a/src/multivariate_smooth_resampling.m b/nonlinear-filters/multivariate_smooth_resampling.m similarity index 100% rename from src/multivariate_smooth_resampling.m rename to nonlinear-filters/multivariate_smooth_resampling.m diff --git a/src/mykmeans.m b/nonlinear-filters/mykmeans.m similarity index 100% rename from src/mykmeans.m rename to nonlinear-filters/mykmeans.m diff --git a/src/neff.m b/nonlinear-filters/neff.m similarity index 100% rename from src/neff.m rename to nonlinear-filters/neff.m diff --git a/src/nonlinear_kalman_filter.m b/nonlinear-filters/nonlinear_kalman_filter.m similarity index 100% rename from src/nonlinear_kalman_filter.m rename to nonlinear-filters/nonlinear_kalman_filter.m diff --git a/src/online_auxiliary_filter.m b/nonlinear-filters/online_auxiliary_filter.m similarity index 100% rename from src/online_auxiliary_filter.m rename to nonlinear-filters/online_auxiliary_filter.m diff --git a/src/probability.m b/nonlinear-filters/probability.m similarity index 100% rename from src/probability.m rename to nonlinear-filters/probability.m diff --git a/src/probability2.m b/nonlinear-filters/probability2.m similarity index 100% rename from src/probability2.m rename to nonlinear-filters/probability2.m diff --git a/src/probability3.m b/nonlinear-filters/probability3.m similarity index 100% rename from src/probability3.m rename to nonlinear-filters/probability3.m diff --git a/src/resample.m b/nonlinear-filters/resample.m similarity index 100% rename from src/resample.m rename to nonlinear-filters/resample.m diff --git a/src/residual_resampling.m b/nonlinear-filters/residual_resampling.m similarity index 100% rename from src/residual_resampling.m rename to nonlinear-filters/residual_resampling.m diff --git a/src/sequential_importance_particle_filter.m b/nonlinear-filters/sequential_importance_particle_filter.m similarity index 100% rename from src/sequential_importance_particle_filter.m rename to nonlinear-filters/sequential_importance_particle_filter.m diff --git a/src/solve_model_for_online_filter.m b/nonlinear-filters/solve_model_for_online_filter.m similarity index 100% rename from src/solve_model_for_online_filter.m rename to nonlinear-filters/solve_model_for_online_filter.m diff --git a/src/spherical_radial_sigma_points.m b/nonlinear-filters/spherical_radial_sigma_points.m similarity index 100% rename from src/spherical_radial_sigma_points.m rename to nonlinear-filters/spherical_radial_sigma_points.m diff --git a/src/traditional_resampling.m b/nonlinear-filters/traditional_resampling.m similarity index 100% rename from src/traditional_resampling.m rename to nonlinear-filters/traditional_resampling.m diff --git a/src/univariate_smooth_resampling.m b/nonlinear-filters/univariate_smooth_resampling.m similarity index 100% rename from src/univariate_smooth_resampling.m rename to nonlinear-filters/univariate_smooth_resampling.m diff --git a/src/unscented_sigma_points.m b/nonlinear-filters/unscented_sigma_points.m similarity index 100% rename from src/unscented_sigma_points.m rename to nonlinear-filters/unscented_sigma_points.m