File: posterior_sampler_iteration.m

package info (click to toggle)
dynare 4.6.3-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 74,896 kB
  • sloc: cpp: 98,057; ansic: 28,929; pascal: 13,844; sh: 5,947; objc: 4,236; yacc: 4,215; makefile: 2,583; lex: 1,534; fortran: 877; python: 647; ruby: 291; lisp: 152; xml: 22
file content (189 lines) | stat: -rw-r--r-- 9,729 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
function  [par, logpost, accepted, neval] = posterior_sampler_iteration(TargetFun,last_draw, last_posterior, sampler_options,varargin)

% function [par, logpost, accepted, neval] = posterior_sampler_iteration(TargetFun,last_draw, last_posterior, sampler_options,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_)
% posterior samplers
%
% INPUTS
%   TargetFun:              string storing the objective function (e.g. 'dsge_likelihood.m')
%   last_draw:              parameter vector in last iteration
%   last_posterior:         value of the posterior in last iteration
%   sampler_options:        posterior sampler options
%   dataset_:               the dataset after required transformation
%   dataset_info:           Various informations about the dataset (descriptive statistics and missing observations).
%   options_:               structure storing the options
%   M_:                     structure storing the model information
%   estim_params_:          structure storing information about estimated parameters
%   bayestopt_:             structure storing information about priors
%   mh_bounds:              structure containing prior bounds
%   oo_:                    structure storing the results
%
% OUTPUTS
%   par:                    last accepted parameter vector
%   logpost:                value of the posterior after current iteration
%   accepted:               share of proposed draws that were accepted
%   neval:                  number of evaluations (>1 only for slice)
%
% SPECIAL REQUIREMENTS
%   none

% Copyright (C) 2015-18 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 <http://www.gnu.org/licenses/>.


posterior_sampling_method = sampler_options.posterior_sampling_method;
mh_bounds = sampler_options.bounds;

switch posterior_sampling_method
  case 'slice'

    [par, logpost, neval] = slice_sampler(TargetFun,last_draw, [mh_bounds.lb mh_bounds.ub], sampler_options,varargin{:});
    accepted = 1;
  case 'random_walk_metropolis_hastings'
    neval = 1;
    ProposalFun = sampler_options.proposal_distribution;
    proposal_covariance_Cholesky_decomposition = sampler_options.proposal_covariance_Cholesky_decomposition;
    n = sampler_options.n;

    par = feval(ProposalFun, last_draw, proposal_covariance_Cholesky_decomposition, n);
    if all( par(:) > mh_bounds.lb ) && all( par(:) < mh_bounds.ub )
        try
            logpost = - feval(TargetFun, par(:),varargin{:});
        catch
            logpost = -inf;
        end
    else
        logpost = -inf;
    end
    r = logpost-last_posterior;
    if (logpost > -inf) && (log(rand) < r)
        accepted = 1;
    else
        accepted = 0;
        par = last_draw;
        logpost = last_posterior;
    end
  case 'tailored_random_block_metropolis_hastings'
    options_=varargin{3};
    bayestopt_=varargin{6};
    npar=length(last_draw);
    %% randomize indices for blocking in this iteration
    indices=randperm(npar)';
    blocks=[1; (1+cumsum((rand(length(indices)-1,1)>(1-sampler_options.new_block_probability))))];
    nblocks=blocks(end,1); %get number of blocks this iteration
    current_draw=last_draw'; %get starting point for current draw for updating
    blocked_draws_counter=0;
    accepted_draws_counter=0;
    for block_iter=1:nblocks
        blocked_draws_counter=blocked_draws_counter+1;
        nxopt=length(indices(blocks==block_iter,1)); %get size of current block
        par_start_current_block=current_draw(indices(blocks==block_iter,1));
        [xopt_current_block, fval, exitflag, hess_mat_optimizer, options_, Scale] = dynare_minimize_objective(@TaRB_optimizer_wrapper,par_start_current_block,sampler_options.mode_compute,options_,[mh_bounds.lb(indices(blocks==block_iter,1),1) mh_bounds.ub(indices(blocks==block_iter,1),1)],bayestopt_.name,bayestopt_,[],...
                                                          current_draw,indices(blocks==block_iter,1),TargetFun,...% inputs for wrapper
                                                          varargin{:}); %inputs for objective
        %% covariance for proposal density
        hessian_mat = reshape(hessian('TaRB_optimizer_wrapper',xopt_current_block, ...
                                      options_.gstep,...
                                      current_draw,indices(blocks==block_iter,1),TargetFun,...% inputs for wrapper
                                      varargin{:}),nxopt,nxopt);

        if any(any(isnan(hessian_mat))) || any(any(isinf(hessian_mat)))
            inverse_hessian_mat=eye(nxopt)*1e-4; %use diagonal
        else
            inverse_hessian_mat=inv(hessian_mat); %get inverse Hessian
            if any(any((isnan(inverse_hessian_mat)))) || any(any((isinf(inverse_hessian_mat))))
                inverse_hessian_mat=eye(nxopt)*1e-4; %use diagonal
            end
        end
        [proposal_covariance_Cholesky_decomposition_upper,negeigenvalues]=chol(inverse_hessian_mat);
        %if not positive definite, use generalized Cholesky of Eskow/Schnabel
        if negeigenvalues~=0
            proposal_covariance_Cholesky_decomposition_upper=chol_SE(inverse_hessian_mat,0);
        end
        proposal_covariance_Cholesky_decomposition_upper=proposal_covariance_Cholesky_decomposition_upper*diag(bayestopt_.jscale(indices(blocks==block_iter,1),:));
        %get proposal draw
        if strcmpi(sampler_options.proposal_distribution,'rand_multivariate_normal')
            n = nxopt;
        elseif strcmpi(sampler_options.proposal_distribution,'rand_multivariate_student')
            n = sampler_options.student_degrees_of_freedom;
        end

        proposed_par = feval(sampler_options.proposal_distribution, xopt_current_block', proposal_covariance_Cholesky_decomposition_upper, n);
        % check whether draw is valid and compute posterior
        if all( proposed_par(:) > mh_bounds.lb(indices(blocks==block_iter,1),:) ) && all( proposed_par(:) < mh_bounds.ub(indices(blocks==block_iter,1),:) )
            try
                logpost = - feval('TaRB_optimizer_wrapper', proposed_par(:),...
                                  current_draw,indices(blocks==block_iter,1),TargetFun,...% inputs for wrapper
                                  varargin{:});
            catch
                logpost = -inf;
            end
        else
            logpost = -inf;
        end

        if (logpost > -inf)
            %get ratio of proposal densities, required because proposal depends
            %on current mode via Hessian and is thus not symmetric anymore
            if strcmpi(sampler_options.proposal_distribution,'rand_multivariate_normal')
                proposal_density_proposed_move_forward=multivariate_normal_pdf(proposed_par,xopt_current_block',proposal_covariance_Cholesky_decomposition_upper,n);
                proposal_density_proposed_move_backward=multivariate_normal_pdf(par_start_current_block',xopt_current_block',proposal_covariance_Cholesky_decomposition_upper,n);
            elseif strcmpi(sampler_options.proposal_distribution,'rand_multivariate_student')
                proposal_density_proposed_move_forward=multivariate_student_pdf(proposed_par,xopt_current_block',proposal_covariance_Cholesky_decomposition_upper,n);
                proposal_density_proposed_move_backward=multivariate_student_pdf(par_start_current_block',xopt_current_block',proposal_covariance_Cholesky_decomposition_upper,n);
            end
            accprob=logpost-last_posterior+ log(proposal_density_proposed_move_backward)-log(proposal_density_proposed_move_forward); %Formula (6), Chib/Ramamurthy
            if  (log(rand) < accprob)
                current_draw(indices(blocks==block_iter,1))=proposed_par;
                last_posterior=logpost;
                accepted_draws_counter =accepted_draws_counter +1;
            else %no updating
                 %do nothing, keep old value
            end
        end
    end
    accepted=accepted_draws_counter/blocked_draws_counter;
    par = current_draw;
    neval=1;
    logpost = last_posterior; %make sure not a temporary draw is returned;
  case 'independent_metropolis_hastings'
    neval = 1;
    ProposalFun = sampler_options.proposal_distribution;
    ProposalDensity = sampler_options.ProposalDensity;
    proposal_covariance_Cholesky_decomposition = sampler_options.proposal_covariance_Cholesky_decomposition;
    n = sampler_options.n;
    xparam1 = sampler_options.xparam1';
    par = feval(ProposalFun, xparam1, proposal_covariance_Cholesky_decomposition, n);
    if all( par(:) > mh_bounds.lb ) && all( par(:) < mh_bounds.ub )
        try
            logpost = - feval(TargetFun, par(:),varargin{:});
        catch
            logpost = -inf;
        end
    else
        logpost = -inf;
    end
    r = logpost - last_posterior + ...
        log(feval(ProposalDensity, last_draw, xparam1, proposal_covariance_Cholesky_decomposition, n)) - ...
        log(feval(ProposalDensity, par, xparam1, proposal_covariance_Cholesky_decomposition, n));
    if (logpost > -inf) && (log(rand) < r)
        accepted = 1;
    else
        accepted = 0;
        par = last_draw;
        logpost = last_posterior;
    end
end