image thumbnail
from Metropolis-Hastings by Felipe Uribe
This folder contains several programs related to Metropolis-Hastings algorithm

metropolis_hastings2.m
%% Metropolis-Hastings algorithm: example 2D
%{
---------------------------------------------------------------------------
*Created by:                  Date:              Comment:
 Felipe Uribe-Castillo        August 2011        Final project algorithm  
*Mail: 
 felipeuribecastillo@gmx.com
*University:
 National university of Colombia at Manizales. Civil engineering Dept.
---------------------------------------------------------------------------
The Metropolis-Hastings algorithm:
Obtain samples from some complex probability distribution in order to 
integrate very complex functions by random sampling. In this case the 
candidate distribution its no longer symmetric. 
The M-H algorithm can draw samples from any probability distribution P(x), 
requiring only that a function proportional to the density can be calculated. 
In Bayesian applications, the normalization factor is often extremely 
difficult to compute, so the ability to generate a sample without knowing 
this constant of proportionality is a major virtue of the algorithm.

This program needs the "MH_routine" function.

Original contribution: 
-"Equations of State Calculations by Fast Computing Machines"
  Metropolis, Rosenbluth, Rosenbluth, Teller & Teller (1953).
-"Monte Carlo Sampling Methods Using Markov Chains and Their Applications"
  W.K.Hastings (1970).
---------------------------------------------------------------------------
Based on:
1."Markov chain Monte Carlo and Gibbs sampling"
   B.Walsh.
   Lecture notes for EEB 581, version april 2004.
   http://web.mit.edu/~wingated/www/introductions/mcmc-gibbs-intro.pdf
2."An introduction to MCMC for machine learning"
   C.Andrieu, N.De Freitas, A.Doucet & M.I.Jordan.
   Machine Learning, 50, 5-43, 2003.
   http://www.cs.ubc.ca/~nando/papers/mlintro.pdf
---------------------------------------------------------------------------
%}
clear; close all; home; format short g;

%% Initial data
% Parameters
N      = 30000;    % Number of samples (iterations)
burnin = 3000;     % Number of runs until the chain approaches stationarity   
lag    = 10;       % Thinning or lag period: storing only every lagth point
acc    = 0;        % To note the acceptance
% Storage and initial points
theta = zeros(2,N);   % Samples drawn from the Markov chain
tt    = [3 1.5];      % Start points or initial states of the chain in X and Y

%% Target "PDF"
% First bivariate normal parameters
muX = 1;   varX = 1;  corrXY = 0.6;
muY = 1;   varY = 4;  covXY = sqrt(varX)*sqrt(varY)*corrXY; 
mu_dist1 = [muX muY]; cov_dist1 = [varX covXY; covXY varY];     % Means and Covariance Matrix for target "PDF"
% Second bivariate normal parameters
muX = 3;     varX = 0.49;  corrXY = -0.5;
muY = 1.5;   varY = 0.09;  covXY = sqrt(varX)*sqrt(varY)*corrXY; 
mu_dist2 = [muX muY]; cov_dist2 = [varX covXY; covXY varY];     % Means and Covariance Matrix for target "PDF"
% Target "PDF"
p = @(X) mvnpdf(X,mu_dist1,cov_dist1) + mvnpdf(X,mu_dist2,cov_dist2);  % Gaussian mixture

%% Proposal PDF
% Bivariate normal parameters
varX_proposal  = 1;    varY_proposal = 1;   corrXY_proposal = -0.5;         % Var(X), var(Y) and CorCoef(X,Y) for proposal, assumed
covXY_proposal = sqrt(varX_proposal)*sqrt(varY_proposal)*corrXY_proposal;   % Cov(XY)for proposal
cov_proposal_PDF = [varX_proposal   covXY_proposal;...
                    covXY_proposal  varY_proposal];    % Covariance Matrix for proposal
% Proposal PDF                 
proposal_PDF = @(X,mu) mvnpdf(X,mu,cov_proposal_PDF);          % Proposal PDF
sample_from_proposal_PDF = @(mu) mvnrnd(mu,cov_proposal_PDF);  % Function that samples from proposal PDF

%% Marginals
X = (-6:0.05:6)';   nx = length(X);
Y = (-6:0.05:6)';   ny = length(Y);
[XX,YY] = meshgrid(X,Y);
pXY = @(x,y) mvnpdf([x' y'],mu_dist1,cov_dist1) + mvnpdf([x' y'],mu_dist2,cov_dist2); 
pX = zeros(nx,1);
for i = 1:nx
   pX(i) = quad(@(y) pXY(repmat(X(i),1,length(y)),y), -10, 10);  % Marginal X
end
pY = zeros(ny,1);
for i = 1:ny
   pY(i) = quad(@(x) pXY(x,repmat(Y(i),1,length(x))), -10, 10);  % Marginal Y
end

%% M-H routine
for i = 1:burnin   % First make the burn-in stage
   [tt a] = MH_routine(tt,p,proposal_PDF,sample_from_proposal_PDF); 
end
for i = 1:N   % Cycle to the number of samples
   for j = 1:lag   % Cycle to make the thinning
      [tt a] = MH_routine(tt,p,proposal_PDF,sample_from_proposal_PDF);
   end
   theta(:,i) = tt;        % Store the chosen states
   acc        = acc + a;   % Accepted ?
end
accrate = acc/N;           % Acceptance rate

%% Autocorrelation
nn = 100;          % Number of samples for examine the AC
pp = theta(1,1:nn);   pp2 = theta(1,end-nn:end);   % First ans Last nn samples in X
qq = theta(2,1:nn);   qq2 = theta(2,end-nn:end);   % First and Last nn samples in Y
% AC in X
[r lags]   = xcorr(pp-mean(pp), 'coeff');
[r2 lags2] = xcorr(pp2-mean(pp2), 'coeff');
% AC in Y
[r3 lags3] = xcorr(qq-mean(qq), 'coeff');
[r4 lags4] = xcorr(qq2-mean(qq2), 'coeff');

%% Plots
% Autocorrelation
figure;
subplot(2,2,1);   stem(lags, r);
title('Autocorrelation in X', 'FontSize', 14);
ylabel('AC (first 100 samples)', 'FontSize', 12);
subplot(2,2,3);   stem(lags2, r2);
ylabel('AC (last 100 samples)', 'FontSize', 12);
subplot(2,2,2);   stem(lags3, r3);
title('Autocorrelation in Y', 'FontSize', 14);
ylabel('AC (first 100 samples)', 'FontSize', 12);
subplot(2,2,4);   stem(lags4, r4);
ylabel('AC (last 100 samples)', 'FontSize', 12);

% Target function and samples 
Z = p([XX(:) YY(:)]);  Z = reshape(Z,length(YY),length(XX));
figure;
subplot(2,1,1);   % Target "PDF"
surf(X,Y,Z); grid on; shading interp;
xlabel('X', 'FontSize', 12);  ylabel('Y', 'FontSize', 12);  
title('f_{XY}(x,y)', 'FontSize', 12);
subplot(2,1,2);   % Distribution of samples
plot(theta(1,:),theta(2,:),'k.','LineWidth',1); hold on; 
contour(X,Y,Z,22,'--','LineWidth',2); colormap jet; axis tight;
xlabel('X', 'FontSize', 12);   ylabel('Y', 'FontSize', 12);
text(3,-3,sprintf('Acceptace rate = %g', accrate),'FontSize',11);

% Joint, Marginals and histograms
figure;
% Marginal Y
subplot(4,4,[1 5 9]);
[n2 x2] = hist(theta(2,:), ceil(sqrt(N))); 
barh(x2, n2/(N*(x2(2)-x2(1))));   hold on;               % Normalized histogram
set(gca,'XDir','reverse','YAxisLocation','right', 'Box','off'); 
xlabel('pY(y)', 'FontSize', 15) 
plot(pY/trapz(Y,pY),Y,'r-','LineWidth',2); axis tight;   % Normalized marginal
% Marginal X
subplot(4,4,[14 15 16]);
[n1 x1] = hist(theta(1,:), ceil(sqrt(N))); 
bar(x1, n1/(N*(x1(2)-x1(1))));   axis tight;   hold on;  % Normalized histogram
set(gca,'YDir','reverse','XAxisLocation','top','Box','off'); 
ylabel('pX(x)', 'FontSize', 15)
plot(X,pX/trapz(X,pX),'r-','LineWidth',2);               % Normalized marginal
% Distribution of samples
subplot(4,4,[2 3 4 6 7 8 10 11 12]);  
plot(theta(1,:),theta(2,:),'b.','LineWidth',1); axis tight; hold on; 
contour(X,Y,Z,22,'--','LineWidth',2); colormap summer; 
title('Distribution of samples', 'FontSize', 15);
xlabel('X', 'FontSize', 15);   ylabel('Y', 'FontSize', 15);

% Useful Matlab command
figure;
scatterhist(theta(1,:),theta(2,:),[ceil(sqrt(N)) ceil(sqrt(N))]); hold on; 
contour(X,Y,Z,22,'--','LineWidth',2); colormap summer;

%%End

Contact us at files@mathworks.com