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-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 . % 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_); str = sprintf('%s\n %s \t\t %5.4f \t\t %7.5f \t\t %5.4f', str, name, lb95_xparam(l), mean_xparam(l), ub95_xparam(l)); end disp([str]) disp('') %% Plot parameters densities [nbplt,nr,nc,lr,lc,nstar] = pltorg(npar); if TeX fidTeX = fopen([M_.fname '_param_density.tex'],'w'); fprintf(fidTeX,'%% TeX eps-loader file generated by DSMH.m (Dynare).\n'); fprintf(fidTeX,['%% ' datestr(now,0) '\n']); fprintf(fidTeX,' \n'); end number_of_grid_points = 2^9; % 2^9 = 512 !... Must be a power of two. bandwidth = 0; % Rule of thumb optimal bandwidth parameter. kernel_function = 'gaussian'; % Gaussian kernel for Fast Fourier Transform approximation. plt = 1 ; %for plt = 1:nbplt, if TeX NAMES = []; TeXNAMES = []; end hh = dyn_figure(options_.nodisplay,'Name','Parameters Densities'); for k=1:npar %min(nstar,npar-(plt-1)*nstar) subplot(ceil(sqrt(npar)),floor(sqrt(npar)),k) %kk = (plt-1)*nstar+k; [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_); optimal_bandwidth = mh_optimal_bandwidth(distrib_param(k,:)',options_.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,[ 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)= 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)