Add Sequential Monte Carlo sampler.

new-samplers
Stéphane Adjemian (Ryûk) 2023-04-10 20:59:05 +02:00 committed by Stéphane Adjemian (Ulysses)
parent 2fbbe66c0a
commit 60c0ed0180
Signed by: stepan
GPG Key ID: A6D44CB9C64CE77B
39 changed files with 1482 additions and 953 deletions

View File

@ -47,6 +47,7 @@ Bibliography
* Hansen, Lars P. (1982): “Large sample properties of generalized method of moments estimators,” Econometrica, 50(4), 10291054. * Hansen, Lars P. (1982): “Large sample properties of generalized method of moments estimators,” Econometrica, 50(4), 10291054.
* Hansen, Nikolaus and Stefan Kern (2004): “Evaluating the CMA Evolution Strategy on Multimodal Test Functions”. In: *Eighth International Conference on Parallel Problem Solving from Nature PPSN VIII*, Proceedings, Berlin: Springer, 282291. * Hansen, Nikolaus and Stefan Kern (2004): “Evaluating the CMA Evolution Strategy on Multimodal Test Functions”. In: *Eighth International Conference on Parallel Problem Solving from Nature PPSN VIII*, Proceedings, Berlin: Springer, 282291.
* Harvey, Andrew C. and Garry D.A. Phillips (1979): “Maximum likelihood estimation of regression models with autoregressive-moving average disturbances,” *Biometrika*, 66(1), 4958. * Harvey, Andrew C. and Garry D.A. Phillips (1979): “Maximum likelihood estimation of regression models with autoregressive-moving average disturbances,” *Biometrika*, 66(1), 4958.
* Herbst, Edward and Schorfheide, Frank (2014): "Sequential monte-carlo sampling for DSGE models," *Journal of Applied Econometrics*, 29, 1073-1098.
* Herbst, Edward (2015): “Using the “Chandrasekhar Recursions” for Likelihood Evaluation of DSGE Models,” *Computational Economics*, 45(4), 693705. * Herbst, Edward (2015): “Using the “Chandrasekhar Recursions” for Likelihood Evaluation of DSGE Models,” *Computational Economics*, 45(4), 693705.
* Ireland, Peter (2004): “A Method for Taking Models to the Data,” *Journal of Economic Dynamics and Control*, 28, 120526. * Ireland, Peter (2004): “A Method for Taking Models to the Data,” *Journal of Economic Dynamics and Control*, 28, 120526.
* Iskrev, Nikolay (2010): “Local identification in DSGE models,” *Journal of Monetary Economics*, 57(2), 189202. * Iskrev, Nikolay (2010): “Local identification in DSGE models,” *Journal of Monetary Economics*, 57(2), 189202.

View File

@ -7454,6 +7454,18 @@ observed variables.
Chain draws than the MH-algorithm. Its relative (in)efficiency can be investigated via Chain draws than the MH-algorithm. Its relative (in)efficiency can be investigated via
the reported inefficiency factors. the reported inefficiency factors.
``'hssmc'``
Instructs Dynare to use the *Herbst and Schorfheide (2014)*
version of the Sequential Monte-Carlo sampler instead of the
standard Random-Walk Metropolis-Hastings.
``'dsmh'``
Instructs Dynare to use the Dynamic Striated Metropolis Hastings
sampler proposed by *Waggoner, Wu and Zha (2016)* instead of the
standard Random-Walk Metropolis-Hastings.
.. option:: posterior_sampler_options = (NAME, VALUE, ...) .. option:: posterior_sampler_options = (NAME, VALUE, ...)
A list of NAME and VALUE pairs. Can be used to set options for A list of NAME and VALUE pairs. Can be used to set options for
@ -7466,141 +7478,173 @@ observed variables.
Available options are: Available options are:
.. _prop_distrib: .. _prop_distrib:
``'proposal_distribution'`` ``'proposal_distribution'``
Specifies the statistical distribution used for the Specifies the statistical distribution used for the
proposal density. proposal density.
``'rand_multivariate_normal'`` ``'rand_multivariate_normal'``
Use a multivariate normal distribution. This is the default. Use a multivariate normal distribution. This is the default.
``'rand_multivariate_student'`` ``'rand_multivariate_student'``
Use a multivariate student distribution. Use a multivariate student distribution.
``'student_degrees_of_freedom'`` ``'student_degrees_of_freedom'``
Specifies the degrees of freedom to be used with the Specifies the degrees of freedom to be used with the
multivariate student distribution. Default: ``3``. multivariate student distribution. Default: ``3``.
.. _usemhcov: .. _usemhcov:
``'use_mh_covariance_matrix'`` ``'use_mh_covariance_matrix'``
Indicates to use the covariance matrix of the draws Indicates to use the covariance matrix of the draws
from a previous MCMC run to define the covariance of from a previous MCMC run to define the covariance of
the proposal distribution. Requires the the proposal distribution. Requires the
:opt:`load_mh_file` option to be specified. Default: :opt:`load_mh_file` option to be specified. Default: ``0``.
``0``.
.. _scale-file: .. _scale-file:
``'scale_file'`` ``'scale_file'``
Provides the name of a ``_mh_scale.mat`` file storing Provides the name of a ``_mh_scale.mat`` file storing
the tuned scale factor from a previous run of the tuned scale factor from a previous run of
``mode_compute=6``. ``mode_compute=6``.
.. _savetmp: .. _savetmp:
``'save_tmp_file'`` ``'save_tmp_file'``
Save the MCMC draws into a ``_mh_tmp_blck`` file at the Save the MCMC draws into a ``_mh_tmp_blck`` file at the
refresh rate of the status bar instead of just saving refresh rate of the status bar instead of just saving
the draws when the current ``_mh*_blck`` file is the draws when the current ``_mh*_blck`` file is
full. Default: ``0`` full. Default: ``0``
``'independent_metropolis_hastings'`` ``'independent_metropolis_hastings'``
Takes the same options as in the case of Takes the same options as in the case of ``random_walk_metropolis_hastings``.
``random_walk_metropolis_hastings``.
``'slice'`` ``'slice'``
``'rotated'`` Available options are:
Triggers rotated slice iterations using a covariance ``'rotated'``
matrix from initial burn-in iterations. Requires either
``use_mh_covariance_matrix`` or
``slice_initialize_with_mode``. Default: ``0``.
``'mode_files'`` Triggers rotated slice iterations using a covariance
matrix from initial burn-in iterations. Requires either
``use_mh_covariance_matrix`` or
``slice_initialize_with_mode``. Default: ``0``.
For multimodal posteriors, provide the name of a file ``'mode_files'``
containing a ``nparam`` by ``nmodes`` variable called
``xparams`` storing the different modes. This array
must have one column vector per mode and the estimated
parameters along the row dimension. With this info, the
code will automatically trigger the ``rotated`` and
``mode`` options. Default: ``[]``.
``'slice_initialize_with_mode'`` For multimodal posteriors, provide the name of a file
containing a ``nparam`` by ``nmodes`` variable called
``xparams`` storing the different modes. This array
must have one column vector per mode and the estimated
parameters along the row dimension. With this info, the
code will automatically trigger the ``rotated`` and
``mode`` options. Default: ``[]``.
The default for slice is to set ``mode_compute=0`` and ``'slice_initialize_with_mode'``
start the chain(s) from a random location in the prior
space. This option first runs the mode-finder and then
starts the chain from the mode. Together with
``rotated``, it will use the inverse Hessian from the
mode to perform rotated slice iterations. Default:
``0``.
``'initial_step_size'`` The default for slice is to set ``mode_compute=0`` and
start the chain(s) from a random location in the prior
space. This option first runs the mode-finder and then
starts the chain from the mode. Together with
``rotated``, it will use the inverse Hessian from the
mode to perform rotated slice iterations. Default:
``0``.
Sets the initial size of the interval in the ``'initial_step_size'``
stepping-out procedure as fraction of the prior
support, i.e. the size will be ``initial_step_size *
(UB-LB)``. ``initial_step_size`` must be a real number
in the interval ``[0,1]``. Default: ``0.8``.
``'use_mh_covariance_matrix'`` Sets the initial size of the interval in the
stepping-out procedure as fraction of the prior
support, i.e. the size will be ``initial_step_size *
(UB-LB)``. ``initial_step_size`` must be a real number
in the interval ``[0,1]``. Default: ``0.8``.
See :ref:`use_mh_covariance_matrix <usemhcov>`. Must be ``'use_mh_covariance_matrix'``
used with ``'rotated'``. Default: ``0``.
``'save_tmp_file'`` See :ref:`use_mh_covariance_matrix <usemhcov>`. Must be
used with ``'rotated'``. Default: ``0``.
See :ref:`save_tmp_file <savetmp>`. Default: ``1``. ``'save_tmp_file'``
See :ref:`save_tmp_file <savetmp>`. Default: ``1``.
``'tailored_random_block_metropolis_hastings'`` ``'tailored_random_block_metropolis_hastings'``
``'proposal_distribution'`` Available options are:
``'proposal_distribution'``
Specifies the statistical distribution used for the Specifies the statistical distribution used for the
proposal density. See :ref:`proposal_distribution <prop_distrib>`. proposal density. See :ref:`proposal_distribution <prop_distrib>`.
``new_block_probability = DOUBLE`` ``new_block_probability = DOUBLE``
Specifies the probability of the next parameter Specifies the probability of the next parameter
belonging to a new block when the random blocking in belonging to a new block when the random blocking in
the TaRB Metropolis-Hastings algorithm is the TaRB Metropolis-Hastings algorithm is
conducted. The higher this number, the smaller is the conducted. The higher this number, the smaller is the
average block size and the more random blocks are average block size and the more random blocks are
formed during each parameter sweep. Default: ``0.25``. formed during each parameter sweep. Default: ``0.25``.
``mode_compute = INTEGER`` ``mode_compute = INTEGER``
Specifies the mode-finder run in every iteration for Specifies the mode-finder run in every iteration for
every block of the TaRB Metropolis-Hastings every block of the TaRB Metropolis-Hastings
algorithm. See :opt:`mode_compute <mode_compute = algorithm. See :opt:`mode_compute <mode_compute =
INTEGER | FUNCTION_NAME>`. Default: ``4``. INTEGER | FUNCTION_NAME>`. Default: ``4``.
``optim = (NAME, VALUE,...)`` ``optim = (NAME, VALUE,...)``
Specifies the options for the mode-finder used in the Specifies the options for the mode-finder used in the
TaRB Metropolis-Hastings algorithm. See :opt:`optim TaRB Metropolis-Hastings algorithm. See :opt:`optim
<optim = (NAME, VALUE, ...)>`. <optim = (NAME, VALUE, ...)>`.
``'scale_file'`` ``'scale_file'``
See :ref:`scale_file <scale-file>`.. See :ref:`scale_file <scale-file>`..
``'save_tmp_file'`` ``'save_tmp_file'``
See :ref:`save_tmp_file <savetmp>`. Default: ``1``. See :ref:`save_tmp_file <savetmp>`. Default: ``1``.
``'hssmc'``
Available options are:
``'particles'``
Number of particles. Default value is: 20000.
``'steps'``
Number of weights :math:`\phi_i\in[0,1]` on the likelihood function used to define a sequence of tempered likelihoods. This parameter is denoted :math:`N_{\phi}` in *Herbst and Schorfheide (2014)*, and we have :math:`\phi_1=0` and :math:`\phi_{N_\phi}=1`. Default value is: 25.
``'lambda'``
Positive parameter controling the sequence of weights :math:`\phi_i`, Default value is: 2. Weights are defined by:
.. math::
\phi_i = \left(\frac{i-1}{N_{\phi}-1}\right)^{\lambda}
for :math:`i=1,\ldots,N_{\phi}`. Usually we set :math:`\lambda>1`, so that :math:`\Delta \phi_i = \phi_i-\phi_{i-1}` is increasing with :math:`i`.
``'target'``
Acceptance rate target. Default value is: .25.
``'scale'``
Scale parameter in the mutation step (on the proposal covariance matrix of the MH iteration). Default value is: .5.
.. option:: moments_varendo .. option:: moments_varendo
Triggers the computation of the posterior distribution of the Triggers the computation of the posterior distribution of the

146
matlab/@dprior/admissible.m Normal file
View File

@ -0,0 +1,146 @@
function b = admissible(o, d)
% Return true iff d is an admissible draw in a distribution characterized by o.
%
% INPUTS
% - o [dprior] Distribution specification for a n×1 vector of independent continuous random variables
% - d [double] n×1 vector.
%
% OUTPUTS
% - b [logical] scalar.
%
% REMARKS
% None.
%
% EXAMPLE
%
% >> Prior = dprior(bayestopt_, options_.prior_trunc);
% >> d = Prior.draw()
% >> Prior.admissible(d)
% ans =
%
% logical
%
% 1
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
b = false;
if ~isequal(length(d), length(o.lb))
return
end
if all(d>=o.lb & d<=o.ub)
b = true;
end
return % --*-- Unit tests --*--
%@test:1
% Fill global structures with required fields...
prior_trunc = 1e-10;
p0 = repmat([1; 2; 3; 4; 5; 6; 8], 2, 1); % Prior shape
p1 = .4*ones(14,1); % Prior mean
p2 = .2*ones(14,1); % Prior std.
p3 = NaN(14,1);
p4 = NaN(14,1);
p5 = NaN(14,1);
p6 = NaN(14,1);
p7 = NaN(14,1);
for i=1:14
switch p0(i)
case 1
% Beta distribution
p3(i) = 0;
p4(i) = 1;
[p6(i), p7(i)] = beta_specification(p1(i), p2(i)^2, p3(i), p4(i));
p5(i) = compute_prior_mode([p6(i) p7(i)], 1);
case 2
% Gamma distribution
p3(i) = 0;
p4(i) = Inf;
[p6(i), p7(i)] = gamma_specification(p1(i), p2(i)^2, p3(i), p4(i));
p5(i) = compute_prior_mode([p6(i) p7(i)], 2);
case 3
% Normal distribution
p3(i) = -Inf;
p4(i) = Inf;
p6(i) = p1(i);
p7(i) = p2(i);
p5(i) = p1(i);
case 4
% Inverse Gamma (type I) distribution
p3(i) = 0;
p4(i) = Inf;
[p6(i), p7(i)] = inverse_gamma_specification(p1(i), p2(i)^2, p3(i), 1, false);
p5(i) = compute_prior_mode([p6(i) p7(i)], 4);
case 5
% Uniform distribution
[p1(i), p2(i), p6(i), p7(i)] = uniform_specification(p1(i), p2(i), p3(i), p4(i));
p3(i) = p6(i);
p4(i) = p7(i);
p5(i) = compute_prior_mode([p6(i) p7(i)], 5);
case 6
% Inverse Gamma (type II) distribution
p3(i) = 0;
p4(i) = Inf;
[p6(i), p7(i)] = inverse_gamma_specification(p1(i), p2(i)^2, p3(i), 2, false);
p5(i) = compute_prior_mode([p6(i) p7(i)], 6);
case 8
% Weibull distribution
p3(i) = 0;
p4(i) = Inf;
[p6(i), p7(i)] = weibull_specification(p1(i), p2(i)^2, p3(i));
p5(i) = compute_prior_mode([p6(i) p7(i)], 8);
otherwise
error('This density is not implemented!')
end
end
BayesInfo.pshape = p0;
BayesInfo.p1 = p1;
BayesInfo.p2 = p2;
BayesInfo.p3 = p3;
BayesInfo.p4 = p4;
BayesInfo.p5 = p5;
BayesInfo.p6 = p6;
BayesInfo.p7 = p7;
ndraws = 10;
% Call the tested routine
try
% Instantiate dprior object
o = dprior(BayesInfo, prior_trunc, false);
% Do simulations in a loop and estimate recursively the mean and the variance.
for i = 1:ndraws
draw = o.draw();
if ~o.admissible(draw)
error()
end
end
t(1) = true;
catch
t(1) = false;
end
T = all(t);
%@eof:1

View File

@ -1,7 +1,17 @@
function [tlogpostkern,loglik] = tempered_likelihood(TargetFun,xparam1,lambda,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_) function n = length(o)
% function [tlogpostkern,loglik] = tempered_likelihood(TargetFun,xparam1,lambda,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_)
% Copyright © 2022 Dynare Team % Return the dimension of the random vector.
%
% INPUTS
% - o [dprior] Distribution specification for a n×1 vector of independent continuous random variables
%
% OUTPUTS
% - n [integer] scalar.
%
% REMARKS
% None.
% Copyright © 2023 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -18,7 +28,4 @@ function [tlogpostkern,loglik] = tempered_likelihood(TargetFun,xparam1,lambda,da
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
logpostkern = -feval(TargetFun,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_); n = length(o.lb);
logprior = priordens(xparam1,bayestopt_.pshape,bayestopt_.p6,bayestopt_.p7,bayestopt_.p3,bayestopt_.p4);
loglik = logpostkern-logprior ;
tlogpostkern = lambda*loglik + logprior;

View File

@ -23,9 +23,9 @@ switch S(1).type
case '.' case '.'
if ismember(S(1).subs, {'p1','p2','p3','p4','p5','p6','p7','lb','ub'}) if ismember(S(1).subs, {'p1','p2','p3','p4','p5','p6','p7','lb','ub'})
p = builtin('subsref', o, S(1)); p = builtin('subsref', o, S(1));
elseif ismember(S(1).subs, {'draw'}) elseif ismember(S(1).subs, {'draw','length'})
p = feval(S(1).subs, o); p = feval(S(1).subs, o);
elseif ismember(S(1).subs, {'draws', 'density', 'densities', 'moments'}) elseif ismember(S(1).subs, {'draws', 'density', 'densities', 'moments', 'admissible'})
p = feval(S(1).subs, o , S(2).subs{:}); p = feval(S(1).subs, o , S(2).subs{:});
elseif ismember(S(1).subs, {'mean', 'median', 'variance', 'mode'}) elseif ismember(S(1).subs, {'mean', 'median', 'variance', 'mode'})
if (length(S)==2 && isempty(S(2).subs)) || length(S)==1 if (length(S)==2 && isempty(S(2).subs)) || length(S)==1

View File

@ -1,23 +1,24 @@
function Draws = GetAllPosteriorDraws(dname, fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFile, NumberOfDraws, nblcks, blck) function draws = GetAllPosteriorDraws(options_, dname, fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFile, NumberOfDraws, nblcks, blck)
% function Draws = GetAllPosteriorDraws(dname, fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFile, NumberOfDraws, nblcks, blck)
% Gets all posterior draws % Gets all posterior draws.
% %
% INPUTS % INPUTS
% dname: name of directory with results % - options_ [struct] Dynare's options.
% fname: name of mod file % - dname [char] name of directory with results.
% column: column of desired parameter in draw matrix % - fname [char] name of mod file.
% FirstMhFile: first mh file % - column [integer] scalar, parameter index.
% FirstLine: first line % - FirstMhFile [integer] scalar, first MH file.
% TotalNumberOfMhFile: total number of mh file % - FirstLine [integer] scalar, first line in first MH file.
% NumberOfDraws: number of draws % - TotalNumberOfMhFile [integer] scalar, total number of MH file.
% nblcks: total number of blocks % - NumberOfDraws [integer] scalar, number of posterior draws.
% blck: desired block to read % - nblcks [integer] scalar, total number of blocks.
% - blck: [integer] scalar, desired block to read.
% %
% OUTPUTS % OUTPUTS
% Draws: draws from posterior distribution % - draws: [double] NumberOfDraws×1 vector, draws from posterior distribution.
% %
% SPECIAL REQUIREMENTS % REMARKS
% none % Only the first and third input arguments are required for SMC samplers.
% Copyright © 2005-2023 Dynare Team % Copyright © 2005-2023 Dynare Team
% %
@ -36,55 +37,61 @@ function Draws = GetAllPosteriorDraws(dname, fname, column, FirstMhFile, FirstLi
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
iline = FirstLine; if ishssmc(options_)
linee = 1; % Load draws from the posterior distribution
DirectoryName = CheckPath('metropolis',dname); pfiles = dir(sprintf('%s/hssmc/particles-*.mat', dname));
posterior = load(sprintf('%s/hssmc/particles-%u-%u.mat', dname, length(pfiles), length(pfiles)));
if nblcks>1 && nargin<9 draws = transpose(posterior.particles(column,:));
Draws = zeros(NumberOfDraws*nblcks,1); else
iline0=iline; iline = FirstLine;
if column>0 linee = 1;
for blck = 1:nblcks DirectoryName = CheckPath('metropolis',dname);
iline=iline0; if nblcks>1 && nargin<10
draws = zeros(NumberOfDraws*nblcks,1);
iline0=iline;
if column>0
for blck = 1:nblcks
iline=iline0;
for file = FirstMhFile:TotalNumberOfMhFile
load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'x2')
NumberOfLines = size(x2(iline:end,:),1);
draws(linee:linee+NumberOfLines-1) = x2(iline:end,column);
linee = linee+NumberOfLines;
iline = 1;
end
end
else
for blck = 1:nblcks
iline=iline0;
for file = FirstMhFile:TotalNumberOfMhFile
load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'logpo2')
NumberOfLines = size(logpo2(iline:end),1);
draws(linee:linee+NumberOfLines-1) = logpo2(iline:end);
linee = linee+NumberOfLines;
iline = 1;
end
end
end
else
if nblcks==1
blck=1;
end
if column>0
for file = FirstMhFile:TotalNumberOfMhFile for file = FirstMhFile:TotalNumberOfMhFile
load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'x2') load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'x2')
NumberOfLines = size(x2(iline:end,:),1); NumberOfLines = size(x2(iline:end,:),1);
Draws(linee:linee+NumberOfLines-1) = x2(iline:end,column); draws(linee:linee+NumberOfLines-1) = x2(iline:end,column);
linee = linee+NumberOfLines; linee = linee+NumberOfLines;
iline = 1; iline = 1;
end end
end else
else
for blck = 1:nblcks
iline=iline0;
for file = FirstMhFile:TotalNumberOfMhFile for file = FirstMhFile:TotalNumberOfMhFile
load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'logpo2') load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'logpo2')
NumberOfLines = size(logpo2(iline:end),1); NumberOfLines = size(logpo2(iline:end,:),1);
Draws(linee:linee+NumberOfLines-1) = logpo2(iline:end); draws(linee:linee+NumberOfLines-1) = logpo2(iline:end);
linee = linee+NumberOfLines; linee = linee+NumberOfLines;
iline = 1; iline = 1;
end end
end end
end end
else end
if nblcks==1
blck=1;
end
if column>0
for file = FirstMhFile:TotalNumberOfMhFile
load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'x2')
NumberOfLines = size(x2(iline:end,:),1);
Draws(linee:linee+NumberOfLines-1) = x2(iline:end,column);
linee = linee+NumberOfLines;
iline = 1;
end
else
for file = FirstMhFile:TotalNumberOfMhFile
load([DirectoryName '/' fname '_mh' int2str(file) '_blck' int2str(blck)],'logpo2')
NumberOfLines = size(logpo2(iline:end,:),1);
Draws(linee:linee+NumberOfLines-1) = logpo2(iline:end);
linee = linee+NumberOfLines;
iline = 1;
end
end
end

View File

@ -1,18 +1,15 @@
function [mean,variance] = GetPosteriorMeanVariance(M_,drop) function [mean, variance] = GetPosteriorMeanVariance(options_, M_)
%function [mean,variance] = GetPosteriorMeanVariance(M,drop) %function [mean,variance] = GetPosteriorMeanVariance(M,drop)
% Computes the posterior mean and variance % Computes the posterior mean and variance
% (+updates of oo_ & TeX output). % (+updates of oo_ & TeX output).
% %
% INPUTS % INPUTS
% M_ [structure] Dynare model structure % - options_ [struct] Dynare's options.
% drop [double] share of draws to drop % - M_ [struct] Description of the model.
% %
% OUTPUTS % OUTPUTS
% mean [double] mean parameter vector % - mean [double] n×1 vector, posterior expectation.
% variance [double] variance % - variance [double] n×n matrix, posterior variance.
%
% SPECIAL REQUIREMENTS
% None.
% Copyright © 2012-2023 Dynare Team % Copyright © 2012-2023 Dynare Team
% %
@ -31,37 +28,46 @@ function [mean,variance] = GetPosteriorMeanVariance(M_,drop)
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
MetropolisFolder = CheckPath('metropolis',M_.dname); if ishssmc(options_)
FileName = M_.fname; % Load draws from the posterior distribution
BaseName = [MetropolisFolder filesep FileName]; pfiles = dir(sprintf('%s/hssmc/particles-*.mat', M_.dname));
record=load_last_mh_history_file(MetropolisFolder, FileName); posterior = load(sprintf('%s/hssmc/particles-%u-%u.mat', M_.dname, length(pfiles), length(pfiles)));
NbrDraws = sum(record.MhDraws(:,1)); % Compute the posterior mean
NbrFiles = sum(record.MhDraws(:,2)); mean = sum(posterior.particles, 2)/length(posterior.tlogpostkernel);
NbrBlocks = record.Nblck; % Compute the posterior covariance
mean = 0; variance = (posterior.particles-mean)*(posterior.particles-mean)'/length(posterior.tlogpostkernel);
variance = 0; else
MetropolisFolder = CheckPath('metropolis',M_.dname);
NbrKeptDraws = 0; FileName = M_.fname;
for i=1:NbrBlocks BaseName = [MetropolisFolder filesep FileName];
NbrDrawsCurrentBlock = 0; record=load_last_mh_history_file(MetropolisFolder, FileName);
for j=1:NbrFiles NbrDraws = sum(record.MhDraws(:,1));
o = load([BaseName '_mh' int2str(j) '_blck' int2str(i),'.mat']); NbrFiles = sum(record.MhDraws(:,2));
NbrDrawsCurrentFile = size(o.x2,1); NbrBlocks = record.Nblck;
if NbrDrawsCurrentBlock + NbrDrawsCurrentFile <= drop*NbrDraws mean = 0;
variance = 0;
NbrKeptDraws = 0;
for i=1:NbrBlocks
NbrDrawsCurrentBlock = 0;
for j=1:NbrFiles
o = load([BaseName '_mh' int2str(j) '_blck' int2str(i),'.mat']);
NbrDrawsCurrentFile = size(o.x2,1);
if NbrDrawsCurrentBlock + NbrDrawsCurrentFile <= options_.mh_drop*NbrDraws
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
continue
elseif NbrDrawsCurrentBlock < options_.mh_drop*NbrDraws
FirstDraw = ceil(options_.mh_drop*NbrDraws - NbrDrawsCurrentBlock + 1);
x2 = o.x2(FirstDraw:end,:);
else
x2 = o.x2;
end
NbrKeptDrawsCurrentFile = size(x2,1);
%recursively compute mean and variance
mean = (NbrKeptDraws*mean + sum(x2)')/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
x2Demeaned = bsxfun(@minus,x2,mean');
variance = (NbrKeptDraws*variance + x2Demeaned'*x2Demeaned)/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile; NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
continue NbrKeptDraws = NbrKeptDraws + NbrKeptDrawsCurrentFile;
elseif NbrDrawsCurrentBlock < drop*NbrDraws
FirstDraw = ceil(drop*NbrDraws - NbrDrawsCurrentBlock + 1);
x2 = o.x2(FirstDraw:end,:);
else
x2 = o.x2;
end end
NbrKeptDrawsCurrentFile = size(x2,1);
%recursively compute mean and variance
mean = (NbrKeptDraws*mean + sum(x2)')/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
x2Demeaned = bsxfun(@minus,x2,mean');
variance = (NbrKeptDraws*variance + x2Demeaned'*x2Demeaned)/(NbrKeptDraws+NbrKeptDrawsCurrentFile);
NbrDrawsCurrentBlock = NbrDrawsCurrentBlock + NbrDrawsCurrentFile;
NbrKeptDraws = NbrKeptDraws + NbrKeptDrawsCurrentFile;
end end
end end

View File

@ -1,5 +1,5 @@
function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bayestopt_, oo_, pnames) function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bayestopt_, oo_, pnames)
% function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bayestopt_, oo_, pnames)
% This function prints and saves posterior estimates after the mcmc % This function prints and saves posterior estimates after the mcmc
% (+updates of oo_ & TeX output). % (+updates of oo_ & TeX output).
% %
@ -34,10 +34,6 @@ function oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bay
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
%if ~options_.mh_replic && options_.load_mh_file
% load([M_.fname '_results.mat'],'oo_');
%end
TeX = options_.TeX; TeX = options_.TeX;
nvx = estim_params_.nvx; nvx = estim_params_.nvx;
nvn = estim_params_.nvn; nvn = estim_params_.nvn;
@ -45,19 +41,20 @@ ncx = estim_params_.ncx;
ncn = estim_params_.ncn; ncn = estim_params_.ncn;
np = estim_params_.np ; np = estim_params_.np ;
MetropolisFolder = CheckPath('metropolis',M_.dname);
latexFolder = CheckPath('latex',M_.dname); latexFolder = CheckPath('latex',M_.dname);
FileName = M_.fname; FileName = M_.fname;
record=load_last_mh_history_file(MetropolisFolder,FileName); if ~issmc(options_)
MetropolisFolder = CheckPath('metropolis',M_.dname);
FirstLine = record.KeepedDraws.FirstLine; record=load_last_mh_history_file(MetropolisFolder,FileName);
TotalNumberOfMhFiles = sum(record.MhDraws(:,2)); FirstLine = record.KeepedDraws.FirstLine;
TotalNumberOfMhDraws = sum(record.MhDraws(:,1)); TotalNumberOfMhFiles = sum(record.MhDraws(:,2));
FirstMhFile = record.KeepedDraws.FirstMhFile; TotalNumberOfMhDraws = sum(record.MhDraws(:,1));
NumberOfDraws = TotalNumberOfMhDraws-floor(options_.mh_drop*TotalNumberOfMhDraws); FirstMhFile = record.KeepedDraws.FirstMhFile;
mh_nblck = size(record.LastParameters,1); NumberOfDraws = TotalNumberOfMhDraws-floor(options_.mh_drop*TotalNumberOfMhDraws);
clear record; mh_nblck = size(record.LastParameters,1);
clear record;
end
header_width = row_header_width(M_, estim_params_, bayestopt_); header_width = row_header_width(M_, estim_params_, bayestopt_);
hpd_interval=[num2str(options_.mh_conf_sig*100), '% HPD interval']; hpd_interval=[num2str(options_.mh_conf_sig*100), '% HPD interval'];
@ -68,13 +65,26 @@ skipline(2)
disp('ESTIMATION RESULTS') disp('ESTIMATION RESULTS')
skipline() skipline()
if ~isfield(oo_,'MarginalDensity') || ~isfield(oo_.MarginalDensity,'ModifiedHarmonicMean') if ishssmc(options_)
[~,oo_] = marginal_density(M_, options_, estim_params_, oo_, bayestopt_); dprintf('Log data density is %f.', oo_.MarginalDensity.hssmc);
% Set function handle for GetAllPosteriorDraws
getalldraws = @(i) GetAllPosteriorDraws(options_, M_.dname, [], i);
else
if ~isfield(oo_,'MarginalDensity') || (issmc(options_) && ~isfield(oo_.MarginalDensity,'ModifiedHarmonicMean'))
[~, oo_] = marginal_density(M_, options_, estim_params_, oo_, bayestopt_);
end
fprintf('Log data density is %f.', oo_.MarginalDensity.ModifiedHarmonicMean);
% Set function handle for GetAllPosteriordraws
getalldraws = @(i) GetAllPosteriorDraws(options_, M_.dname, M_.fname, i, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck);
end end
fprintf('\nLog data density is %f.\n', oo_.MarginalDensity.ModifiedHarmonicMean);
num_draws=NumberOfDraws*mh_nblck; if ishssmc(options_)
hpd_draws = round((1-options_.mh_conf_sig)*num_draws); num_draws = options_.posterior_sampler_options.hssmc.particles;
hpd_draws = round((1-options_.mh_conf_sig)*num_draws);
else
num_draws=NumberOfDraws*mh_nblck;
hpd_draws = round((1-options_.mh_conf_sig)*num_draws);
end
if hpd_draws<2 if hpd_draws<2
fprintf('posterior_moments: There are not enough draws computes to compute HPD Intervals. Skipping their computation.\n') fprintf('posterior_moments: There are not enough draws computes to compute HPD Intervals. Skipping their computation.\n')
@ -93,9 +103,9 @@ if np
disp(tit2) disp(tit2)
ip = nvx+nvn+ncx+ncn+1; ip = nvx+nvn+ncx+ncn+1;
for i=1:np for i=1:np
if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) || ishssmc(options_)
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws, 1, options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
name = bayestopt_.name{ip}; name = bayestopt_.name{ip};
oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density); oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density);
else else
@ -103,8 +113,8 @@ if np
name = bayestopt_.name{ip}; name = bayestopt_.name{ip};
[post_mean, hpd_interval, post_var] = Extractoo(oo_, name, type); [post_mean, hpd_interval, post_var] = Extractoo(oo_, name, type);
catch catch
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws, 1, options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
name = bayestopt_.name{ip}; name = bayestopt_.name{ip};
oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density); oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density);
end end
@ -137,8 +147,8 @@ if nvx
disp(tit2) disp(tit2)
for i=1:nvx for i=1:nvx
if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws, 1, options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
k = estim_params_.var_exo(i,1); k = estim_params_.var_exo(i,1);
name = M_.exo_names{k}; name = M_.exo_names{k};
oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density); oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density);
@ -149,9 +159,8 @@ if nvx
name = M_.exo_names{k}; name = M_.exo_names{k};
[post_mean, hpd_interval, post_var] = Extractoo(oo_, name, type); [post_mean, hpd_interval, post_var] = Extractoo(oo_, name, type);
catch catch
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = ... [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
posterior_moments(Draws, 1, options_.mh_conf_sig);
k = estim_params_.var_exo(i,1); k = estim_params_.var_exo(i,1);
name = M_.exo_names{k}; name = M_.exo_names{k};
oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density); oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density);
@ -181,8 +190,8 @@ if nvn
ip = nvx+1; ip = nvx+1;
for i=1:nvn for i=1:nvn
if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws, 1, options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
name = options_.varobs{estim_params_.nvn_observable_correspondence(i,1)}; name = options_.varobs{estim_params_.nvn_observable_correspondence(i,1)};
oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density); oo_ = Filloo(oo_, name, type, post_mean, hpd_interval, post_median, post_var, post_deciles, density);
else else
@ -190,8 +199,8 @@ if nvn
name = options_.varobs{estim_params_.nvn_observable_correspondence(i,1)}; name = options_.varobs{estim_params_.nvn_observable_correspondence(i,1)};
[post_mean,hpd_interval,post_var] = Extractoo(oo_,name,type); [post_mean,hpd_interval,post_var] = Extractoo(oo_,name,type);
catch catch
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip,FirstMhFile,FirstLine,TotalNumberOfMhFiles,NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws,1,options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws,1,options_.mh_conf_sig);
name = options_.varobs{estim_params_.nvn_observable_correspondence(i,1)}; name = options_.varobs{estim_params_.nvn_observable_correspondence(i,1)};
oo_ = Filloo(oo_,name,type,post_mean,hpd_interval,post_median,post_var,post_deciles,density); oo_ = Filloo(oo_,name,type,post_mean,hpd_interval,post_median,post_var,post_deciles,density);
end end
@ -220,8 +229,8 @@ if ncx
ip = nvx+nvn+1; ip = nvx+nvn+1;
for i=1:ncx for i=1:ncx
if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws,1,options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws,1,options_.mh_conf_sig);
k1 = estim_params_.corrx(i,1); k1 = estim_params_.corrx(i,1);
k2 = estim_params_.corrx(i,2); k2 = estim_params_.corrx(i,2);
name = sprintf('%s,%s', M_.exo_names{k1}, M_.exo_names{k2}); name = sprintf('%s,%s', M_.exo_names{k1}, M_.exo_names{k2});
@ -237,8 +246,8 @@ if ncx
NAME = sprintf('%s_%s', M_.exo_names{k1}, M_.exo_names{k2}); NAME = sprintf('%s_%s', M_.exo_names{k1}, M_.exo_names{k2});
[post_mean,hpd_interval,post_var] = Extractoo(oo_, NAME, type); [post_mean,hpd_interval,post_var] = Extractoo(oo_, NAME, type);
catch catch
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws, 1, options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
k1 = estim_params_.corrx(i,1); k1 = estim_params_.corrx(i,1);
k2 = estim_params_.corrx(i,2); k2 = estim_params_.corrx(i,2);
name = sprintf('%s,%s', M_.exo_names{k1}, M_.exo_names{k2}); name = sprintf('%s,%s', M_.exo_names{k1}, M_.exo_names{k2});
@ -259,6 +268,7 @@ if ncx
TeXEnd(fid, 4, 'correlation of structural shocks'); TeXEnd(fid, 4, 'correlation of structural shocks');
end end
end end
if ncn if ncn
type = 'measurement_errors_corr'; type = 'measurement_errors_corr';
if TeX if TeX
@ -270,8 +280,8 @@ if ncn
ip = nvx+nvn+ncx+1; ip = nvx+nvn+ncx+1;
for i=1:ncn for i=1:ncn
if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip,FirstMhFile,FirstLine,TotalNumberOfMhFiles,NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws, 1, options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
k1 = estim_params_.corrn(i,1); k1 = estim_params_.corrn(i,1);
k2 = estim_params_.corrn(i,2); k2 = estim_params_.corrn(i,2);
name = sprintf('%s,%s', M_.endo_names{k1}, M_.endo_names{k2}); name = sprintf('%s,%s', M_.endo_names{k1}, M_.endo_names{k2});
@ -285,8 +295,8 @@ if ncn
NAME = sprintf('%s_%s', M_.endo_names{k1}, M_.endo_names{k2}); NAME = sprintf('%s_%s', M_.endo_names{k1}, M_.endo_names{k2});
[post_mean,hpd_interval,post_var] = Extractoo(oo_, NAME, type); [post_mean,hpd_interval,post_var] = Extractoo(oo_, NAME, type);
catch catch
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, ip, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, mh_nblck); draws = getalldraws(ip);
[post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(Draws, 1, options_.mh_conf_sig); [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, 1, options_.mh_conf_sig);
k1 = estim_params_.corrn(i,1); k1 = estim_params_.corrn(i,1);
k2 = estim_params_.corrn(i,2); k2 = estim_params_.corrn(i,2);
name = sprintf('%s,%s', M_.endo_names{k1}, M_.endo_names{k2}); name = sprintf('%s,%s', M_.endo_names{k1}, M_.endo_names{k2});
@ -333,11 +343,8 @@ fprintf(fidTeX, ' & \\multicolumn{3}{c}{Prior} & \\multicolumn{4}{c}{Posterio
fprintf(fidTeX, ' \\cmidrule(r{.75em}){2-4} \\cmidrule(r{.75em}){5-8}\n'); fprintf(fidTeX, ' \\cmidrule(r{.75em}){2-4} \\cmidrule(r{.75em}){5-8}\n');
fprintf(fidTeX, ' & Dist. & Mean & Stdev. & Mean & Stdev. & HPD inf & HPD sup\\\\\n'); fprintf(fidTeX, ' & Dist. & Mean & Stdev. & Mean & Stdev. & HPD inf & HPD sup\\\\\n');
fprintf(fidTeX, '\\midrule \\endhead \n'); fprintf(fidTeX, '\\midrule \\endhead \n');
fprintf(fidTeX, '\\bottomrule \\multicolumn{8}{r}{(Continued on next page)} \\endfoot \n'); fprintf(fidTeX, '\\bottomrule \\multicolumn{8}{r}{(Continued on next page)} \\endfoot \n');
fprintf(fidTeX, '\\bottomrule \\endlastfoot \n'); fprintf(fidTeX, '\\bottomrule \\endlastfoot \n');
fid = fidTeX; fid = fidTeX;
@ -375,4 +382,4 @@ hpd_interval = zeros(2,1);
post_mean = oo.posterior_mean.(type).(name); post_mean = oo.posterior_mean.(type).(name);
hpd_interval(1) = oo.posterior_hpdinf.(type).(name); hpd_interval(1) = oo.posterior_hpdinf.(type).(name);
hpd_interval(2) = oo.posterior_hpdsup.(type).(name); hpd_interval(2) = oo.posterior_hpdsup.(type).(name);
post_var = oo.posterior_variance.(type).(name); post_var = oo.posterior_variance.(type).(name);

View File

@ -1,246 +0,0 @@
function Herbst_Schorfheide_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_)
% function Herbst_Schorfheide_sampler(TargetFun,xparam1,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 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 © 2006-2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
% Create the tempering schedule
phi = bsxfun(@power,(bsxfun(@minus,1:1:options_.posterior_sampler_options.HSsmc.nphi,1)/(options_.posterior_sampler_options.HSsmc.nphi-1)),options_.posterior_sampler_options.HSsmc.lambda) ;
% tuning for MH algorithms matrices
zhat = 0 ; % normalization constant
csim = zeros(options_.posterior_sampler_options.HSsmc.nphi,1) ; % scale parameter
ESSsim = zeros(options_.posterior_sampler_options.HSsmc.nphi,1) ; % ESS
acptsim = zeros(options_.posterior_sampler_options.HSsmc.nphi,1) ; % average acceptance rate
% Step 0: Initialization of the sampler
[ param, tlogpost_i, loglik, bayestopt_] = ...
SMC_samplers_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,options_.posterior_sampler_options.HSsmc.nparticles);
weights = ones(options_.posterior_sampler_options.HSsmc.nparticles,1)/options_.posterior_sampler_options.HSsmc.nparticles ;
% The Herbst and Schorfheide sampler starts here
for i=2:options_.posterior_sampler_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_.posterior_sampler_options.HSsmc.nparticles/2)
indx_resmpl = smc_resampling(weights,rand(1,1),options_.posterior_sampler_options.HSsmc.nparticles) ;
param = param(:,indx_resmpl) ;
loglik = loglik(indx_resmpl) ;
tlogpost_i = tlogpost_i(indx_resmpl) ;
weights = ones(options_.posterior_sampler_options.HSsmc.nparticles,1)/options_.posterior_sampler_options.HSsmc.nparticles ;
end
% (c) Mutation
options_.posterior_sampler_options.HSsmc.c = options_.posterior_sampler_options.HSsmc.c*modified_logit(0.95,0.1,16.0,options_.posterior_sampler_options.HSsmc.acpt-options_.posterior_sampler_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_.posterior_sampler_options.HSsmc.option_mutation==1
[param,tlogpost_i,loglik,options_.posterior_sampler_options.HSsmc.acpt] = mutation_RW(TargetFun,param,tlogpost_i,loglik,phi,i,options_.posterior_sampler_options.HSsmc.c*Rchol,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) ;
elseif options_.posterior_sampler_options.HSsmc.option_mutation==2
inv_R = inv(options_.posterior_sampler_options.HSsmc.c^2*R) ;
Rdiagchol = sqrt(diag(R)) ;
[param,tlogpost_i,loglik,options_.posterior_sampler_options.HSsmc.acpt] = mutation_Mixture(TargetFun,param,tlogpost_i,loglik,phi,i,options_.posterior_sampler_options.HSsmc.c*Rchol,options_.posterior_sampler_options.HSsmc.c*Rdiagchol,inv_R,mu,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_) ;
end
acptsim(i) = options_.posterior_sampler_options.HSsmc.acpt ;
csim(i) = options_.posterior_sampler_options.HSsmc.c ;
% print information
fprintf(' Iteration = %5.0f / %5.0f \n', i, options_.posterior_sampler_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_.posterior_sampler_options.HSsmc.nparticles);
distrib_param = param(:,indx_resmpl);
fprintf(' Log_lik = %5.4f \n', zhat);
mean_xparam = mean(distrib_param,2);
npar = length(xparam1) ;
%mat_var_cov = bsxfun(@minus,distrib_param,mean_xparam) ;
%mat_var_cov = (mat_var_cov*mat_var_cov')/(options_.posterior_sampler_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_.posterior_sampler_options.HSsmc.nparticles) ;
ub95_xparam(i) = temp(0.975*options_.posterior_sampler_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_.varobs);
str = sprintf('%s\n %s \t\t %5.4f \t\t %7.5f \t\t %5.4f', str, name, lb95_xparam(l), mean_xparam(l), ub95_xparam(l));
end
disp([str])
disp('')
%% Plot parameters densities
[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_fig = dyn_figure(options_.nodisplay,'Name','Parameters Densities');
for k=1:npar %min(nstar,npar-(plt-1)*nstar)
subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k)
%kk = (plt-1)*nstar+k;
[name,texname] = get_the_name(k,TeX,M_,estim_params_,options_.varobs);
optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.posterior_sampler_options.HSsmc.nparticles,bandwidth,kernel_function);
[density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,...
options_.posterior_sampler_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_fig,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format);
if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
% TeX eps loader file
fprintf(fidTeX,'\\begin{figure}[H]\n');
fprintf(fidTeX,'\\centering \n');
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/floor(sqrt(npar)),1),M_.fname,int2str(plt));
fprintf(fidTeX,'\\caption{Parameter densities based on the 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_.posterior_sampler_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)<exp(tlogpostx-tlogpost_i(j)) % accept
acpt = acpt + 1 ;
param(:,j) = candidate;
loglik(j) = loglikx;
tlogpost_i(j) = tlogpostx;
end
end
end
end
end
acpt = acpt/options_.posterior_sampler_options.HSsmc.nparticles;
function [param,tlogpost_i,loglik,acpt] = mutation_Mixture(TargetFun,param,tlogpost_i,loglik,phi,i,cRchol,cRdiagchol,invR,mu,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_.posterior_sampler_options.HSsmc.nparticles
qx = 0 ;
q0 = 0 ;
alpind = rand(1,1) ;
validate= 0;
while validate==0
if alpind<options_.posterior_sampler_options.HSsmc.alp % RW, no need to modify qx and q0
candidate = param(:,j) + cRchol*randn(size(param,1),1);
elseif alpind<options_.posterior_sampler_options.HSsmc.alp + (1-options_.posterior_sampler_options.HSsmc.alp/2) % random walk with diagonal cov no need to modify qx and q0
candidate = param(:,j) + cRdiagchol*randn(size(param,1),1);
else % Proposal densities
candidate = mu + cRchol*randn(size(param,1),1);
qx = -.5*(candidate-mu)'*invR*(candidate-mu) ; % no need of the constants in the acceptation rule
q0 = -.5*(param(:,j)-mu)'*invR*(param(:,j)-mu) ;
end
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)<exp((tlogpostx-qx)-(tlogpost_i(j)-q0)) % accept
acpt = acpt + 1 ;
param(:,j) = candidate;
loglik(j) = loglikx;
tlogpost_i(j) = tlogpostx;
end
end
end
end
end
acpt = acpt/options_.posterior_sampler_options.HSsmc.nparticles;
function x = modified_logit(a,b,c,d)
tmp = exp(c*d) ;
x = a + b*tmp/(1 + tmp) ;

View File

@ -31,6 +31,7 @@ function oo_ = PlotPosteriorDistributions(estim_params_, M_, options_, bayestopt
% %
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
latexDirectoryName = CheckPath('latex',M_.dname); latexDirectoryName = CheckPath('latex',M_.dname);
graphDirectoryName = CheckPath('graphs',M_.dname); graphDirectoryName = CheckPath('graphs',M_.dname);
@ -72,7 +73,7 @@ for i=1:npar
f1 = oo_.posterior_density.shocks_std.(name)(:,2); f1 = oo_.posterior_density.shocks_std.(name)(:,2);
oo_.prior_density.shocks_std.(name)(:,1) = x2; oo_.prior_density.shocks_std.(name)(:,1) = x2;
oo_.prior_density.shocks_std.(name)(:,2) = f2; oo_.prior_density.shocks_std.(name)(:,2) = f2;
if ~options_.mh_posterior_mode_estimation if ~issmc(options_) && ~options_.mh_posterior_mode_estimation
pmod = oo_.posterior_mode.shocks_std.(name); pmod = oo_.posterior_mode.shocks_std.(name);
end end
elseif i <= nvx+nvn elseif i <= nvx+nvn
@ -81,7 +82,7 @@ for i=1:npar
f1 = oo_.posterior_density.measurement_errors_std.(name)(:,2); f1 = oo_.posterior_density.measurement_errors_std.(name)(:,2);
oo_.prior_density.measurement_errors_std.(name)(:,1) = x2; oo_.prior_density.measurement_errors_std.(name)(:,1) = x2;
oo_.prior_density.measurement_errors_std.(name)(:,2) = f2; oo_.prior_density.measurement_errors_std.(name)(:,2) = f2;
if ~options_.mh_posterior_mode_estimation if ~issmc(options_) && ~options_.mh_posterior_mode_estimation
pmod = oo_.posterior_mode.measurement_errors_std.(name); pmod = oo_.posterior_mode.measurement_errors_std.(name);
end end
elseif i <= nvx+nvn+ncx elseif i <= nvx+nvn+ncx
@ -93,7 +94,7 @@ for i=1:npar
f1 = oo_.posterior_density.shocks_corr.(name)(:,2); f1 = oo_.posterior_density.shocks_corr.(name)(:,2);
oo_.prior_density.shocks_corr.(name)(:,1) = x2; oo_.prior_density.shocks_corr.(name)(:,1) = x2;
oo_.prior_density.shocks_corr.(name)(:,2) = f2; oo_.prior_density.shocks_corr.(name)(:,2) = f2;
if ~options_.mh_posterior_mode_estimation if ~issmc(options_) && ~options_.mh_posterior_mode_estimation
pmod = oo_.posterior_mode.shocks_corr.(name); pmod = oo_.posterior_mode.shocks_corr.(name);
end end
elseif i <= nvx+nvn+ncx+ncn elseif i <= nvx+nvn+ncx+ncn
@ -105,7 +106,7 @@ for i=1:npar
f1 = oo_.posterior_density.measurement_errors_corr.(name)(:,2); f1 = oo_.posterior_density.measurement_errors_corr.(name)(:,2);
oo_.prior_density.measurement_errors_corr.(name)(:,1) = x2; oo_.prior_density.measurement_errors_corr.(name)(:,1) = x2;
oo_.prior_density.measurement_errors_corr.(name)(:,2) = f2; oo_.prior_density.measurement_errors_corr.(name)(:,2) = f2;
if ~options_.mh_posterior_mode_estimation if ~issmc(options_) && ~options_.mh_posterior_mode_estimation
pmod = oo_.posterior_mode.measurement_errors_corr.(name); pmod = oo_.posterior_mode.measurement_errors_corr.(name);
end end
else else
@ -115,7 +116,7 @@ for i=1:npar
f1 = oo_.posterior_density.parameters.(name)(:,2); f1 = oo_.posterior_density.parameters.(name)(:,2);
oo_.prior_density.parameters.(name)(:,1) = x2; oo_.prior_density.parameters.(name)(:,1) = x2;
oo_.prior_density.parameters.(name)(:,2) = f2; oo_.prior_density.parameters.(name)(:,2) = f2;
if ~options_.mh_posterior_mode_estimation if ~issmc(options_) && ~options_.mh_posterior_mode_estimation
pmod = oo_.posterior_mode.parameters.(name); pmod = oo_.posterior_mode.parameters.(name);
end end
end end
@ -130,7 +131,7 @@ for i=1:npar
set(hh_plt, 'color', [0.7 0.7 0.7]); set(hh_plt, 'color', [0.7 0.7 0.7]);
hold on; hold on;
plot(x1, f1, '-k', 'linewidth', 2); plot(x1, f1, '-k', 'linewidth', 2);
if ~options_.mh_posterior_mode_estimation if ~issmc(options_) && ~options_.mh_posterior_mode_estimation
plot([pmod pmod], [0.0 1.1*top0], '--g', 'linewidth', 2); plot([pmod pmod], [0.0 1.1*top0], '--g', 'linewidth', 2);
end end
box on box on
@ -160,4 +161,4 @@ for i=1:npar
end end
subplotnum = 0; subplotnum = 0;
end end
end end

View File

@ -1,113 +0,0 @@
function [ ix2, temperedlogpost, loglik, bayestopt_] = ...
SMC_samplers_initialization(TargetFun, xparam1, mh_bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_, NumberOfParticles)
% function [ ix2, ilogpo2, ModelName, MetropolisFolder, FirstBlock, FirstLine, npar, NumberOfParticles, bayestopt_] = ...
% SMC_samplers_initialization(TargetFun, xparam1, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,NumberOfParticles)
% Draw in prior distribution to initialize samplers.
%
% 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 bayestopt_ [structure] estimation options structure
%
% SPECIAL REQUIREMENTS
% None.
% Copyright © 2006-2022 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
%Initialize outputs
ix2 = [];
ilogpo2 = [];
iloglik2 = [];
ModelName = [];
MetropolisFolder = [];
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...
options_=set_dynare_seed_local_options(options_,'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()

View File

@ -1,20 +1,17 @@
function [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options(posterior_sampler_options, fname, dname, options_, bounds, bayestopt_,outputFolderName) function [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options(posterior_sampler_options, fname, dname, options_, bounds, bayestopt_, outputFolderName)
% function [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options(posterior_sampler_options, fname, dname, options_, bounds, bayestopt_,outputFolderName)
% initialization of posterior samplers % Initialization of posterior samplers
% %
% INPUTS % INPUTS
% posterior_sampler_options: posterior sampler options % - posterior_sampler_options [struct] posterior sampler options
% fname: name of the mod-file % - options_ [struct] options
% dname: name of directory with metropolis folder % - bounds [struct] prior bounds
% options_: structure storing the options % - bayestopt_ [struct] information about priors
% bounds: structure containing prior bounds %
% bayestopt_: structure storing information about priors
% OUTPUTS % OUTPUTS
% posterior_sampler_options: checked posterior sampler options % - posterior_sampler_options [struct] checked posterior sampler options (updated)
% options_: structure storing the options % - options_ [struct] options (updated)
% bayestopt_: structure storing information about priors % - bayestopt_ [struct] information about priors (updated)
% outputFolderName: string of folder to store mat files
% %
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% none % none
@ -40,15 +37,17 @@ if nargin < 7
outputFolderName = 'Output'; outputFolderName = 'Output';
end end
init=0; init = false;
if isempty(posterior_sampler_options) if isempty(posterior_sampler_options)
init=1; init = true;
end end
if init if init
% set default options and user defined options % set default options and user defined options
posterior_sampler_options.posterior_sampling_method = options_.posterior_sampler_options.posterior_sampling_method; posterior_sampler_options.posterior_sampling_method = options_.posterior_sampler_options.posterior_sampling_method;
posterior_sampler_options.bounds = bounds; if ~issmc(options_)
posterior_sampler_options.bounds = bounds;
end
switch posterior_sampler_options.posterior_sampling_method switch posterior_sampler_options.posterior_sampling_method
@ -227,7 +226,6 @@ if init
end end
end end
case 'slice' case 'slice'
posterior_sampler_options.parallel_bar_refresh_rate=1; posterior_sampler_options.parallel_bar_refresh_rate=1;
posterior_sampler_options.serial_bar_refresh_rate=1; posterior_sampler_options.serial_bar_refresh_rate=1;
@ -342,50 +340,120 @@ if init
end end
% moreover slice must be associated to: % moreover slice must be associated to:
% options_.mh_posterior_mode_estimation = false; % options_.mh_posterior_mode_estimation = false;
% this is done below, but perhaps preprocessing should do this? % this is done below, but perhaps preprocessing should do this?
if ~isempty(posterior_sampler_options.mode) if ~isempty(posterior_sampler_options.mode)
% multimodal case % multimodal case
posterior_sampler_options.rotated = 1; posterior_sampler_options.rotated = 1;
posterior_sampler_options.WR=[]; posterior_sampler_options.WR=[];
end end
% posterior_sampler_options = set_default_option(posterior_sampler_options,'mode_files',[]); % posterior_sampler_options = set_default_option(posterior_sampler_options,'mode_files',[]);
posterior_sampler_options.W1=posterior_sampler_options.initial_step_size*(bounds.ub-bounds.lb); posterior_sampler_options.W1=posterior_sampler_options.initial_step_size*(bounds.ub-bounds.lb);
if options_.load_mh_file if options_.load_mh_file
posterior_sampler_options.slice_initialize_with_mode = 0; posterior_sampler_options.slice_initialize_with_mode = 0;
else else
if ~posterior_sampler_options.slice_initialize_with_mode if ~posterior_sampler_options.slice_initialize_with_mode
posterior_sampler_options.invhess=[]; posterior_sampler_options.invhess=[];
end
end
if ~isempty(posterior_sampler_options.mode_files) % multimodal case
modes = posterior_sampler_options.mode_files; % these can be also mean files from previous parallel slice chains
load(modes, 'xparams')
if size(xparams,2)<2
error(['check_posterior_sampler_options:: Variable xparams loaded in file <' modes '> has size [' int2str(size(xparams,1)) 'x' int2str(size(xparams,2)) ']: it must contain at least two columns, to allow multi-modal sampling.'])
end
for j=1:size(xparams,2)
mode(j).m=xparams(:,j);
end
posterior_sampler_options.mode = mode;
posterior_sampler_options.rotated = 1;
posterior_sampler_options.WR=[];
end
case 'hssmc'
% default options
posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.hssmc);
% user defined options
if ~isempty(options_.posterior_sampler_options.sampling_opt)
options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
for i=1:rows(options_list)
switch options_list{i,1}
case 'target'
posterior_sampler_options.target = options_list{i,2};
case 'steps'
posterior_sampler_options.steps = options_list{i,2};
case 'scale'
posterior_sampler_options.scale = options_list{i,2};
case 'particles'
posterior_sampler_options.particles = options_list{i,2};
case 'lambda'
posterior_sampler_options.lambda = options_list{i,2};
otherwise
warning(['hssmc: Unknown option (' options_list{i,1} ')!'])
end
end
end
options_.mode_compute = 0;
options_.cova_compute = 0;
options_.mh_replic = 0;
options_.mh_posterior_mode_estimation = false;
case 'dsmh'
% default options
posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.dsmh);
% user defined options
if ~isempty(options_.posterior_sampler_options.sampling_opt)
options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
for i=1:rows(options_list)
switch options_list{i,1}
case 'proposal_distribution'
if ~(strcmpi(options_list{i,2}, 'rand_multivariate_student') || ...
strcmpi(options_list{i,2}, 'rand_multivariate_normal'))
error(['initial_estimation_checks:: the proposal_distribution option to estimation takes either ' ...
'rand_multivariate_student or rand_multivariate_normal as options']);
else
posterior_sampler_options.proposal_distribution=options_list{i,2};
end
case 'student_degrees_of_freedom'
if options_list{i,2} <= 0
error('initial_estimation_checks:: the student_degrees_of_freedom takes a positive integer argument');
else
posterior_sampler_options.student_degrees_of_freedom=options_list{i,2};
end
case 'save_tmp_file'
posterior_sampler_options.save_tmp_file = options_list{i,2};
case 'number_of_particles'
posterior_sampler_options.particles = options_list{i,2};
otherwise
warning(['rwmh_sampler: Unknown option (' options_list{i,1} ')!'])
end
end end
end end
if ~isempty(posterior_sampler_options.mode_files) % multimodal case options_.mode_compute = 0;
modes = posterior_sampler_options.mode_files; % these can be also mean files from previous parallel slice chains options_.cova_compute = 0;
load(modes, 'xparams') options_.mh_replic = 0;
if size(xparams,2)<2 options_.mh_posterior_mode_estimation = true;
error(['check_posterior_sampler_options:: Variable xparams loaded in file <' modes '> has size [' int2str(size(xparams,1)) 'x' int2str(size(xparams,2)) ']: it must contain at least two columns, to allow multi-modal sampling.'])
end otherwise
for j=1:size(xparams,2) error('check_posterior_sampler_options:: Unknown posterior_sampling_method option %s ',posterior_sampler_options.posterior_sampling_method);
mode(j).m=xparams(:,j);
end
posterior_sampler_options.mode = mode;
posterior_sampler_options.rotated = 1;
posterior_sampler_options.WR=[];
end end
otherwise return
error('check_posterior_sampler_options:: Unknown posterior_sampling_method option %s ',posterior_sampler_options.posterior_sampling_method);
end
return
end end
% here are all samplers requiring a proposal distribution % here are all samplers requiring a proposal distribution
if ~strcmp(posterior_sampler_options.posterior_sampling_method,'slice') if ~strcmp(posterior_sampler_options.posterior_sampling_method,'slice')
if ~options_.cova_compute && ~(options_.load_mh_file && posterior_sampler_options.use_mh_covariance_matrix) if ~options_.cova_compute && ~(options_.load_mh_file && posterior_sampler_options.use_mh_covariance_matrix)
if strcmp('hessian',options_.MCMC_jumping_covariance) if strcmp('hessian',options_.MCMC_jumping_covariance)
skipline() skipline()
disp('check_posterior_sampler_options:: I cannot start the MCMC because the Hessian of the posterior kernel at the mode was not computed') disp('check_posterior_sampler_options:: I cannot start the MCMC because the Hessian of the posterior kernel at the mode was not computed')

View File

@ -1,23 +1,19 @@
function [posterior_mean,posterior_covariance,posterior_mode,posterior_kernel_at_the_mode] = compute_mh_covariance_matrix(bayestopt_,fname,dname,outputFolderName) function [mean, covariance, mode, kernel_at_the_mode] = compute_mh_covariance_matrix(names, fname, dname, outputFolderName)
% function [posterior_mean,posterior_covariance,posterior_mode,posterior_kernel_at_the_mode] = compute_mh_covariance_matrix(bayestopt_,fname,dname,outputFolderName)
% Estimation of the posterior covariance matrix, posterior mean, posterior mode and evaluation of the posterior kernel at the % Estimation of the posterior covariance matrix, posterior mean, posterior mode and evaluation of the posterior kernel at the
% estimated mode, using the draws from a metropolis-hastings. The estimated posterior mode and covariance matrix are saved in % estimated mode, using posterior draws from a metropolis-hastings.
% a file <fname>_mh_mode.mat.
% %
% INPUTS % INPUTS
% o bayestopt_ [struct] characterizing priors % - names [cell] n×1 cell array of row char arrays, names of the estimated parameters.
% o fname [string] name of model % - fname [char] name of the model
% o dname [string] name of directory with metropolis folder % - dname [char] name of subfolder with output files
% o outputFolderName [string] name of directory to store results % - outputFolderName [char] name of directory to store results
% %
% OUTPUTS % OUTPUTS
% o posterior_mean [double] (n*1) vector, posterior expectation of the parameters. % - mean [double] n×1 vector, posterior expectation of the parameters.
% o posterior_covariance [double] (n*n) matrix, posterior covariance of the parameters (computed from previous metropolis hastings). % - covariance [double] n×n matrix, posterior covariance of the parameters.
% o posterior_mode [double] (n*1) vector, posterior mode of the parameters. % - mode [double] n×1 vector, posterior mode of the parameters.
% o posterior_kernel_at_the_mode [double] scalar. % - kernel_at_the_mode [double] scalar, value of the posterior kernel at the mode.
%
% SPECIAL REQUIREMENTS
% None.
% Copyright © 2006-2023 Dynare Team % Copyright © 2006-2023 Dynare Team
% %
@ -35,9 +31,7 @@ function [posterior_mean,posterior_covariance,posterior_mode,posterior_kernel_at
% %
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
if nargin < 4
outputFolderName = 'Output';
end
MetropolisFolder = CheckPath('metropolis',dname); MetropolisFolder = CheckPath('metropolis',dname);
BaseName = [MetropolisFolder filesep fname]; BaseName = [MetropolisFolder filesep fname];
@ -49,29 +43,24 @@ TotalNumberOfMhFiles = sum(record.MhDraws(:,2));
[nblck, n] = size(record.LastParameters); [nblck, n] = size(record.LastParameters);
posterior_kernel_at_the_mode = -Inf; kernel_at_the_mode = -Inf;
posterior_mean = zeros(n,1); mean = zeros(n,1);
posterior_mode = NaN(n,1); mode = NaN(n,1);
posterior_covariance = zeros(n,n); covariance = zeros(n,n);
offset = 0; offset = 0;
for b=1:nblck for b=1:nblck
first_line = FirstLine; first_line = FirstLine;
for n = FirstMhFile:TotalNumberOfMhFiles for n = FirstMhFile:TotalNumberOfMhFiles
load([ BaseName '_mh' int2str(n) '_blck' int2str(b) '.mat'],'x2','logpo2'); load([ BaseName '_mh' int2str(n) '_blck' int2str(b) '.mat'],'x2','logpo2');
[tmp,idx] = max(logpo2); [tmp, idx] = max(logpo2);
if tmp>posterior_kernel_at_the_mode if tmp>kernel_at_the_mode
posterior_kernel_at_the_mode = tmp; kernel_at_the_mode = tmp;
posterior_mode = x2(idx,:); mode = x2(idx,:);
end end
[posterior_mean,posterior_covariance,offset] = recursive_moments(posterior_mean,posterior_covariance,x2(first_line:end,:),offset); [mean, covariance, offset] = recursive_moments(mean, covariance, x2(first_line:end,:), offset);
first_line = 1; first_line = 1;
end end
end end
xparam1 = posterior_mode'; mode = transpose(mode);
hh = inv(posterior_covariance);
fval = posterior_kernel_at_the_mode;
parameter_names = bayestopt_.name;
save([dname filesep outputFolderName filesep fname '_mh_mode.mat'],'xparam1','hh','fval','parameter_names');

View File

@ -0,0 +1,65 @@
function [mu, covariance, mode, kernel_at_the_mode] = compute_posterior_covariance_matrix(names, fname, dname, options_, outputFolderName)
% Estimation of the posterior covariance matrix, posterior mean, posterior mode and evaluation of the posterior kernel at the
% estimated mode, using posterior draws from a metropolis-hastings. The estimated posterior mode and covariance matrix are saved in
% a file <fname>_mh_mode.mat, hssmc_mode.mat or dsmh__mode.mat under <dname>/<outputFolderName>/.
%
% INPUTS
% - names [cell] n×1 cell array of row char arrays, names of the estimated parameters.
% - fname [char] name of the model
% - dname [char] name of subfolder with output files
% - outputFolderName [char] name of directory to store results
%
% OUTPUTS
% - mean [double] n×1 vector, posterior expectation of the parameters.
% - covariance [double] n×n matrix, posterior covariance of the parameters.
% - mode [double] n×1 vector, posterior mode of the parameters.
% - kernel_at_the_mode [double] scalar, value of the posterior kernel at the mode.
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
if nargin<5
outputFolderName = 'Output';
end
if ishssmc(options_)
% Load draws from the posterior distribution
pfiles = dir(sprintf('%s/hssmc/particles-*.mat', dname));
posterior = load(sprintf('%s/hssmc/particles-%u-%u.mat', dname, length(pfiles), length(pfiles)));
% Get the posterior mode
[kernel_at_the_mode, id] = max(posterior.tlogpostkernel);
mode = posterior.particles(:,id);
% Compute the posterior mean
mu = sum(posterior.particles, 2)/length(posterior.tlogpostkernel);
% Compute the posterior covariance
covariance = (posterior.particles-mu)*(posterior.particles-mu)'/length(posterior.tlogpostkernel);
else
[mu, covariance, mode, kernel_at_the_mode] = compute_mh_covariance_matrix(names, fname, dname, outputFolderName);
end
xparam1 = mode;
hh = inv(covariance);
fval = kernel_at_the_mode;
parameter_names = names;
if ishssmc(options_)
save(sprintf('%s/%s/hssmc_mode.mat', dname, outputFolderName), 'xparam1', 'hh', 'fval', 'parameter_names');
else
save(sprintf('%s/%s/%s_mh_mode.mat', dname, outputFolderName, fname), 'xparam1', 'hh', 'fval', 'parameter_names');
end

View File

@ -79,7 +79,7 @@ for jj = 1:npar
par_name_temp = get_the_name(jj, options_.TeX, M_, estim_params_, options_.varobs); par_name_temp = get_the_name(jj, options_.TeX, M_, estim_params_, options_.varobs);
param_name = vertcat(param_name, par_name_temp); param_name = vertcat(param_name, par_name_temp);
end end
Draws = GetAllPosteriorDraws(M_.dname, M_.fname, jj, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck); Draws = GetAllPosteriorDraws(options_, M_.dname, M_.fname, jj, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck);
Draws = reshape(Draws, [NumberOfDraws nblck]); Draws = reshape(Draws, [NumberOfDraws nblck]);
Nc = min(1000, NumberOfDraws/2); Nc = min(1000, NumberOfDraws/2);
for ll = 1:nblck for ll = 1:nblck

View File

@ -451,6 +451,7 @@ options_.nk = 1;
options_.noconstant = false; options_.noconstant = false;
options_.nodiagnostic = false; options_.nodiagnostic = false;
options_.mh_posterior_mode_estimation = false; options_.mh_posterior_mode_estimation = false;
options_.smc_posterior_mode_estimation = false;
options_.prefilter = 0; options_.prefilter = 0;
options_.presample = 0; options_.presample = 0;
options_.prior_trunc = 1e-10; options_.prior_trunc = 1e-10;
@ -463,7 +464,7 @@ options_.use_mh_covariance_matrix = false;
options_.gradient_method = 2; %used by csminwel and newrat options_.gradient_method = 2; %used by csminwel and newrat
options_.gradient_epsilon = 1e-6; %used by csminwel and newrat options_.gradient_epsilon = 1e-6; %used by csminwel and newrat
options_.posterior_sampler_options.sampling_opt = []; %extended set of options for individual posterior samplers options_.posterior_sampler_options.sampling_opt = []; %extended set of options for individual posterior samplers
% Random Walk Metropolis-Hastings % Random Walk Metropolis-Hastings
options_.posterior_sampler_options.posterior_sampling_method = 'random_walk_metropolis_hastings'; options_.posterior_sampler_options.posterior_sampling_method = 'random_walk_metropolis_hastings';
options_.posterior_sampler_options.rwmh.proposal_distribution = 'rand_multivariate_normal'; options_.posterior_sampler_options.rwmh.proposal_distribution = 'rand_multivariate_normal';
options_.posterior_sampler_options.rwmh.student_degrees_of_freedom = 3; options_.posterior_sampler_options.rwmh.student_degrees_of_freedom = 3;
@ -491,23 +492,19 @@ options_.posterior_sampler_options.imh.proposal_distribution = 'rand_multivariat
options_.posterior_sampler_options.imh.use_mh_covariance_matrix=0; options_.posterior_sampler_options.imh.use_mh_covariance_matrix=0;
options_.posterior_sampler_options.imh.save_tmp_file=0; options_.posterior_sampler_options.imh.save_tmp_file=0;
% Herbst and Schorfeide SMC Sampler % Herbst and Schorfeide SMC Sampler
%options_.posterior_sampler = 'Herbst_Schorfheide' ; options_.posterior_sampler_options.hssmc.steps= 25;
options_.posterior_sampler_options.HSsmc.nphi= 25 ; options_.posterior_sampler_options.hssmc.lambda = 2;
options_.posterior_sampler_options.HSsmc.lambda = 2 ; options_.posterior_sampler_options.hssmc.particles = 20000;
options_.posterior_sampler_options.HSsmc.nparticles = 20000 ; options_.posterior_sampler_options.hssmc.scale = 0.5;
options_.posterior_sampler_options.HSsmc.c = 0.5 ; options_.posterior_sampler_options.hssmc.acpt = 1.00;
options_.posterior_sampler_options.HSsmc.acpt = 0.25 ; options_.posterior_sampler_options.hssmc.target = 0.25;
options_.posterior_sampler_options.HSsmc.trgt = 0.25 ;
options_.posterior_sampler_options.HSsmc.option_mutation = 1 ;
options_.posterior_sampler_options.HSsmc.alp = .9 ;
% DSMH: Dynamic Striated Metropolis-Hastings algorithm % DSMH: Dynamic Striated Metropolis-Hastings algorithm
%options_.posterior_sampler = 'DSMH' ;
options_.posterior_sampler_options.dsmh.H = 25 ; options_.posterior_sampler_options.dsmh.H = 25 ;
options_.posterior_sampler_options.dsmh.N = 20 ; options_.posterior_sampler_options.dsmh.N = 20 ;
options_.posterior_sampler_options.dsmh.G = 10 ; options_.posterior_sampler_options.dsmh.G = 10 ;
options_.posterior_sampler_options.dsmh.K = 50 ; options_.posterior_sampler_options.dsmh.K = 50 ;
options_.posterior_sampler_options.dsmh.lambda1 = 0.1 ; options_.posterior_sampler_options.dsmh.lambda1 = 0.1 ;
options_.posterior_sampler_options.dsmh.nparticles = 20000 ; options_.posterior_sampler_options.dsmh.particles = 20000 ;
options_.posterior_sampler_options.dsmh.alpha0 = 0.2 ; options_.posterior_sampler_options.dsmh.alpha0 = 0.2 ;
options_.posterior_sampler_options.dsmh.alpha1 = 0.3 ; options_.posterior_sampler_options.dsmh.alpha1 = 0.3 ;
options_.posterior_sampler_options.dsmh.tau = 10 ; options_.posterior_sampler_options.dsmh.tau = 10 ;

View File

@ -17,4 +17,4 @@ function dprintf(str, varargin)
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
disp(sprintf(str, varargin{:})); disp(sprintf(str, varargin{:}));

View File

@ -51,6 +51,9 @@ p = {'/../contrib/ms-sbvar/TZcode/MatlabFiles/' ; ...
'/discretionary_policy/' ; ... '/discretionary_policy/' ; ...
'/distributions/' ; ... '/distributions/' ; ...
'/ep/' ; ... '/ep/' ; ...
'/estimation/'; ...
'/estimation/smc/'; ...
'/estimation/resampler/'; ...
'/gsa/' ; ... '/gsa/' ; ...
'/kalman/' ; ... '/kalman/' ; ...
'/kalman/likelihood' ; ... '/kalman/likelihood' ; ...

View File

@ -31,6 +31,14 @@ function dynare_estimation_1(var_list_,dname)
global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info
if issmc(options_)
options_.mode_compute = 0;
options_.mh_replic = 0;
options_.mh_recover = false;
options_.load_mh_file = false;
options_.load_results_after_load_mh = false;
end
dispString = 'Estimation::mcmc'; dispString = 'Estimation::mcmc';
if ~exist([M_.dname filesep 'Output'],'dir') if ~exist([M_.dname filesep 'Output'],'dir')
@ -88,7 +96,9 @@ if options_.order > 1
end end
end end
%% set objective function %
% set objective function
%
if ~options_.dsge_var if ~options_.dsge_var
if options_.particle.status if options_.particle.status
objective_function = str2func('non_linear_dsge_likelihood'); objective_function = str2func('non_linear_dsge_likelihood');
@ -147,7 +157,10 @@ if ~isempty(estim_params_)
M_ = set_all_parameters(xparam1,estim_params_,M_); M_ = set_all_parameters(xparam1,estim_params_,M_);
end end
%% perform initial estimation checks; %
% perform initial estimation checks;
%
try try
oo_ = initial_estimation_checks(objective_function,xparam1,dataset_,dataset_info,M_,estim_params_,options_,bayestopt_,bounds,oo_); oo_ = initial_estimation_checks(objective_function,xparam1,dataset_,dataset_info,M_,estim_params_,options_,bayestopt_,bounds,oo_);
catch % if check fails, provide info on using calibration if present catch % if check fails, provide info on using calibration if present
@ -164,8 +177,11 @@ catch % if check fails, provide info on using calibration if present
rethrow(e); rethrow(e);
end end
%% Run smoother if no estimation or mode-finding are requested %
if isequal(options_.mode_compute,0) && isempty(options_.mode_file) && ~options_.mh_posterior_mode_estimation % Run smoother if no estimation or mode-finding are requested
%
if isequal(options_.mode_compute,0) && isempty(options_.mode_file) && ~options_.mh_posterior_mode_estimation && ~issmc(options_)
if options_.order==1 && ~options_.particle.status if options_.order==1 && ~options_.particle.status
if options_.smoother if options_.smoother
if options_.occbin.smoother.status && options_.occbin.smoother.inversion_filter if options_.occbin.smoother.status && options_.occbin.smoother.inversion_filter
@ -210,11 +226,11 @@ if isequal(options_.mode_compute,0) && isempty(options_.mode_file) && ~options_.
end end
end end
%% Estimation of the posterior mode or likelihood mode %
% Estimation of the posterior mode or likelihood mode
%
if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation && ~issmc(options_)
if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
optimizer_vec = [options_.mode_compute;num2cell(options_.additional_optimizer_steps)]; optimizer_vec = [options_.mode_compute;num2cell(options_.additional_optimizer_steps)];
for optim_iter = 1:length(optimizer_vec) for optim_iter = 1:length(optimizer_vec)
current_optimizer = optimizer_vec{optim_iter}; current_optimizer = optimizer_vec{optim_iter};
@ -238,7 +254,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
ana_deriv_old = options_.analytic_derivation; ana_deriv_old = options_.analytic_derivation;
options_.analytic_derivation = 2; options_.analytic_derivation = 2;
[~,~,~,~,hh] = feval(objective_function,xparam1, ... [~,~,~,~,hh] = feval(objective_function,xparam1, ...
dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state); dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
options_.analytic_derivation = ana_deriv_old; options_.analytic_derivation = ana_deriv_old;
elseif ~isnumeric(current_optimizer) || ~(isequal(current_optimizer,5) && newratflag~=1 && strcmp(func2str(objective_function),'dsge_likelihood')) elseif ~isnumeric(current_optimizer) || ~(isequal(current_optimizer,5) && newratflag~=1 && strcmp(func2str(objective_function),'dsge_likelihood'))
% enter here if i) not mode_compute_5, ii) if mode_compute_5 and newratflag==1; % enter here if i) not mode_compute_5, ii) if mode_compute_5 and newratflag==1;
@ -292,16 +308,19 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
end end
end end
if ~options_.mh_posterior_mode_estimation && options_.cova_compute if ~options_.mh_posterior_mode_estimation && options_.cova_compute && ~issmc(options_)
check_hessian_at_the_mode(hh, xparam1, M_, estim_params_, options_, bounds); check_hessian_at_the_mode(hh, xparam1, M_, estim_params_, options_, bounds);
end end
%% create mode_check_plots %
if options_.mode_check.status && ~options_.mh_posterior_mode_estimation % create mode_check_plots
%
if options_.mode_check.status && ~options_.mh_posterior_mode_estimation && ~issmc(options_)
ana_deriv_old = options_.analytic_derivation; ana_deriv_old = options_.analytic_derivation;
options_.analytic_derivation = 0; options_.analytic_derivation = 0;
mode_check(objective_function,xparam1,hh,options_,M_,estim_params_,bayestopt_,bounds,false,... mode_check(objective_function,xparam1,hh,options_,M_,estim_params_,bayestopt_,bounds,false,...
dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state); dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
options_.analytic_derivation = ana_deriv_old; options_.analytic_derivation = ana_deriv_old;
end end
@ -309,43 +328,38 @@ oo_.posterior.optimization.mode = [];
oo_.posterior.optimization.Variance = []; oo_.posterior.optimization.Variance = [];
oo_.posterior.optimization.log_density=[]; oo_.posterior.optimization.log_density=[];
invhess=[]; invhess = [];
if ~options_.mh_posterior_mode_estimation
oo_.posterior.optimization.mode = xparam1; if ~issmc(options_)
if exist('fval','var') if ~options_.mh_posterior_mode_estimation
oo_.posterior.optimization.log_density=-fval; oo_.posterior.optimization.mode = xparam1;
if exist('fval','var')
oo_.posterior.optimization.log_density=-fval;
end
if options_.cova_compute
hsd = sqrt(diag(hh));
invhess = inv(hh./(hsd*hsd'))./(hsd*hsd');
stdh = sqrt(diag(invhess));
oo_.posterior.optimization.Variance = invhess;
end
else
variances = bayestopt_.p2.*bayestopt_.p2;
idInf = isinf(variances);
variances(idInf) = 1;
invhess = options_.mh_posterior_mode_estimation*diag(variances);
xparam1 = bayestopt_.p5;
idNaN = isnan(xparam1);
xparam1(idNaN) = bayestopt_.p1(idNaN);
outside_bound_pars=find(xparam1 < bounds.lb | xparam1 > bounds.ub);
xparam1(outside_bound_pars) = bayestopt_.p1(outside_bound_pars);
end end
if options_.cova_compute
hsd = sqrt(diag(hh));
invhess = inv(hh./(hsd*hsd'))./(hsd*hsd');
stdh = sqrt(diag(invhess));
oo_.posterior.optimization.Variance = invhess;
end
else
variances = bayestopt_.p2.*bayestopt_.p2;
idInf = isinf(variances);
variances(idInf) = 1;
invhess = options_.mh_posterior_mode_estimation*diag(variances);
xparam1 = bayestopt_.p5;
idNaN = isnan(xparam1);
xparam1(idNaN) = bayestopt_.p1(idNaN);
outside_bound_pars=find(xparam1 < bounds.lb | xparam1 > bounds.ub);
xparam1(outside_bound_pars) = bayestopt_.p1(outside_bound_pars);
end end
if ~options_.cova_compute if ~options_.cova_compute
stdh = NaN(length(xparam1),1); stdh = NaN(length(xparam1),1);
end end
if options_.particle.status && isfield(options_.particle,'posterior_sampler') if ~issmc(options_) && any(bayestopt_.pshape > 0) && ~options_.mh_posterior_mode_estimation
if strcmpi(options_.particle.posterior_sampler,'Herbst_Schorfheide')
Herbst_Schorfheide_sampler(objective_function,xparam1,bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state)
elseif strcmpi(options_.particle.posterior_sampler,'DSMH')
DSMH_sampler(objective_function,xparam1,bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state)
end
end
if any(bayestopt_.pshape > 0) && ~options_.mh_posterior_mode_estimation
% display results table and store parameter estimates and standard errors in results % display results table and store parameter estimates and standard errors in results
oo_ = display_estimation_results_table(xparam1, stdh, M_, options_, estim_params_, bayestopt_, oo_, prior_dist_names, 'Posterior', 'posterior'); oo_ = display_estimation_results_table(xparam1, stdh, M_, options_, estim_params_, bayestopt_, oo_, prior_dist_names, 'Posterior', 'posterior');
% Laplace approximation to the marginal log density: % Laplace approximation to the marginal log density:
@ -366,56 +380,75 @@ if any(bayestopt_.pshape > 0) && ~options_.mh_posterior_mode_estimation
[~,~,~,~,~,~,~,oo_.dsge_var.posterior_mode.PHI_tilde,oo_.dsge_var.posterior_mode.SIGMA_u_tilde,oo_.dsge_var.posterior_mode.iXX,oo_.dsge_var.posterior_mode.prior] =... [~,~,~,~,~,~,~,oo_.dsge_var.posterior_mode.PHI_tilde,oo_.dsge_var.posterior_mode.SIGMA_u_tilde,oo_.dsge_var.posterior_mode.iXX,oo_.dsge_var.posterior_mode.prior] =...
feval(objective_function,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state); feval(objective_function,xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
end end
elseif ~issmc(options_) && ~any(bayestopt_.pshape > 0) && ~options_.mh_posterior_mode_estimation
elseif ~any(bayestopt_.pshape > 0) && ~options_.mh_posterior_mode_estimation
oo_=display_estimation_results_table(xparam1, stdh, M_, options_, estim_params_, bayestopt_, oo_, prior_dist_names, 'Maximum Likelihood', 'mle'); oo_=display_estimation_results_table(xparam1, stdh, M_, options_, estim_params_, bayestopt_, oo_, prior_dist_names, 'Maximum Likelihood', 'mle');
end end
invhess = set_mcmc_jumping_covariance(invhess, nx, options_.MCMC_jumping_covariance, bayestopt_, 'dynare_estimation_1'); if ~issmc(options_)
invhess = set_mcmc_jumping_covariance(invhess, nx, options_.MCMC_jumping_covariance, bayestopt_, 'dynare_estimation_1');
end
if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ... %
(any(bayestopt_.pshape >0 ) && options_.load_mh_file) %% not ML estimation % Run SMC sampler.
%reset bounds as lb and ub must only be operational during mode-finding %
bounds = set_mcmc_prior_bounds(xparam1, bayestopt_, options_, 'dynare_estimation_1');
% Tunes the jumping distribution's scale parameter if ishssmc(options_)
if options_.mh_tune_jscale.status [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options([], M_.fname, M_.dname, options_, bounds, bayestopt_);
if strcmp(options_.posterior_sampler_options.posterior_sampling_method, 'random_walk_metropolis_hastings') options_.posterior_sampler_options.current_options = posterior_sampler_options;
options_.mh_jscale = tune_mcmc_mh_jscale_wrapper(invhess, options_, M_, objective_function, xparam1, bounds,... oo_.MarginalDensity.hssmc = hssmc(objective_function, bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_);
dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds, oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state); elseif isdsmh(options_)
bayestopt_.jscale(:) = options_.mh_jscale; dsmh(objective_function, xparam1, bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_)
fprintf('mh_jscale has been set equal to %s\n', num2str(options_.mh_jscale)); end
else
warning('mh_tune_jscale is only available with Random Walk Metropolis Hastings!') %
% Run MCMC and compute posterior statistics.
%
if issmc(options_) || (any(bayestopt_.pshape>0) && options_.mh_replic) || (any(bayestopt_.pshape>0) && options_.load_mh_file) % not ML estimation
if ~issmc(options_)
% Reset bounds as lb and ub must only be operational during mode-finding
bounds = set_mcmc_prior_bounds(xparam1, bayestopt_, options_, 'dynare_estimation_1');
% Tune the jumping distribution's scale parameter
if options_.mh_tune_jscale.status
if strcmp(options_.posterior_sampler_options.posterior_sampling_method, 'random_walk_metropolis_hastings')
options_.mh_jscale = tune_mcmc_mh_jscale_wrapper(invhess, options_, M_, objective_function, xparam1, bounds,...
dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds, oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
bayestopt_.jscale(:) = options_.mh_jscale;
fprintf('mh_jscale has been set equal to %s\n', num2str(options_.mh_jscale));
else
warning('mh_tune_jscale is only available with Random Walk Metropolis Hastings!')
end
end end
end % Run MCMC
% runs MCMC if options_.mh_replic || options_.load_mh_file
if options_.mh_replic || options_.load_mh_file posterior_sampler_options = options_.posterior_sampler_options.current_options;
posterior_sampler_options = options_.posterior_sampler_options.current_options; posterior_sampler_options.invhess = invhess;
posterior_sampler_options.invhess = invhess; [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options(posterior_sampler_options, M_.fname, M_.dname, options_, bounds, bayestopt_);
[posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options(posterior_sampler_options, M_.fname, M_.dname, options_, bounds, bayestopt_); % store current options in global
% store current options in global options_.posterior_sampler_options.current_options = posterior_sampler_options;
options_.posterior_sampler_options.current_options = posterior_sampler_options; if options_.mh_replic
if options_.mh_replic ana_deriv_old = options_.analytic_derivation;
ana_deriv_old = options_.analytic_derivation; options_.analytic_derivation = 0;
options_.analytic_derivation = 0; posterior_sampler(objective_function,posterior_sampler_options.proposal_distribution,xparam1,posterior_sampler_options,bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,dispString);
posterior_sampler(objective_function,posterior_sampler_options.proposal_distribution,xparam1,posterior_sampler_options,bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,dispString); options_.analytic_derivation = ana_deriv_old;
options_.analytic_derivation = ana_deriv_old; end
end end
% Discard first mh_drop percent of the draws:
CutSample(M_, options_, dispString);
end end
%% Here I discard first mh_drop percent of the draws: if options_.mh_posterior_mode_estimation || (issmc(options_) && options_.smc_posterior_mode_estimation)
CutSample(M_, options_, dispString); [~, covariance, posterior_mode, ~] = compute_posterior_covariance_matrix(bayestopt_.name, M_.fname, M_.dname, options_);
if options_.mh_posterior_mode_estimation oo_ = fill_mh_mode(posterior_mode, sqrt(diag(covariance)), M_, options_, estim_params_, oo_, 'posterior');
[~,~,posterior_mode,~] = compute_mh_covariance_matrix(bayestopt_,M_.fname,M_.dname);
oo_=fill_mh_mode(posterior_mode',NaN(length(posterior_mode),1),M_,options_,estim_params_,bayestopt_,oo_,'posterior');
%reset qz_criterium %reset qz_criterium
options_.qz_criterium=qz_criterium_old; options_.qz_criterium = qz_criterium_old;
return return
else else
%get stored results if required % Get stored results if required
if options_.load_mh_file && options_.load_results_after_load_mh if ~issmc(options_) && options_.load_mh_file && options_.load_results_after_load_mh
oo_load_mh=load([M_.dname filesep 'Output' filesep M_.fname '_results'],'oo_'); oo_load_mh = load(sprintf('%s/%s/%s_results', M_.dname, 'Output', M_.fname), 'oo_');
end end
if ~options_.nodiagnostic % Compute MCMC convergence diagnostics
if ~issmc(options_) && ~options_.nodiagnostic
if (options_.mh_replic>0 || (options_.load_mh_file && ~options_.load_results_after_load_mh)) if (options_.mh_replic>0 || (options_.load_mh_file && ~options_.load_results_after_load_mh))
oo_= mcmc_diagnostics(options_, estim_params_, M_,oo_); oo_= mcmc_diagnostics(options_, estim_params_, M_,oo_);
elseif options_.load_mh_file && options_.load_results_after_load_mh elseif options_.load_mh_file && options_.load_results_after_load_mh
@ -424,9 +457,11 @@ if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ...
end end
end end
end end
%% Estimation of the marginal density from the Mh draws: % Estimation of the marginal density from the Mh draws:
if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) if ishssmc(options_) || options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
[~,oo_] = marginal_density(M_, options_, estim_params_, oo_, bayestopt_); if ~issmc(options_)
[~, oo_] = marginal_density(M_, options_, estim_params_, oo_, bayestopt_);
end
% Store posterior statistics by parameter name % Store posterior statistics by parameter name
oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bayestopt_, oo_, prior_dist_names); oo_ = GetPosteriorParametersStatistics(estim_params_, M_, options_, bayestopt_, oo_, prior_dist_names);
if ~options_.nograph if ~options_.nograph
@ -435,13 +470,13 @@ if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ...
% Store posterior mean in a vector and posterior variance in % Store posterior mean in a vector and posterior variance in
% a matrix % a matrix
[oo_.posterior.metropolis.mean,oo_.posterior.metropolis.Variance] ... [oo_.posterior.metropolis.mean,oo_.posterior.metropolis.Variance] ...
= GetPosteriorMeanVariance(M_,options_.mh_drop); = GetPosteriorMeanVariance(options_, M_);
elseif options_.load_mh_file && options_.load_results_after_load_mh elseif options_.load_mh_file && options_.load_results_after_load_mh
%% load fields from previous MCMC run stored in results-file % load fields from previous MCMC run stored in results-file
field_names={'posterior_mode','posterior_std_at_mode',...% fields set by marginal_density field_names={'posterior_mode','posterior_std_at_mode',...% fields set by marginal_density
'posterior_mean','posterior_hpdinf','posterior_hpdsup','posterior_median','posterior_variance','posterior_std','posterior_deciles','posterior_density',...% fields set by GetPosteriorParametersStatistics 'posterior_mean','posterior_hpdinf','posterior_hpdsup','posterior_median','posterior_variance','posterior_std','posterior_deciles','posterior_density',...% fields set by GetPosteriorParametersStatistics
'prior_density',...%fields set by PlotPosteriorDistributions 'prior_density',...%fields set by PlotPosteriorDistributions
}; };
for field_iter=1:size(field_names,2) for field_iter=1:size(field_names,2)
if isfield(oo_load_mh.oo_,field_names{1,field_iter}) if isfield(oo_load_mh.oo_,field_names{1,field_iter})
oo_.(field_names{1,field_iter})=oo_load_mh.oo_.(field_names{1,field_iter}); oo_.(field_names{1,field_iter})=oo_load_mh.oo_.(field_names{1,field_iter});
@ -456,7 +491,9 @@ if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ...
oo_.posterior.metropolis=oo_load_mh.oo_.posterior.metropolis; oo_.posterior.metropolis=oo_load_mh.oo_.posterior.metropolis;
end end
end end
[error_flag,~,options_]= metropolis_draw(1,options_,estim_params_,M_); if ~issmc(options_)
[error_flag, ~, options_]= metropolis_draw(1, options_, estim_params_, M_);
end
if ~(~isempty(options_.sub_draws) && options_.sub_draws==0) if ~(~isempty(options_.sub_draws) && options_.sub_draws==0)
if options_.bayesian_irf if options_.bayesian_irf
if error_flag if error_flag
@ -499,9 +536,9 @@ if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ...
error('%s: Particle Smoothers are not yet implemented.',dispString) error('%s: Particle Smoothers are not yet implemented.',dispString)
end end
end end
else else
fprintf('%s: sub_draws was set to 0. Skipping posterior computations.',dispString); fprintf('%s: sub_draws was set to 0. Skipping posterior computations.',dispString);
end end
xparam1 = get_posterior_parameters('mean',M_,estim_params_,oo_,options_); xparam1 = get_posterior_parameters('mean',M_,estim_params_,oo_,options_);
M_ = set_all_parameters(xparam1,estim_params_,M_); M_ = set_all_parameters(xparam1,estim_params_,M_);
end end
@ -517,7 +554,7 @@ end
%Run and store classical smoother if needed %Run and store classical smoother if needed
if (~((any(bayestopt_.pshape > 0) && options_.mh_replic) || (any(bayestopt_.pshape> 0) && options_.load_mh_file)) ... if (~((any(bayestopt_.pshape > 0) && options_.mh_replic) || (any(bayestopt_.pshape> 0) && options_.load_mh_file)) ...
|| ~options_.smoother ) && ~options_.partial_information % to be fixed || ~options_.smoother ) && ~options_.partial_information % to be fixed
%% ML estimation, or posterior mode without Metropolis-Hastings or Metropolis without Bayesian smoothed variables %% ML estimation, or posterior mode without Metropolis-Hastings or Metropolis without Bayesian smoothed variables
oo_=save_display_classical_smoother_results(xparam1,M_,oo_,options_,bayestopt_,dataset_,dataset_info,estim_params_); oo_=save_display_classical_smoother_results(xparam1,M_,oo_,options_,bayestopt_,dataset_,dataset_info,estim_params_);
end end

View File

@ -1,8 +1,6 @@
function [dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_,bayestopt_, bounds] = dynare_estimation_init(var_list_, dname, gsa_flag, M_, options_, oo_, estim_params_, bayestopt_) function [dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_,bayestopt_, bounds] = dynare_estimation_init(var_list_, dname, gsa_flag, M_, options_, oo_, estim_params_, bayestopt_)
% function [dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_,bayestopt_, bounds] = dynare_estimation_init(var_list_, dname, gsa_flag, M_, options_, oo_, estim_params_, bayestopt_) % Performs initialization tasks before estimation or global sensitivity analysis
% performs initialization tasks before estimation or
% global sensitivity analysis
% %
% INPUTS % INPUTS
% var_list_: selected endogenous variables vector % var_list_: selected endogenous variables vector
@ -390,7 +388,7 @@ end
%set options for old interface from the ones for new interface %set options for old interface from the ones for new interface
if ~isempty(dataset_) if ~isempty(dataset_)
options_.nobs = dataset_.nobs; options_.nobs = dataset_.nobs;
if options_.endogenous_prior if options_.endogenous_prior
if ~isnan(dataset_info.missing.number_of_observations) && ~(dataset_info.missing.number_of_observations==0) %missing observations present if ~isnan(dataset_info.missing.number_of_observations) && ~(dataset_info.missing.number_of_observations==0) %missing observations present
if dataset_info.missing.no_more_missing_observations<dataset_.nobs-10 if dataset_info.missing.no_more_missing_observations<dataset_.nobs-10
fprintf('\ndynare_estimation_init: There are missing observations in the data.\n') fprintf('\ndynare_estimation_init: There are missing observations in the data.\n')
@ -537,15 +535,15 @@ end
if options_.occbin.smoother.status && options_.occbin.smoother.inversion_filter if options_.occbin.smoother.status && options_.occbin.smoother.inversion_filter
if ~isempty(options_.nk) if ~isempty(options_.nk)
fprintf('dynare_estimation_init: the inversion filter does not support filter_step_ahead. Disabling the option.\n') fprintf('dynare_estimation_init: the inversion filter does not support filter_step_ahead. Disabling the option.\n')
options_.nk=[]; options_.nk=[];
end end
if options_.filter_covariance if options_.filter_covariance
fprintf('dynare_estimation_init: the inversion filter does not support filter_covariance. Disabling the option.\n') fprintf('dynare_estimation_init: the inversion filter does not support filter_covariance. Disabling the option.\n')
options_.filter_covariance=false; options_.filter_covariance=false;
end end
if options_.smoothed_state_uncertainty if options_.smoothed_state_uncertainty
fprintf('dynare_estimation_init: the inversion filter does not support smoothed_state_uncertainty. Disabling the option.\n') fprintf('dynare_estimation_init: the inversion filter does not support smoothed_state_uncertainty. Disabling the option.\n')
options_.smoothed_state_uncertainty=false; options_.smoothed_state_uncertainty=false;
end end
end end

View File

@ -0,0 +1,45 @@
function indices = kitagawa(weights, noise)
% Return indices for resampling.
%
% INPUTS
% - weights [double] n×1 vector of partcles' weights.
% - noise [double] scalar, uniform random deviates in [0,1]
%
% OUTPUTS
% - indices [integer] n×1 vector of indices in [1:n]
% Copyright © 2022-2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
n= length(weights);
if nargin<2, noise = rand; end
indices = NaN(n, 1);
cweights = cumsum(weights);
wweights = (transpose(0:n-1)+noise)*(1.0/n);
j = 1;
for i=1:n
while wweights(i)>cweights(j)
j = j+1;
end
indices(i) = j;
end

View File

@ -1,5 +1,5 @@
function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) function dsmh(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. % Dynamic Striated Metropolis-Hastings algorithm.
% %
% INPUTS % INPUTS
@ -33,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 % Then the comments write here can be used for all the other pairs of
% parallel functions and also for management functions. % parallel functions and also for management functions.
% Copyright © 2006-2023 Dynare Team % Copyright © 2022-2023 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -50,14 +50,15 @@ function DSMH_sampler(TargetFun,xparam1,mh_bounds,dataset_,dataset_info,options_
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
opts = options_.posterior_sampler_options.dsmh;
lambda = exp(bsxfun(@minus,options_.posterior_sampler_options.dsmh.H,1:1:options_.posterior_sampler_options.dsmh.H)/(options_.posterior_sampler_options.dsmh.H-1)*log(options_.posterior_sampler_options.dsmh.lambda1)); lambda = exp(bsxfun(@minus,options_.posterior_sampler_options.dsmh.H,1:1:options_.posterior_sampler_options.dsmh.H)/(options_.posterior_sampler_options.dsmh.H-1)*log(options_.posterior_sampler_options.dsmh.lambda1));
c = 0.055 ; c = 0.055 ;
MM = int64(options_.posterior_sampler_options.dsmh.N*options_.posterior_sampler_options.dsmh.G/10) ; MM = int64(options_.posterior_sampler_options.dsmh.N*options_.posterior_sampler_options.dsmh.G/10) ;
% Step 0: Initialization of the sampler % Step 0: Initialization of the sampler
[ param, tlogpost_iminus1, loglik, bayestopt_] = ... [param, tlogpost_iminus1, loglik, bayestopt_] = ...
SMC_samplers_initialization(TargetFun, xparam1, mh_bounds, dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_,options_.posterior_sampler_options.dsmh.nparticles); smc_samplers_initialization(TargetFun, 'dsmh', opts.particles, mh_bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_);
ESS = zeros(options_.posterior_sampler_options.dsmh.H,1) ; ESS = zeros(options_.posterior_sampler_options.dsmh.H,1) ;
zhat = 1 ; zhat = 1 ;
@ -78,20 +79,17 @@ end
weights = exp(loglik*(lambda(end)-lambda(end-1))); weights = exp(loglik*(lambda(end)-lambda(end-1)));
weights = weights/sum(weights); weights = weights/sum(weights);
indx_resmpl = smc_resampling(weights,rand(1,1),options_.posterior_sampler_options.dsmh.nparticles); indx_resmpl = smc_resampling(weights,rand(1,1),options_.posterior_sampler_options.dsmh.particles);
distrib_param = param(:,indx_resmpl); distrib_param = param(:,indx_resmpl);
mean_xparam = mean(distrib_param,2); mean_xparam = mean(distrib_param,2);
npar = length(xparam1); npar = length(xparam1);
%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) ; lb95_xparam = zeros(npar,1) ;
ub95_xparam = zeros(npar,1) ; ub95_xparam = zeros(npar,1) ;
for i=1:npar for i=1:npar
temp = sortrows(distrib_param(i,:)') ; temp = sortrows(distrib_param(i,:)') ;
lb95_xparam(i) = temp(0.025*options_.posterior_sampler_options.dsmh.nparticles) ; lb95_xparam(i) = temp(0.025*options_.posterior_sampler_options.dsmh.particles) ;
ub95_xparam(i) = temp(0.975*options_.posterior_sampler_options.dsmh.nparticles) ; ub95_xparam(i) = temp(0.975*options_.posterior_sampler_options.dsmh.particles) ;
end end
TeX = options_.TeX; TeX = options_.TeX;
@ -130,9 +128,9 @@ for k=1:npar %min(nstar,npar-(plt-1)*nstar)
subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k)
%kk = (plt-1)*nstar+k; %kk = (plt-1)*nstar+k;
[name,texname] = get_the_name(k,TeX,M_,estim_params_,options_.varobs); [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_.varobs);
optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.posterior_sampler_options.dsmh.nparticles,bandwidth,kernel_function); optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.posterior_sampler_options.dsmh.particles,bandwidth,kernel_function);
[density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,... [density(:,1),density(:,2)] = kernel_density_estimate(distrib_param(k,:)',number_of_grid_points,...
options_.posterior_sampler_options.dsmh.nparticles,optimal_bandwidth,kernel_function); options_.posterior_sampler_options.dsmh.particles,optimal_bandwidth,kernel_function);
plot(density(:,1),density(:,2)); plot(density(:,1),density(:,2));
hold on hold on
if TeX if TeX

View File

@ -0,0 +1,136 @@
function mdd = hssmc(TargetFun, mh_bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_)
% Sequential Monte-Carlo sampler, Herbst and Schorfheide (JAE, 2014).
%
% INPUTS
% - TargetFun [char] string specifying the name of the objective function (posterior kernel).
% - xparam1 [double] p×1 vector of parameters to be estimated (initial values).
% - mh_bounds [double] p×2 matrix defining lower and upper bounds for the parameters.
% - dataset_ [dseries] sample
% - dataset_info [struct] informations about the dataset
% - options_ [struct] dynare's options
% - M_ [struct] model description
% - estim_params_ [struct] estimated parameters
% - bayestopt_ [struct] estimated parameters
% - oo_ [struct] outputs
%
% SPECIAL REQUIREMENTS
% None.
% Copyright © 2022-2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
smcopt = options_.posterior_sampler_options.current_options;
% Set location for the simulated particles.
SimulationFolder = CheckPath('hssmc', M_.dname);
% Define prior distribution
Prior = dprior(bayestopt_, options_.prior_trunc);
% Set function handle for the objective
eval(sprintf('%s = @(x) %s(x, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, mh_bounds, oo_.dr , oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state, []);', 'funobj', func2str(TargetFun)));
mlogit = @(x) .95 + .1/(1 + exp(-16*x)); % Update of the scale parameter
% Create the tempering schedule
phi = ((0:smcopt.steps-1)/(smcopt.steps-1)).^smcopt.lambda;
% Initialise the estimate of the marginal density of the data
mdd = .0;
% tuning for MH algorithms matrices
scl = zeros(smcopt.steps, 1); % scale parameter
ESS = zeros(smcopt.steps, 1); % ESS
acpt = zeros(smcopt.steps, 1); % average acceptance rate
% Initialization of the sampler (draws from the prior distribution with finite logged likelihood)
t0 = tic;
[particles, tlogpostkernel, loglikelihood] = ...
smc_samplers_initialization(funobj, 'hssmc', smcopt.particles, Prior, SimulationFolder, smcopt.steps);
tt = toc(t0);
dprintf('#Iter. lambda ESS Acceptance rate scale resample seconds')
dprintf('%3u %5.4f %9.5E %5.4f %4.3f %3s %5.2f', 1, 0, 0, 0, 0, 'no', tt)
weights = ones(smcopt.particles, 1)/smcopt.particles;
resampled_particle_swarm = false;
for i=2:smcopt.steps % Loop over the weight on the liklihood (phi)
weights = weights.*exp((phi(i)-phi(i-1))*loglikelihood);
sweight = sum(weights);
weights = weights/sweight;
mdd = mdd + log(sweight);
ESS(i) = 1.0/sum(weights.^2);
if (2*ESS(i) < smcopt.particles) % Resampling
resampled_particle_swarm = true;
iresample = kitagawa(weights);
particles = particles(:,iresample);
loglikelihood = loglikelihood(iresample);
tlogpostkernel = tlogpostkernel(iresample);
weights = ones(smcopt.particles, 1)/smcopt.particles;
end
smcopt.scale = smcopt.scale*mlogit(smcopt.acpt-smcopt.target); % Adjust the scale parameter
scl(i) = smcopt.scale; % Scale parameter (for the jumping distribution in MH mutation step).
mu = particles*weights; % Weighted average of the particles.
z = particles-mu;
R = z*(z'.*weights); % Weighted covariance matrix of the particles.
t0 = tic;
acpt_ = false(smcopt.particles, 1);
tlogpostkernel = tlogpostkernel + (phi(i)-phi(i-1))*loglikelihood;
[acpt_, particles, loglikelihood, tlogpostkernel] = ...
randomwalk(funobj, chol(R, 'lower'), mu, scl(i), phi(i), acpt_, Prior, particles, loglikelihood, tlogpostkernel);
smcopt.acpt = sum(acpt_)/smcopt.particles; % Acceptance rate.
tt = toc(t0);
acpt(i) = smcopt.acpt;
if resampled_particle_swarm
dprintf('%3u %5.4f %9.5E %5.4f %4.3f %3s %5.2f', i, phi(i), ESS(i), acpt(i), scl(i), 'yes', tt)
else
dprintf('%3u %5.4f %9.5E %5.4f %4.3f %3s %5.2f', i, phi(i), ESS(i), acpt(i), scl(i), 'no', tt)
end
if i==smcopt.steps
iresample = kitagawa(weights);
particles = particles(:,iresample);
end
save(sprintf('%s%sparticles-%u-%u.mat', SimulationFolder, filesep(), i, smcopt.steps), 'particles', 'tlogpostkernel', 'loglikelihood')
resampled_particle_swarm = false;
end
end
function [accept, particles, loglikelihood, tlogpostkernel] = randomwalk(funobj, RR, mu, scale, phi, accept, Prior, particles, loglikelihood, tlogpostkernel)
parfor j=1:size(particles, 2)
notvalid= true;
while notvalid
candidate = particles(:,j) + scale*(RR*randn(size(mu)));
if Prior.admissible(candidate)
[tlogpost, loglik] = tempered_likelihood(funobj, candidate, phi, Prior);
if isfinite(loglik)
notvalid = false;
if rand<exp(tlogpost-tlogpostkernel(j))
accept(j) = true ;
particles(:,j) = candidate;
loglikelihood(j) = loglik;
tlogpostkernel(j) = tlogpost;
end
end
end
end
end
end

View File

@ -1,7 +1,6 @@
function indx = smc_resampling(weights,noise,number) function bool = isdsmh(options_)
% function indx = smc_resampling(weights,noise,number)
% Copyright © 2022 Dynare Team % Copyright © 2023 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -18,13 +17,9 @@ function indx = smc_resampling(weights,noise,number)
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>. % along with Dynare. If not, see <https://www.gnu.org/licenses/>.
indx = zeros(number,1); bool = false;
cumweights = cumsum(weights); if isfield(options_, 'posterior_sampler_options')
randvec = (transpose(1:number)-1+noise(:))/number; if strcmp(options_.posterior_sampler_options.posterior_sampling_method, 'dsmh')
j = 1; bool = true;
for i=1:number
while (randvec(i)>cumweights(j))
j = j+1;
end
indx(i) = j;
end end
end

View File

@ -0,0 +1,25 @@
function bool = ishssmc(options_)
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
bool = false;
if isfield(options_, 'posterior_sampler_options')
if strcmp(options_.posterior_sampler_options.posterior_sampling_method, 'hssmc')
bool = true;
end
end

View File

@ -0,0 +1,81 @@
function [particles, tlogpostkernel, loglikelihood, SimulationFolder] = smc_samplers_initialization(funobj, sampler, n, Prior, SimulationFolder, nsteps)
% Initialize SMC samplers by drawing initial particles in the prior distribution.
%
% INPUTS
% - TargetFun [char] string specifying the name of the objective function (posterior kernel).
% - sampler [char] name of the sampler.
% - n [integer] scalar, number of particles.
% - mh_bounds [double] p×2 matrix defining lower and upper bounds for the estimated parameters.
% - dataset_ [dseries] sample
% - dataset_info [struct] informations about the dataset
% - options_ [struct] dynare's options
% - M_ [struct] model description
% - estim_params_ [struct] estimated parameters
% - bayestopt_ [struct] estimated parameters
% - oo_ [struct] outputs
%
% OUTPUTS
% - ix2 [double] p×n matrix of particles
% - ilogpo2 [double] n×1 vector of posterior kernel values for the particles
% - iloglik2 [double] n×1 vector of likelihood values for the particles
% - ModelName [string] name of the mod-file
% - MetropolisFolder [string] path to the Metropolis subfolder
% - bayestopt_ [structure] estimation options structure
%
% SPECIAL REQUIREMENTS
% None.
% Copyright © 2022-2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
dprintf('Estimation:%s: Initialization...', sampler)
% Delete old mat files storign particles if any...
matfiles = sprintf('%s%sparticles*.mat', SimulationFolder, filesep());
files = dir(matfiles);
if ~isempty(files)
delete(matfiles);
dprintf('Estimation:%s: Old %s-files successfully erased.', sampler, sampler)
end
% Simulate a pool of particles characterizing the prior distribution (with the additional constraint that the likelihood is finite)
set_dynare_seed('default');
dprintf('Estimation:%s: Searching for initial values...', sampler);
particles = zeros(Prior.length(), n);
tlogpostkernel = zeros(n, 1);
loglikelihood = zeros(n, 1);
t0 = tic;
parfor j=1:n
notvalid = true;
while notvalid
candidate = Prior.draw();
if Prior.admissible(candidate)
particles(:,j) = candidate;
[tlogpostkernel(j), loglikelihood(j)] = tempered_likelihood(funobj, candidate, 0.0, Prior);
if isfinite(loglikelihood(j)) % if returned log-density is Inf or Nan (penalized value)
notvalid = false;
end
end
end
end
tt = toc(t0);
save(sprintf('%s%sparticles-1-%u.mat', SimulationFolder, filesep(), nsteps), 'particles', 'tlogpostkernel', 'loglikelihood')
dprintf('Estimation:%s: Initial values found (%.2fs)', sampler, tt)
skipline()

View File

@ -0,0 +1,35 @@
function [tlogpostkernel,loglikelihood] = tempered_likelihood(postkernelfun, xparam, lambda, Prior)
% Evaluate tempered likelihood (posterior kernel)
%
% INPUTS
% - postkernelfun [handle] Function handle for the opposite of the posterior kernel.
% - xparam [double] n×1 vector of parameters.
% - lambda [double] scalar between 0 and 1, weight on the posterior kernel.
% - Prior [dprior] Prior specification.
%
% OUTPUTS
% - tlogpostkernel [double] scalar, value of the tempered posterior kernel.
% - loglikelihood [double] scalar, value of the log likelihood.
% Copyright © 2022-2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
logpostkernel = -postkernelfun(xparam);
logprior = Prior.density(xparam);
loglikelihood = logpostkernel-logprior;
tlogpostkernel = lambda*loglikelihood + logprior;

View File

@ -1,22 +1,22 @@
function oo_=fill_mh_mode(xparam1,stdh,M_,options_,estim_params_,bayestopt_,oo_, field_name) function oo_ = fill_mh_mode(xparam1, stdh, M_, options_, estim_params_, oo_, field_name)
%function oo_=fill_mh_mode(xparam1,stdh,M_,options_,estim_params_,bayestopt_,oo_, field_name)
% Fill oo_.<field_name>.mode and oo_.<field_name>.std_at_mode
% %
% INPUTS % INPUTS
% o xparam1 [double] (p*1) vector of estimate parameters. % - xparam1 [double] p×1 vector, estimated posterior mode.
% o stdh [double] (p*1) vector of estimate parameters. % - stdh [double] p×1 vector, estimated posterior standard deviation.
% o M_ Matlab's structure describing the Model (initialized by dynare, see @ref{M_}). % - M_ [struct] Description of the model.
% o estim_params_ Matlab's structure describing the estimated_parameters (initialized by dynare, see @ref{estim_params_}). % - estim_params_ [struct] Description of the estimated parameters.
% o options_ Matlab's structure describing the options (initialized by dynare, see @ref{options_}). % - options_ [struct] Dynare's options.
% o bayestopt_ Matlab's structure describing the priors (initialized by dynare, see @ref{bayesopt_}). % - oo_ [struct] Estimation and simulation results.
% o oo_ Matlab's structure gathering the results (initialized by dynare, see @ref{oo_}).
% %
% OUTPUTS % OUTPUTS
% o oo_ Matlab's structure gathering the results % - oo_ Matlab's structure gathering the results
% %
% SPECIAL REQUIREMENTS % SPECIAL REQUIREMENTS
% None. % None.
% Copyright © 2005-2021 Dynare Team % Copyright © 2005-2023 Dynare Team
% %
% This file is part of Dynare. % This file is part of Dynare.
% %
@ -42,7 +42,8 @@ np = estim_params_.np ; % Number of deep parameters.
if np if np
ip = nvx+nvn+ncx+ncn+1; ip = nvx+nvn+ncx+ncn+1;
for i=1:np for i=1:np
name = bayestopt_.name{ip}; k = estim_params_.param_vals(i,1);
name = M_.param_names{k};
oo_.([field_name '_mode']).parameters.(name) = xparam1(ip); oo_.([field_name '_mode']).parameters.(name) = xparam1(ip);
oo_.([field_name '_std_at_mode']).parameters.(name) = stdh(ip); oo_.([field_name '_std_at_mode']).parameters.(name) = stdh(ip);
ip = ip+1; ip = ip+1;
@ -90,4 +91,4 @@ if ncn
oo_.([field_name '_std_at_mode']).measurement_errors_corr.(name) = stdh(ip); oo_.([field_name '_std_at_mode']).measurement_errors_corr.(name) = stdh(ip);
ip = ip+1; ip = ip+1;
end end
end end

20
matlab/issmc.m Normal file
View File

@ -0,0 +1,20 @@
function bool = issmc(options_)
% Copyright © 2023 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
bool = ishssmc(options_) || isdsmh(options_);

View File

@ -60,7 +60,7 @@ xparam1 = posterior_mean;
hh = inv(SIGMA); hh = inv(SIGMA);
fprintf(' Done!\n'); fprintf(' Done!\n');
if ~isfield(oo_,'posterior_mode') || (options_.mh_replic && isequal(options_.posterior_sampler_options.posterior_sampling_method,'slice')) if ~isfield(oo_,'posterior_mode') || (options_.mh_replic && isequal(options_.posterior_sampler_options.posterior_sampling_method,'slice'))
oo_=fill_mh_mode(posterior_mode',NaN(npar,1),M_,options_,estim_params_,bayestopt_,oo_,'posterior'); oo_=fill_mh_mode(posterior_mode',NaN(npar,1),M_,options_,estim_params_,oo_,'posterior');
end end
% save the posterior mean and the inverse of the covariance matrix % save the posterior mean and the inverse of the covariance matrix

View File

@ -59,7 +59,7 @@ nblck = size(record.LastParameters,1);
clear record; clear record;
% Get all the posterior draws: % Get all the posterior draws:
PosteriorDraws = GetAllPosteriorDraws(M_.dname, M_.fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck, blck); PosteriorDraws = GetAllPosteriorDraws(options_, M_.dname, M_.fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck, blck);
% Compute the autocorrelation function: % Compute the autocorrelation function:
[~,autocor] = sample_autocovariance(PosteriorDraws,options_.mh_autocorrelation_function_size); [~,autocor] = sample_autocovariance(PosteriorDraws,options_.mh_autocorrelation_function_size);

View File

@ -1,8 +1,7 @@
function [ ix2, ilogpo2, ModelName, MetropolisFolder, FirstBlock, FirstLine, npar, NumberOfBlocks, nruns, NewFile, MAX_nruns, d, bayestopt_] = ... function [ ix2, ilogpo2, ModelName, MetropolisFolder, FirstBlock, FirstLine, npar, NumberOfBlocks, nruns, NewFile, MAX_nruns, d, bayestopt_] = ...
posterior_sampler_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_, dispString) posterior_sampler_initialization(TargetFun, xparam1, vv, mh_bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_, dispString)
% function [ ix2, ilogpo2, ModelName, MetropolisFolder, FirstBlock, FirstLine, npar, NumberOfBlocks, nruns, NewFile, MAX_nruns, d, bayestopt_] = ...
% metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_, dispString) % Posterior sampler initialization.
% Metropolis-Hastings initialization.
% %
% INPUTS % INPUTS
% o TargetFun [char] string specifying the name of the objective % o TargetFun [char] string specifying the name of the objective
@ -257,7 +256,7 @@ if ~options_.load_mh_file && ~options_.mh_recover
if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub) if all(candidate(:) >= mh_bounds.lb) && all(candidate(:) <= mh_bounds.ub)
ix2 = candidate; ix2 = candidate;
ilogpo2 = - feval(TargetFun,ix2',dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_.dr, oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state); ilogpo2 = - feval(TargetFun,ix2',dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_.dr, oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
fprintf('%s: Initialization at the posterior mode.\n\n',dispString); fprintf('%s: Initialization at the posterior mode.\n\n',dispString);
fprintf(fidlog,[' Blck ' int2str(1) 'params:\n']); fprintf(fidlog,[' Blck ' int2str(1) 'params:\n']);
for i=1:length(ix2(1,:)) for i=1:length(ix2(1,:))
fprintf(fidlog,[' ' int2str(i) ':' num2str(ix2(1,i)) '\n']); fprintf(fidlog,[' ' int2str(i) ':' num2str(ix2(1,i)) '\n']);

View File

@ -1,6 +1,5 @@
function bounds = prior_bounds(bayestopt, priortrunc) function bounds = prior_bounds(bayestopt_, priortrunc)
% function bounds = prior_bounds(bayestopt)
% computes bounds for prior density. % computes bounds for prior density.
% %
% INPUTS % INPUTS
@ -31,11 +30,11 @@ if nargin<2, priortrunc = 0.0; end
assert(priortrunc>=0 && priortrunc<=1, 'Second input argument must be non negative and not larger than one.') assert(priortrunc>=0 && priortrunc<=1, 'Second input argument must be non negative and not larger than one.')
pshape = bayestopt.pshape; pshape = bayestopt_.pshape;
p3 = bayestopt.p3; p3 = bayestopt_.p3;
p4 = bayestopt.p4; p4 = bayestopt_.p4;
p6 = bayestopt.p6; p6 = bayestopt_.p6;
p7 = bayestopt.p7; p7 = bayestopt_.p7;
bounds.lb = zeros(size(p6)); bounds.lb = zeros(size(p6));
bounds.ub = zeros(size(p6)); bounds.ub = zeros(size(p6));
@ -59,12 +58,12 @@ for i=1:length(p6)
bounds.ub(i) = gaminv(1.0-priortrunc, p6(i), p7(i))+p3(i); bounds.ub(i) = gaminv(1.0-priortrunc, p6(i), p7(i))+p3(i);
end end
case 3 case 3
if prior_trunc == 0 if priortrunc == 0
bounds.lb(i) = max(-Inf, p3(i)); bounds.lb(i) = max(-Inf, p3(i));
bounds.ub(i) = min(Inf, p4(i)); bounds.ub(i) = min(Inf, p4(i));
else else
bounds.lb(i) = max(norminv(prior_trunc, p6(i), p7(i)), p3(i)); bounds.lb(i) = max(norminv(priortrunc, p6(i), p7(i)), p3(i));
bounds.ub(i) = min(norminv(1-prior_trunc, p6(i), p7(i)), p4(i)); bounds.ub(i) = min(norminv(1-priortrunc, p6(i), p7(i)), p4(i));
end end
case 4 case 4
if priortrunc==0 if priortrunc==0
@ -99,6 +98,6 @@ for i=1:length(p6)
bounds.ub(i) = p3(i)+wblinv(1.0-priortrunc, p6(i), p7(i)); bounds.ub(i) = p3(i)+wblinv(1.0-priortrunc, p6(i), p7(i));
end end
otherwise otherwise
error(sprintf('prior_bounds: unknown distribution shape (index %d, type %d)', i, pshape(i))); error('prior_bounds: unknown distribution shape (index %d, type %d)', i, pshape(i));
end end
end end

View File

@ -212,9 +212,9 @@ if strcmpi(type,'posterior')
mh_nblck = options_.mh_nblck; mh_nblck = options_.mh_nblck;
if B==NumberOfDraws*mh_nblck if B==NumberOfDraws*mh_nblck
% we load all retained MH runs ! % we load all retained MH runs !
logpost=GetAllPosteriorDraws(M_.dname, M_.fname, 0, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck); logpost=GetAllPosteriorDraws(options_, M_.dname, M_.fname, 0, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck);
for column=1:npar for column=1:npar
x(:,column) = GetAllPosteriorDraws(M_.dname, M_.fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck); x(:,column) = GetAllPosteriorDraws(options_, M_.dname, M_.fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, NumberOfDraws, nblck);
end end
else else
logpost=NaN(B,1); logpost=NaN(B,1);
@ -390,4 +390,4 @@ if ~isnumeric(options_.parallel)
if leaveSlaveOpen == 0 if leaveSlaveOpen == 0
closeSlave(options_.parallel,options_.parallel_info.RemoteTmpFolder), closeSlave(options_.parallel,options_.parallel_info.RemoteTmpFolder),
end end
end end

View File

@ -67,7 +67,7 @@ n_nblocks_to_plot=length(blck);
if n_nblocks_to_plot==1 if n_nblocks_to_plot==1
% Get all the posterior draws: % Get all the posterior draws:
PosteriorDraws = GetAllPosteriorDraws(M_.dname,M_.fname,column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, TotalNumberOfMhDraws, mh_nblck, blck); PosteriorDraws = GetAllPosteriorDraws(options_, M_.dname,M_.fname,column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, TotalNumberOfMhDraws, mh_nblck, blck);
else else
PosteriorDraws=NaN(TotalNumberOfMhDraws,n_nblocks_to_plot); PosteriorDraws=NaN(TotalNumberOfMhDraws,n_nblocks_to_plot);
save_string=''; save_string='';
@ -75,7 +75,7 @@ else
title_string_tex=''; title_string_tex='';
end end
for block_iter=1:n_nblocks_to_plot for block_iter=1:n_nblocks_to_plot
PosteriorDraws(:,block_iter) = GetAllPosteriorDraws(M_.dname, M_.fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, TotalNumberOfMhDraws, mh_nblck, blck(block_iter)); PosteriorDraws(:,block_iter) = GetAllPosteriorDraws(options_, M_.dname, M_.fname, column, FirstMhFile, FirstLine, TotalNumberOfMhFiles, TotalNumberOfMhDraws, mh_nblck, blck(block_iter));
save_string=[save_string,'_',num2str(blck(block_iter))]; save_string=[save_string,'_',num2str(blck(block_iter))];
if options_.TeX if options_.TeX
title_string_tex=[title_string_tex, ', ' num2str(blck(block_iter))]; title_string_tex=[title_string_tex, ', ' num2str(blck(block_iter))];

View File

@ -805,6 +805,8 @@ mod_and_m_tests = [
'estimation/fsdat_simul.m' ] }, 'estimation/fsdat_simul.m' ] },
{ 'test' : [ 'estimation/fs2000.mod' ], { 'test' : [ 'estimation/fs2000.mod' ],
'extra' : [ 'estimation/fsdat_simul.m' ] }, 'extra' : [ 'estimation/fsdat_simul.m' ] },
{ 'test' : [ 'estimation/hssmc/fs2000.mod' ],
'extra' : [ 'estimation/fsdat_simul.m' ] },
{ 'test' : [ 'gsa/ls2003a.mod', { 'test' : [ 'gsa/ls2003a.mod',
'gsa/ls2003.mod', 'gsa/ls2003.mod',
'gsa/ls2003scr.mod', 'gsa/ls2003scr.mod',

View File

@ -0,0 +1,85 @@
// See fs2000.mod in the examples/ directory for details on the model
var m P c e W R k d n l gy_obs gp_obs y dA;
varexo e_a e_m;
parameters alp bet gam mst rho psi del;
alp = 0.33;
bet = 0.99;
gam = 0.003;
mst = 1.011;
rho = 0.7;
psi = 0.787;
del = 0.02;
model;
dA = exp(gam+e_a);
log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m;
-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0;
W = l/n;
-(psi/(1-psi))*(c*P/(1-n))+l/n = 0;
R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W;
1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0;
c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1);
P*c = m;
m-1+d = l;
e = exp(e_a);
y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a));
gy_obs = dA*y/y(-1);
gp_obs = (P/P(-1))*m(-1)/dA;
end;
steady_state_model;
dA = exp(gam);
gst = 1/dA;
m = mst;
khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1));
xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1);
nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp );
n = xist/(nust+xist);
P = xist + nust;
k = khst*n;
l = psi*mst*n/( (1-psi)*(1-n) );
c = mst/P;
d = l - mst + 1;
y = k^alp*n^(1-alp)*gst^alp;
R = mst/bet;
W = l/n;
ist = y-c;
q = 1 - d;
e = 1;
gp_obs = m/dA;
gy_obs = dA;
end;
shocks;
var e_a; stderr 0.014;
var e_m; stderr 0.005;
end;
steady;
check;
estimated_params;
alp, beta_pdf, 0.356, 0.02;
bet, beta_pdf, 0.993, 0.002;
gam, normal_pdf, 0.0085, 0.003;
mst, normal_pdf, 1.0002, 0.007;
rho, beta_pdf, 0.129, 0.223;
psi, beta_pdf, 0.65, 0.05;
del, beta_pdf, 0.01, 0.005;
stderr e_a, inv_gamma_pdf, 0.035449, inf;
stderr e_m, inv_gamma_pdf, 0.008862, inf;
end;
varobs gp_obs gy_obs;
options_.solve_tolf = 1e-12;
estimation(order=1,datafile='../fsdat_simul.m',nobs=192,loglinear,posterior_sampling_method='dsmh');

View File

@ -0,0 +1,91 @@
// See fs2000.mod in the examples/ directory for details on the model
var m P c e W R k d n l gy_obs gp_obs y dA;
varexo e_a e_m;
parameters alp bet gam mst rho psi del;
alp = 0.33;
bet = 0.99;
gam = 0.003;
mst = 1.011;
rho = 0.7;
psi = 0.787;
del = 0.02;
model;
dA = exp(gam+e_a);
log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m;
-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0;
W = l/n;
-(psi/(1-psi))*(c*P/(1-n))+l/n = 0;
R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W;
1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0;
c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1);
P*c = m;
m-1+d = l;
e = exp(e_a);
y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a));
gy_obs = dA*y/y(-1);
gp_obs = (P/P(-1))*m(-1)/dA;
end;
steady_state_model;
dA = exp(gam);
gst = 1/dA;
m = mst;
khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1));
xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1);
nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp );
n = xist/(nust+xist);
P = xist + nust;
k = khst*n;
l = psi*mst*n/( (1-psi)*(1-n) );
c = mst/P;
d = l - mst + 1;
y = k^alp*n^(1-alp)*gst^alp;
R = mst/bet;
W = l/n;
ist = y-c;
q = 1 - d;
e = 1;
gp_obs = m/dA;
gy_obs = dA;
end;
shocks;
var e_a; stderr 0.014;
var e_m; stderr 0.005;
end;
steady;
check;
estimated_params;
alp, beta_pdf, 0.356, 0.02;
bet, beta_pdf, 0.993, 0.002;
gam, normal_pdf, 0.0085, 0.003;
mst, normal_pdf, 1.0002, 0.007;
rho, beta_pdf, 0.129, 0.223;
psi, beta_pdf, 0.65, 0.05;
del, beta_pdf, 0.01, 0.005;
stderr e_a, inv_gamma_pdf, 0.035449, inf;
stderr e_m, inv_gamma_pdf, 0.008862, inf;
end;
varobs gp_obs gy_obs;
options_.solve_tolf = 1e-12;
estimation(order=1, datafile='../fsdat_simul.m', nobs=192, loglinear,
posterior_sampling_method='hssmc',
posterior_sampler_options=('steps',10,
'lambda',2,
'particles', 20000,
'scale',.5,
'target', .25));

View File

@ -1,94 +1,94 @@
// See fs2000.mod in the examples/ directory for details on the model // See fs2000.mod in the examples/ directory for details on the model
var m P c e W R k d n l gy_obs gp_obs y dA; var m P c e W R k d n l gy_obs gp_obs y dA;
varexo e_a e_m; varexo e_a e_m;
parameters alp bet gam mst rho psi del; parameters alp bet gam mst rho psi del;
alp = 0.33; alp = 0.33;
bet = 0.99; bet = 0.99;
gam = 0.003; gam = 0.003;
mst = 1.011; mst = 1.011;
rho = 0.7; rho = 0.7;
psi = 0.787; psi = 0.787;
del = 0.02; del = 0.02;
model; model;
dA = exp(gam+e_a); dA = exp(gam+e_a);
log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m;
-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; -P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0;
W = l/n; W = l/n;
-(psi/(1-psi))*(c*P/(1-n))+l/n = 0; -(psi/(1-psi))*(c*P/(1-n))+l/n = 0;
R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W;
1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; 1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0;
c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1);
P*c = m; P*c = m;
m-1+d = l; m-1+d = l;
e = exp(e_a); e = exp(e_a);
y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a));
gy_obs = dA*y/y(-1); gy_obs = dA*y/y(-1);
gp_obs = (P/P(-1))*m(-1)/dA; gp_obs = (P/P(-1))*m(-1)/dA;
end; end;
steady_state_model; steady_state_model;
dA = exp(gam); dA = exp(gam);
gst = 1/dA; gst = 1/dA;
m = mst; m = mst;
khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1)); khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1));
xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1); xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1);
nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp ); nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp );
n = xist/(nust+xist); n = xist/(nust+xist);
P = xist + nust; P = xist + nust;
k = khst*n; k = khst*n;
l = psi*mst*n/( (1-psi)*(1-n) ); l = psi*mst*n/( (1-psi)*(1-n) );
c = mst/P; c = mst/P;
d = l - mst + 1; d = l - mst + 1;
y = k^alp*n^(1-alp)*gst^alp; y = k^alp*n^(1-alp)*gst^alp;
R = mst/bet; R = mst/bet;
W = l/n; W = l/n;
ist = y-c; ist = y-c;
q = 1 - d; q = 1 - d;
e = 1; e = 1;
gp_obs = m/dA; gp_obs = m/dA;
gy_obs = dA; gy_obs = dA;
end; end;
shocks; shocks;
var e_a; stderr 0.014; var e_a; stderr 0.014;
var e_m; stderr 0.005; var e_m; stderr 0.005;
end; end;
steady; steady;
check; check;
estimated_params; estimated_params;
alp, beta_pdf, 0.356, 0.02; alp, beta_pdf, 0.356, 0.02;
bet, beta_pdf, 0.993, 0.002; bet, beta_pdf, 0.993, 0.002;
gam, normal_pdf, 0.0085, 0.003; gam, normal_pdf, 0.0085, 0.003;
mst, normal_pdf, 1.0002, 0.007; mst, normal_pdf, 1.0002, 0.007;
rho, beta_pdf, 0.129, 0.05; rho, beta_pdf, 0.129, 0.05;
psi, beta_pdf, 0.65, 0.05; psi, beta_pdf, 0.65, 0.05;
del, beta_pdf, 0.01, 0.005; del, beta_pdf, 0.01, 0.005;
stderr e_a, inv_gamma_pdf, 0.035449, inf; stderr e_a, inv_gamma_pdf, 0.035449, inf;
stderr e_m, inv_gamma_pdf, 0.008862, inf; stderr e_m, inv_gamma_pdf, 0.008862, inf;
end; end;
varobs gp_obs gy_obs; varobs gp_obs gy_obs;
//options_.posterior_sampling_method = 'slice'; //options_.posterior_sampling_method = 'slice';
estimation(order=1,datafile='../fsdat_simul',nobs=192,silent_optimizer,loglinear,mh_replic=50,mh_nblocks=2,mh_drop=0.2, //mode_compute=0,cova_compute=0, estimation(order=1,datafile='../fsdat_simul',nobs=192,silent_optimizer,loglinear,mh_replic=50,mh_nblocks=2,mh_drop=0.2, //mode_compute=0,cova_compute=0,
posterior_sampling_method='slice' posterior_sampling_method='slice'
); );
// continue with rotated slice // continue with rotated slice
estimation(order=1,datafile='../fsdat_simul',silent_optimizer,nobs=192,loglinear,mh_replic=100,mh_nblocks=2,mh_drop=0.5,load_mh_file,//mode_compute=0, estimation(order=1,datafile='../fsdat_simul',silent_optimizer,nobs=192,loglinear,mh_replic=100,mh_nblocks=2,mh_drop=0.5,load_mh_file,//mode_compute=0,
posterior_sampling_method='slice', posterior_sampling_method='slice',
posterior_sampler_options=('rotated',1,'use_mh_covariance_matrix',1) posterior_sampler_options=('rotated',1,'use_mh_covariance_matrix',1)
); );
options_.TeX=1; options_.TeX=1;
generate_trace_plots(1:2); generate_trace_plots(1:2);
options_.TeX=1; options_.TeX=1;