|
1 | 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
2 | 2 | % |
3 | | -% Example of PMH in a LGSS model |
| 3 | +% Example of particle Metropolis-Hastings in a LGSS model. |
4 | 4 | % |
5 | | -% Main script |
6 | | -% |
7 | | -% Copyright (C) 2015 Johan Dahlin < johan.dahlin (at) liu.se > |
| 5 | +% Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.com.nospam > |
8 | 6 | % |
9 | 7 | % This program is free software; you can redistribute it and/or modify |
10 | 8 | % it under the terms of the GNU General Public License as published by |
|
22 | 20 | % |
23 | 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
24 | 22 |
|
| 23 | +% Set random seed |
| 24 | +rng(0) |
| 25 | + |
25 | 26 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
26 | 27 | % Define the model |
27 | 28 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
28 | 29 |
|
29 | 30 | % Here, we use the following model |
30 | 31 | % |
31 | | -% x[tt+1] = phi * x[tt] + sigmav * v[tt] |
32 | | -% y[tt] = x[tt] + sigmae * e[tt] |
| 32 | +% x[t + 1] = phi * x[t] + sigmav * v[t] |
| 33 | +% y[t] = x[t] + sigmae * e[t] |
33 | 34 | % |
34 | | -% where v[tt] ~ N(0,1) and e[tt] ~ N(0,1) |
| 35 | +% where v[t] ~ N(0, 1) and e[t] ~ N(0, 1) |
35 | 36 |
|
36 | 37 | % Set the parameters of the model |
37 | | -phi = 0.75; |
| 38 | +phi = 0.75; |
38 | 39 | sigmav = 1.00; |
39 | 40 | sigmae = 0.10; |
| 41 | +theta = [phi sigmav sigmae]; |
40 | 42 |
|
41 | 43 | % Set the number of time steps to simulate |
42 | | -T = 500; |
| 44 | +T = 250; |
43 | 45 |
|
44 | 46 | % Set the initial state |
45 | | -x0 = 0; |
| 47 | +initialState = 0; |
46 | 48 |
|
47 | 49 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
48 | 50 | % Generate data |
49 | 51 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
50 | 52 |
|
51 | | -[x,y] = generateData(phi,sigmav,sigmae,T,x0); |
| 53 | +[x, y] = generateData(theta, T, initialState); |
52 | 54 |
|
53 | 55 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
54 | 56 | % Parameter estimation using PMH |
55 | 57 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
56 | 58 |
|
57 | 59 | % The inital guess of the parameter |
58 | | -initPar = 0.50; |
| 60 | +initialPhi = 0.50; |
59 | 61 |
|
60 | | -% No. particles in the particle filter ( choose nPart ~ T ) |
61 | | -nPart = 100; |
| 62 | +% No. particles in the particle filter (choose noParticles ~ T) |
| 63 | +noParticles = 100; |
62 | 64 |
|
63 | | -% The length of the burn-in and the no. iterations of PMH ( nBurnIn < nRuns ) |
64 | | -nBurnIn = 1000; |
65 | | -nRuns = 5000; |
| 65 | +% The length of the burn-in and the no. iterations of PMH |
| 66 | +% (noBurnInIterations < noIterations) |
| 67 | +noBurnInIterations = 1000; |
| 68 | +noIterations = 5000; |
66 | 69 |
|
67 | 70 | % The standard deviation in the random walk proposal |
68 | 71 | stepSize = 0.10; |
69 | 72 |
|
70 | 73 | % Run the PMH algorithm |
71 | | -res = pmh(y,initPar,sigmav,sigmae,nPart,T,x0,nRuns,stepSize); |
| 74 | +res = particleMetropolisHastings(y, initialPhi, [sigmav sigmae],... |
| 75 | + noParticles, initialState,... |
| 76 | + noIterations, stepSize); |
72 | 77 |
|
73 | 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
74 | 79 | % Plot the results |
75 | 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
76 | 81 |
|
| 82 | +noBins = floor(sqrt(noIterations - noBurnInIterations)); |
| 83 | +grid = noBurnInIterations:noIterations; |
| 84 | +resPhi = res(noBurnInIterations:noIterations); |
| 85 | + |
77 | 86 | % Plot the parameter posterior estimate |
78 | 87 | % Solid black line indicate posterior mean |
79 | | -subplot(3,1,1); |
80 | | -hist(res(nBurnIn:nRuns), floor(sqrt(nRuns-nBurnIn)) ); |
81 | | -xlabel('phi'); ylabel('posterior density estimate'); |
| 88 | +subplot(3, 1, 1); |
| 89 | +hist(resPhi, noBins); |
| 90 | +xlabel('phi'); |
| 91 | +ylabel('posterior density estimate'); |
82 | 92 |
|
83 | | -h = findobj(gca,'Type','patch'); |
84 | | -set(h,'FaceColor',[117 112 179]/256,'EdgeColor','w'); |
| 93 | +h = findobj(gca, 'Type', 'patch'); |
| 94 | +set(h, 'FaceColor', [117 112 179] / 256, 'EdgeColor', 'w'); |
85 | 95 |
|
86 | 96 | hold on; |
87 | | -plot([1 1] * mean(res(nBurnIn:nRuns)), [0 500], 'LineWidth', 1); |
| 97 | +plot([1 1] * mean(resPhi), [0 200], 'LineWidth', 3); |
88 | 98 | hold off; |
89 | 99 |
|
90 | 100 | % Plot the trace of the Markov chain after burn-in |
91 | 101 | % Solid black line indicate posterior mean |
92 | | -subplot(3,1,2); |
93 | | -plot(nBurnIn:nRuns,res(nBurnIn:nRuns), 'Color', [117 112 179]/256, 'LineWidth', 1); |
94 | | -xlabel('iteration'); ylabel('phi'); |
| 102 | +subplot(3, 1, 2); |
| 103 | +plot(grid, resPhi, 'Color', [117 112 179] / 256, 'LineWidth', 1); |
| 104 | +xlabel('iteration'); |
| 105 | +ylabel('phi'); |
95 | 106 |
|
96 | 107 | hold on; |
97 | | -plot([nBurnIn,nRuns], [1 1] * mean(res(nBurnIn:nRuns)), 'k', 'LineWidth', 1); |
| 108 | +plot([grid(1) grid(end)], [1 1] * mean(resPhi), 'k', 'LineWidth', 3); |
98 | 109 | hold off; |
99 | 110 |
|
100 | 111 | % Plot ACF of the Markov chain after burn-in |
101 | | -subplot(3,1,3); |
102 | | -macf = acf( res(nBurnIn:nRuns), 100, 0 ); |
103 | | -plot(2:101, macf, 'Color', [117 112 179]/256, 'LineWidth', 2); |
104 | | -xlabel('lag'); ylabel('ACF of phi'); |
| 112 | +subplot(3, 1, 3); |
| 113 | +[acf, lags] = xcorr(resPhi - mean(resPhi), 100, 'coeff'); |
| 114 | +stem(lags(101:200), acf(101:200), 'Color', [117 112 179] / 256, 'LineWidth', 2); |
| 115 | +xlabel('lag'); |
| 116 | +ylabel('ACF of phi'); |
105 | 117 |
|
106 | 118 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
107 | 119 | % End of file |
|
0 commit comments