Skip to content

Commit 1101540

Browse files
committed
removed superfluous comments to improve readability. some minor refactorisations in matlab code.
Former-commit-id: 66e4794 [formerly 66e4794 [formerly ca86603]] Former-commit-id: d32092f872e797c0b4dc71e7818052cef96d8ed9 Former-commit-id: 5b7efe5
1 parent f9289a2 commit 1101540

23 files changed

+325
-1258
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.vscode/
22
.R~
33
.m~
4+
.pyc
45

56
# Byte-compiled / optimized / DLL files
67
__pycache__/

README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# pmh-tutorial
22

3-
This code was downloaded from < https://github.com/compops/pmh-tutorial > and contains the code used to produce the results in the tutorial:
3+
This code was downloaded from https://github.com/compops/pmh-tutorial and contains the code used to produce the results in the tutorial:
44

55
J. Dahlin and T. B. Schön, **Getting started with particle Metropolis-Hastings for inference in nonlinear models**. Pre-print, arXiv:1511:01707, 2017.
66

7-
The papers are available as a preprint from < http://arxiv.org/pdf/1511.01707 >.
7+
The papers are available as a preprint from http://arxiv.org/pdf/1511.01707
88

99
Included material
1010
--------------
@@ -18,4 +18,28 @@ Included material
1818

1919
**matlab-skeleton** Skeleton code files for MATLAB to help step-by-step implementation during courses and seminars.
2020

21-
21+
Copyright information
22+
--------------
23+
See *LICENSE* for more information.
24+
25+
``` R
26+
##############################################################################
27+
#
28+
# Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.com.nospam >
29+
#
30+
# This program is free software; you can redistribute it and/or modify
31+
# it under the terms of the GNU General Public License as published by
32+
# the Free Software Foundation; either version 2 of the License, or
33+
# (at your option) any later version.
34+
#
35+
# This program is distributed in the hope that it will be useful,
36+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
37+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+
# GNU General Public License for more details.
39+
#
40+
# You should have received a copy of the GNU General Public License along
41+
# with this program; if not, write to the Free Software Foundation, Inc.,
42+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43+
#
44+
##############################################################################
45+
```

matlab/README.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# MATLAB code for PMH tutorial
22

3-
This MATLAB code implements the Kalman filter (KF), particle filter (PF) and particle Metropolis-Hastings (PMH) algorithm for two different dynamical models: a linear Gaussian state-space (LGSS) model and a stochastic volatilty (SV) model. Note that the Kalman filter can only be employed for the first of these two models. The details of the code is described in the tutorial paper available at: < http://arxiv.org/pdf/1511.01707 >.
3+
This MATLAB code implements the Kalman filter (KF), particle filter (PF) and particle Metropolis-Hastings (PMH) algorithm for two different dynamical models: a linear Gaussian state-space (LGSS) model and a stochastic volatilty (SV) model. Note that the Kalman filter can only be employed for the first of these two models. The details of the code is described in the tutorial paper available at http://arxiv.org/pdf/1511.01707
44

5-
Note that the MATLAB code in this folder covers the basic implementations in the paper. See the R code in r/ for all the implementations and to recreate the results in the tutorial.
5+
Note that the MATLAB code in this folder covers the basic implementations in the paper. The notation of the variables has been changed sligthly compared with the tutorial paper to improve readability of the code. However, it should be easy to translate between the two. See the R code in r/ for all the implementations and to recreate the results in the tutorial.
66

77
Requirements
88
--------------
9-
The code is written and tested for MATLAB 2016b and makes use of the statistics toolbox and the Quandl package. See < https://github.com/quandl/Matlab > for more installation and to download the toolbox. Note that urlread2 is required by the Quandl toolbox and should be installed as detailed in the README file of the Quandl toolbox.
9+
The code is written and tested for MATLAB 2016b and makes use of the statistics toolbox and the Quandl package. See https://github.com/quandl/Matlab for more installation and to download the toolbox. Note that urlread2 is required by the Quandl toolbox and should be installed as detailed in the README file of the Quandl toolbox.
1010

1111
Main script files
1212
--------------
@@ -29,4 +29,28 @@ Supporting files
2929

3030
Adapting the code for another model
3131
--------------
32-
See the discussion in *README.MD* in the directory *r/*.
32+
See the discussion in *README.MD* in the directory *r/*.
33+
34+
Copyright information
35+
--------------
36+
``` R
37+
##############################################################################
38+
#
39+
# Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.com.nospam >
40+
#
41+
# This program is free software; you can redistribute it and/or modify
42+
# it under the terms of the GNU General Public License as published by
43+
# the Free Software Foundation; either version 2 of the License, or
44+
# (at your option) any later version.
45+
#
46+
# This program is distributed in the hope that it will be useful,
47+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
48+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49+
# GNU General Public License for more details.
50+
#
51+
# You should have received a copy of the GNU General Public License along
52+
# with this program; if not, write to the Free Software Foundation, Inc.,
53+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
54+
#
55+
##############################################################################
56+
```

matlab/example1_lgss.m

Lines changed: 15 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,39 @@
1-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2-
%
3-
% Example of state estimation in a LGSS model
4-
% using particle filters and Kalman filters
5-
%
6-
% Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.com.nospam >
7-
%
8-
% This program is free software; you can redistribute it and/or modify
9-
% it under the terms of the GNU General Public License as published by
10-
% the Free Software Foundation; either version 2 of the License, or
11-
% (at your option) any later version.
12-
%
13-
% This program is distributed in the hope that it will be useful,
14-
% but WITHOUT ANY WARRANTY; without even the implied warranty of
15-
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16-
% GNU General Public License for more details.
17-
%
18-
% You should have received a copy of the GNU General Public License along
19-
% with this program; if not, write to the Free Software Foundation, Inc.,
20-
% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21-
%
22-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1+
% State estimation in a LGSS model using particle and Kalman filters
232

243
% Set random seed
254
rng(0)
265

27-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286
% Define the model
29-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30-
31-
% Here, we use the following model
32-
%
33-
% x[t + 1] = phi * x[t] + sigmav * v[t]
34-
% y[t] = x[t] + sigmae * e[t]
35-
%
36-
% where v[t] ~ N(0, 1) and e[t] ~ N(0, 1)
37-
38-
% Set the parameters of the model
7+
% x[t + 1] = phi * x[t] + sigmav * v[t], v[t] ~ N(0, 1)
8+
% y[t] = x[t] + sigmae * e[t], e[t] ~ N(0, 1)
399
phi = 0.75;
4010
sigmav = 1.00;
4111
sigmae = 0.10;
42-
theta = [phi sigmav sigmae];
43-
44-
% Set the number of time steps to simulate
45-
T = 250;
46-
47-
% Set the initial state
12+
parameters = [phi sigmav sigmae];
13+
noObservations = 250;
4814
initialState = 0;
4915

50-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5116
% Generate data
52-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17+
[states, observations] = generateData(parameters, noObservations, initialState);
5318

54-
[x, y] = generateData(theta, T, initialState);
55-
56-
% Plot the measurements and latent states
5719
subplot(3,1,1);
58-
plot(y(2:(T + 1)), 'LineWidth', 1.5, 'Color', [27 158 119] / 256);
20+
plot(observations(2:(noObservations + 1)), 'LineWidth', 1.5, 'Color', [27 158 119] / 256);
5921
xlabel('time');
6022
ylabel('measurement');
6123

6224
subplot(3,1,2);
63-
plot(x(2:(T + 1)), 'LineWidth', 1.5, 'Color', [217 95 2] / 256);
25+
plot(states(2:(noObservations + 1)), 'LineWidth', 1.5, 'Color', [217 95 2] / 256);
6426
xlabel('time');
6527
ylabel('latent state');
6628

67-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68-
% State estimation
69-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70-
71-
% Using N = 20 particles and plot the estimate of the latent state
72-
outPF = particleFilter(y, theta, 20, initialState);
29+
% State estimation using particle filter with N = 20 particles
30+
stateEstPF = particleFilter(observations, parameters, 20, initialState);
7331

74-
% Kalman filter
75-
outKF = kalmanFilter(y, theta, initialState, 0.01);
32+
% State estimation using Kalman filter
33+
stateEstKF = kalmanFilter(observations, parameters, initialState, 0.01);
7634

77-
% Plot the difference
7835
subplot(3,1,3);
79-
difference = outPF(2:T) - outKF(2:T);
80-
plot(1:(T - 1), difference, 'LineWidth', 1.5, 'Color', [117 112 179] / 256);
36+
difference = stateEstPF(2:noObservations) - stateEstKF(2:noObservations);
37+
plot(1:(noObservations - 1), difference, 'LineWidth', 1.5, 'Color', [117 112 179] / 256);
8138
xlabel('time');
82-
ylabel('difference in state estimate');
83-
84-
85-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86-
% End of file
87-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39+
ylabel('difference in state estimate');

matlab/example2_lgss.m

Lines changed: 17 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,62 @@
1-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2-
%
31
% Example of particle Metropolis-Hastings in a LGSS model.
4-
%
5-
% Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.com.nospam >
6-
%
7-
% This program is free software; you can redistribute it and/or modify
8-
% it under the terms of the GNU General Public License as published by
9-
% the Free Software Foundation; either version 2 of the License, or
10-
% (at your option) any later version.
11-
%
12-
% This program is distributed in the hope that it will be useful,
13-
% but WITHOUT ANY WARRANTY; without even the implied warranty of
14-
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15-
% GNU General Public License for more details.
16-
%
17-
% You should have received a copy of the GNU General Public License along
18-
% with this program; if not, write to the Free Software Foundation, Inc.,
19-
% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20-
%
21-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222

233
% Set random seed
244
rng(0)
255

26-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276
% Define the model
28-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29-
30-
% Here, we use the following model
31-
%
32-
% x[t + 1] = phi * x[t] + sigmav * v[t]
33-
% y[t] = x[t] + sigmae * e[t]
34-
%
35-
% where v[t] ~ N(0, 1) and e[t] ~ N(0, 1)
36-
37-
% Set the parameters of the model
7+
% x[t + 1] = phi * x[t] + sigmav * v[t], v[t] ~ N(0, 1)
8+
% y[t] = x[t] + sigmae * e[t], e[t] ~ N(0, 1)
389
phi = 0.75;
3910
sigmav = 1.00;
4011
sigmae = 0.10;
41-
theta = [phi sigmav sigmae];
42-
43-
% Set the number of time steps to simulate
44-
T = 250;
45-
46-
% Set the initial state
12+
parameters = [phi sigmav sigmae];
13+
noObservations = 250;
4714
initialState = 0;
4815

49-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5016
% Generate data
51-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52-
53-
[x, y] = generateData(theta, T, initialState);
54-
55-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56-
% Parameter estimation using PMH
57-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17+
[states, observations] = generateData(parameters, noObservations, initialState);
5818

59-
% The inital guess of the parameter
19+
% Setings for PMH
6020
initialPhi = 0.50;
61-
62-
% No. particles in the particle filter (choose noParticles ~ T)
63-
noParticles = 100;
64-
65-
% The length of the burn-in and the no. iterations of PMH
66-
% (noBurnInIterations < noIterations)
21+
noParticles = 100; % Use noParticles ~ noObservations
6722
noBurnInIterations = 1000;
6823
noIterations = 5000;
69-
70-
% The standard deviation in the random walk proposal
7124
stepSize = 0.10;
7225

7326
% Run the PMH algorithm
74-
res = particleMetropolisHastings(y, initialPhi, [sigmav sigmae],...
75-
noParticles, initialState,...
76-
noIterations, stepSize);
27+
phiTrace = particleMetropolisHastings(observations, initialPhi, [sigmav sigmae], noParticles, initialState, noIterations, stepSize);
7728

78-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7929
% Plot the results
80-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81-
8230
noBins = floor(sqrt(noIterations - noBurnInIterations));
8331
grid = noBurnInIterations:noIterations;
84-
resPhi = res(noBurnInIterations:noIterations);
32+
phiTrace = phiTrace(noBurnInIterations:noIterations);
8533

86-
% Plot the parameter posterior estimate
87-
% Solid black line indicate posterior mean
34+
% Plot the parameter posterior estimate (solid black line = posterior mean)
8835
subplot(3, 1, 1);
89-
hist(resPhi, noBins);
36+
hist(phiTrace, noBins);
9037
xlabel('phi');
9138
ylabel('posterior density estimate');
9239

9340
h = findobj(gca, 'Type', 'patch');
9441
set(h, 'FaceColor', [117 112 179] / 256, 'EdgeColor', 'w');
9542

9643
hold on;
97-
plot([1 1] * mean(resPhi), [0 200], 'LineWidth', 3);
44+
plot([1 1] * mean(phiTrace), [0 200], 'LineWidth', 3);
9845
hold off;
9946

100-
% Plot the trace of the Markov chain after burn-in
101-
% Solid black line indicate posterior mean
47+
% Plot the trace of the Markov chain after burn-in (solid black line = posterior mean)
10248
subplot(3, 1, 2);
103-
plot(grid, resPhi, 'Color', [117 112 179] / 256, 'LineWidth', 1);
49+
plot(grid, phiTrace, 'Color', [117 112 179] / 256, 'LineWidth', 1);
10450
xlabel('iteration');
10551
ylabel('phi');
10652

10753
hold on;
108-
plot([grid(1) grid(end)], [1 1] * mean(resPhi), 'k', 'LineWidth', 3);
54+
plot([grid(1) grid(end)], [1 1] * mean(phiTrace), 'k', 'LineWidth', 3);
10955
hold off;
11056

11157
% Plot ACF of the Markov chain after burn-in
11258
subplot(3, 1, 3);
113-
[acf, lags] = xcorr(resPhi - mean(resPhi), 100, 'coeff');
59+
[acf, lags] = xcorr(phiTrace - mean(phiTrace), 100, 'coeff');
11460
stem(lags(101:200), acf(101:200), 'Color', [117 112 179] / 256, 'LineWidth', 2);
11561
xlabel('lag');
116-
ylabel('ACF of phi');
117-
118-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119-
% End of file
120-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62+
ylabel('ACF of phi');

0 commit comments

Comments
 (0)