Skip to content

Commit 503aacd

Browse files
committed
R bug: missing library and IACT computation. Added script for computing IACT while varying N in example 4.
Former-commit-id: 9126c30
1 parent a85397b commit 503aacd

6 files changed

Lines changed: 240 additions & 10 deletions

File tree

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
##############################################################################
2+
#
3+
# Example of particle Metropolis-Hastings in a stochastic volatility model
4+
# The effect on mixing while varying N.
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+
##############################################################################
23+
24+
# Import libraries
25+
library("Quandl")
26+
library("mvtnorm")
27+
28+
# Import helpers
29+
source("../helpers/stateEstimation.R")
30+
source("../helpers/parameterEstimation.R")
31+
source("../helpers/plotting.R")
32+
33+
# Set the random seed to replicate results in tutorial
34+
set.seed(10)
35+
36+
# Should the results be loaded from file (to quickly generate plots)
37+
loadSavedWorkspace <- FALSE
38+
39+
# Save plot to file
40+
savePlotToFile <- FALSE
41+
42+
43+
##############################################################################
44+
# Load data
45+
##############################################################################
46+
d <-
47+
Quandl(
48+
"NASDAQOMX/OMXS30",
49+
start_date = "2012-01-02",
50+
end_date = "2014-01-02",
51+
type = "zoo"
52+
)
53+
y <- as.numeric(100 * diff(log(d$"Index Value")))
54+
55+
56+
##############################################################################
57+
# Likelihood estimation using particle filter
58+
##############################################################################
59+
60+
# True parameters estimated in example5-sv.R
61+
theta <- c(-0.12, 0.96, 0.17)
62+
63+
# No. particles in the particle filter to try out
64+
noParticles <- c(10, 20, 50, 100, 200, 500, 1000)
65+
66+
# No. repetitions of log-likelihood estimate
67+
noSimulations <- 1000
68+
69+
# Pre-allocate vectors
70+
logLikelihoodEstimates <- matrix(0, nrow = length(noParticles), ncol = noSimulations)
71+
logLikelihoodVariance <- rep(0, length(noParticles))
72+
computationalTimePerSample <- rep(0, length(noParticles))
73+
74+
# Main loop
75+
if (loadSavedWorkspace) {
76+
load("../savedWorkspaces/example4-sv-varyingN.RData")
77+
} else {
78+
for (k in 1:length(noParticles)) {
79+
# Save the current time
80+
ptm <- proc.time()
81+
82+
for (i in 1:noSimulations) {
83+
# Run the particle filter
84+
res <- particleFilterSVmodel(y, theta, noParticles[k])
85+
86+
# Save the log-Likelihood estimate
87+
logLikelihoodEstimates[k, i] <- res$logLikelihood
88+
}
89+
90+
# Compute the variance of the log-likelihood and computational time per sample
91+
logLikelihoodVariance[k] <- var(logLikelihoodEstimates[k, ])
92+
computationalTimePerSample[k] <- (proc.time() - ptm)[3] / noSimulations
93+
94+
# Print to screen
95+
print(paste(paste(paste(paste("Simulation: ", k, sep = ""), " of ", sep = ""), length(noParticles), sep = ""), " completed.", sep = ""))
96+
print(paste(paste(paste(paste("No. particles: ", noParticles[k], sep = ""), " requires ", sep = ""), computationalTimePerSample[k], sep = ""), " seconds for computing one sample.", sep = ""))
97+
}
98+
}
99+
100+
##############################################################################
101+
# Parameter estimation using PMH
102+
##############################################################################
103+
104+
# The inital guess of the parameter (use the estimate of the posterior mean to
105+
# accelerated the algorithm, i.e., so less PMH iterations can be used).
106+
initialTheta <- theta
107+
108+
# The length of the burn-in and the no. iterations of PMH ( noBurnInIterations < noIterations )
109+
noBurnInIterations <- 2500
110+
noIterations <- 7500
111+
112+
# The standard deviation in the random walk proposal
113+
stepSize <- matrix(
114+
c(
115+
0.137255431,
116+
-0.0016258103,
117+
0.0015047492,
118+
-0.0016258103,
119+
0.0004802053,
120+
-0.0009973058,
121+
0.0015047492,
122+
-0.0009973058,
123+
0.0031307062
124+
),
125+
ncol = 3,
126+
nrow = 3
127+
)
128+
stepSize <- 0.8 * stepSize
129+
130+
# Main loop
131+
if (loadSavedWorkspace) {
132+
load("../savedWorkspaces/example4-sv-varyingN.RData")
133+
} else {
134+
resTheta <- array(0, dim = c(length(noParticles), noIterations - noBurnInIterations + 1, 3))
135+
computationalTimePerIteration <- rep(0, length(noParticles))
136+
acceptProbability <- rep(0, length(noParticles))
137+
138+
for (k in 1:length(noParticles)) {
139+
# Save the current time
140+
ptm <- proc.time()
141+
142+
# Run the PMH algorithm
143+
res <- particleMetropolisHastingsSVmodel(y, initialTheta, noParticles[k], noIterations, stepSize)
144+
145+
# Save the parameter trace
146+
resTheta[k, ,] <- res$theta[noBurnInIterations:noIterations,]
147+
148+
# Compute acceptance probability and computational time per sample
149+
computationalTimePerIteration[k] <- (proc.time() - ptm)[3] / noIterations
150+
acceptProbability[k] <- mean(res$proposedThetaAccepted[noBurnInIterations:noIterations])
151+
152+
# Print to screen
153+
print(paste(paste(paste(paste("Simulation: ", k, sep = ""), " of ", sep = ""), length(noParticles), sep = ""), " completed.", sep = ""))
154+
}
155+
}
156+
157+
##############################################################################
158+
# Post-processing (computing IACT and IACT * time)
159+
##############################################################################
160+
161+
resThetaIACT <- matrix(0, nrow = length(noParticles), ncol = 3)
162+
resThetaIACTperSecond <- matrix(0, nrow = length(noParticles), ncol = 3)
163+
164+
for (k in 1:length(noParticles)) {
165+
acf_mu <- acf(resTheta[k, , 1], plot = FALSE, lag.max = 200)
166+
acf_phi <- acf(resTheta[k, , 2], plot = FALSE, lag.max = 200)
167+
acf_sigmav <- acf(resTheta[k, , 3], plot = FALSE, lag.max = 200)
168+
169+
resThetaIACT[k, ] <- 1 + 2 * c(sum(acf_mu$acf), sum(acf_phi$acf), sum(acf_sigmav$acf))
170+
resThetaIACTperSecond[k, ] <- resThetaIACT[k, ] / computationalTimePerIteration[k]
171+
}
172+
173+
print(rbind(noParticles, apply(resThetaIACT, 1, max), apply(resThetaIACTperSecond, 1, max)))
174+
175+
176+
177+
# # Export plot to file
178+
# if (savePlotToFile) {
179+
# cairo_pdf("figures/example4-sv-varyingN.pdf",
180+
# height = 10,
181+
# width = 8)
182+
# }
183+
#
184+
# layout(matrix(1:14, 7, 2, byrow = FALSE))
185+
# par(mar = c(4, 5, 0, 0))
186+
#
187+
# for (k in 1:length(noParticles)) {
188+
# xlab = ""
189+
# if (k == length(noParticles)) { xlab = "log-likelihood"}
190+
# hist(
191+
# logLikelihoodEstimates[k, ],
192+
# breaks = floor(sqrt(noSimulations)),
193+
# col = rgb(t(col2rgb("#1B9E77")) / 256, alpha = 0.25),
194+
# border = NA,
195+
# xlab = xlab,
196+
# ylab = "",
197+
# xlim = c(-730, -680),
198+
# main = "",
199+
# freq = FALSE
200+
# )
201+
# }
202+
#
203+
# # Close the plotting device
204+
# if (savePlotToFile) {
205+
# dev.off()
206+
# }
207+
208+
209+
##############################################################################
210+
# Compute and save the results
211+
##############################################################################
212+
213+
214+
# Save the workspace to file
215+
if (!loadSavedWorkspace) {
216+
save.image("../savedWorkspaces/example4-sv-varyingN.RData")
217+
}
218+
219+
220+
##############################################################################
221+
# End of file
222+
##############################################################################

r/example3-sv.R

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020
#
2121
##############################################################################
2222

23-
# Import library
23+
# Import libraries
2424
library("Quandl")
25+
library("mvtnorm")
2526

2627
# Import helpers
2728
source("helpers/stateEstimation.R")
@@ -87,7 +88,7 @@ if (savePlotToFile) {
8788
width = 8)
8889
}
8990

90-
makePlotsParticleMetropolisHastingsSVModel(y, res, noBurnInIterations, noIterations, nPlot)
91+
iact <- makePlotsParticleMetropolisHastingsSVModel(y, res, noBurnInIterations, noIterations, nPlot)
9192

9293
# Close the plotting device
9394
if (savePlotToFile) {
@@ -107,7 +108,7 @@ print(thhatSD)
107108
#[1] 0.37048000 0.02191359 0.05595271
108109

109110
# Compute an estimate of the IACT using the first 100 ACF coefficients
110-
(iact <- 1 + 2 * c(sum(muACF$acf), sum(phiACF$acf), sum(sigmavACF$acf)))
111+
print(iact)
111112
# [1] 135.19084 85.98935 65.80120
112113

113114
# Estimate the covariance of the posterior to tune the proposal

r/example4-sv.R

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
#
2222
##############################################################################
2323

24-
# Import library
24+
# Import libraries
2525
library("Quandl")
26+
library("mvtnorm")
2627

2728
# Import helpers
2829
source("helpers/stateEstimation.R")
@@ -99,7 +100,7 @@ if (savePlotToFile) {
99100
width = 8)
100101
}
101102

102-
makePlotsParticleMetropolisHastingsSVModel(y, res, noBurnInIterations, noIterations, nPlot)
103+
iact <- makePlotsParticleMetropolisHastingsSVModel(y, res, noBurnInIterations, noIterations, nPlot)
103104

104105
# Close the plotting device
105106
if (savePlotToFile) {
@@ -119,7 +120,7 @@ print(thhatSD)
119120
#[1] 0.24976843 0.02232583 0.05356500
120121

121122
# Compute an estimate of the IACT using the first 100 ACF coefficients
122-
(iact <- 1 + 2 * c(sum(muACF$acf), sum(phiACF$acf), sum(sigmavACF$acf)))
123+
print(iact)
123124
# [1] 13.28575 26.50253 23.31947
124125

125126
# Estimate the covariance of the posterior to tune the proposal

r/example5-sv.R

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
#
2222
##############################################################################
2323

24-
# Import library
24+
# Import libraries
2525
library("Quandl")
26+
library("mvtnorm")
2627

2728
# Import helpers
2829
source("helpers/stateEstimation.R")
@@ -95,7 +96,7 @@ if (savePlotToFile) {
9596
cairo_pdf("figures/example5-sv.pdf", height = 10, width = 8)
9697
}
9798

98-
makePlotsParticleMetropolisHastingsSVModel(y, res, noBurnInIterations, noIterations, nPlot)
99+
iact <- makePlotsParticleMetropolisHastingsSVModel(y, res, noBurnInIterations, noIterations, nPlot)
99100

100101
# Close the plotting device
101102
if (savePlotToFile) {
@@ -115,7 +116,7 @@ print(thhatSD)
115116
#[1] 0.21236553 0.02287443 0.05967315
116117

117118
# Compute an estimate of the IACT using the first 100 ACF coefficients
118-
(iact <- 1 + 2 * c(sum(muACF$acf), sum(phiACF$acf), sum(sigmavACF$acf)))
119+
print(iact)
119120
# [1] 12.55590 20.63091 16.94274
120121

121122
# Estimate the covariance of the posterior to tune the proposal

r/helpers/parameterEstimation.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ particleMetropolisHastingsSVmodel <- function(y, initialTheta, noParticles, noIt
267267
#=====================================================================
268268
# Return traces of the parameters
269269
#=====================================================================
270-
list(theta = theta, xHatFiltered = xHatFiltered)
270+
list(theta = theta, xHatFiltered = xHatFiltered, proposedThetaAccepted = proposedThetaAccepted)
271271
}
272272

273273

r/helpers/plotting.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ makePlotsParticleMetropolisHastingsSVModel <- function(y, res, noBurnInIteration
101101
parameterScales <- c(-1, 1, 0.88, 1.0, 0, 0.4)
102102
parameterScales <- matrix(parameterScales, nrow = 3, ncol = 2, byrow = TRUE)
103103
parameterColors <- c("#7570B3", "#E7298A", "#66A61E")
104+
iact <- c()
104105

105106
for (k in 1:3) {
106107

@@ -172,7 +173,11 @@ makePlotsParticleMetropolisHastingsSVModel <- function(y, res, noBurnInIteration
172173
)
173174
abline(h = 1.96 / sqrt(noIterations - noBurnInIterations), lty = "dotted")
174175
abline(h = -1.96 / sqrt(noIterations - noBurnInIterations), lty = "dotted")
176+
177+
iact <- c(iact, 1 + 2 * sum(acf_res$acf))
175178
}
179+
180+
iact
176181
}
177182

178183

0 commit comments

Comments
 (0)