11# #############################################################################
22#
3- # Example of fully-adapted particle filtering
3+ # Example of fully-adapted particle filtering
44# in a linear Gaussian state space model
55#
6+ #
7+ # Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.se >
8+ #
69# This program is free software; you can redistribute it and/or modify
710# it under the terms of the GNU General Public License as published by
811# the Free Software Foundation; either version 2 of the License, or
912# (at your option) any later version.
10- #
13+ #
1114# This program is distributed in the hope that it will be useful,
1215# but WITHOUT ANY WARRANTY; without even the implied warranty of
1316# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1417# GNU General Public License for more details.
15- #
18+ #
1619# You should have received a copy of the GNU General Public License along
1720# with this program; if not, write to the Free Software Foundation, Inc.,
1821# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1922#
2023# #############################################################################
2124
2225# Import helper
23- source( " stateEstimationHelper.R" )
26+ source(" stateEstimationHelper.R" )
2427
2528# Set the random seed to replicate results in tutorial
26- set.seed( 10 )
29+ set.seed(10 )
30+
2731
2832# #############################################################################
2933# Define the model
@@ -37,63 +41,104 @@ set.seed( 10 )
3741# where v[tt] ~ N(0,1) and e[tt] ~ N(0,1)
3842
3943# Set the parameters of the model
40- phi = 0.75
41- sigmav = 1.00
42- sigmae = 0.10
44+ phi <- 0.75
45+ sigmav <- 1.00
46+ sigmae <- 0.10
4347
4448# Set the number of time steps to simulate
45- T = 250
49+ T <- 250
4650
4751# Set the initial state
48- x0 = 0
52+ initialState <- 0
4953
5054# #############################################################################
5155# Generate data
5256# #############################################################################
5357
54- data <- generateData( phi , sigmav , sigmae , T , x0 )
55- x <- data $ x
56- y <- data $ y
58+ data <- generateData(c( phi , sigmav , sigmae ) , T , initialState )
59+ x <- data $ x
60+ y <- data $ y
5761
5862# Plot the latent state and observations
59- layout( matrix ( c(1 ,1 ,2 ,2 ,3 ,4 ), 3 , 2 , byrow = TRUE ) )
60- par ( mar = c(4 ,5 ,0 ,0 ) )
61-
62- grid <- seq( 0 , T )
63-
64- plot( grid , y , col = " #1B9E77" , type = " l" , xlab = " time" , ylab = " observation" , ylim = c(- 6 ,6 ) )
63+ layout(matrix (c(1 , 1 , 2 , 2 , 3 , 4 ), 3 , 2 , byrow = TRUE ))
64+ par (mar = c(4 , 5 , 0 , 0 ))
65+
66+ grid <- seq(0 , T )
67+
68+ plot(
69+ grid ,
70+ y ,
71+ col = " #1B9E77" ,
72+ type = " l" ,
73+ xlab = " time" ,
74+ ylab = " observation" ,
75+ ylim = c(- 6 , 6 ),
76+ bty = " n"
77+ )
6578
6679# ##################################################################################
6780# State estimation using the particle filter and Kalman filter
6881# ##################################################################################
6982
70- # Using N = 20 particles and plot the estimate of the latent state
71- N <- 20
72- outPF <- sm( y , phi , sigmav , sigmae , N , T , x0 )
73- outKF <- kf( y , phi , sigmav , sigmae , x0 , 0.01 )
74- diff <- outPF $ xh - outKF $ xh [ - (T + 1 ) ]
75-
76- grid <- seq( 0 , T - 1 )
77- plot( grid , diff , col = " #7570B3" , type = " l" , xlab = " time" , ylab = " difference in state estimate" , ylim = c(- 0.1 ,0.1 ) )
83+ # Using noParticles = 20 particles and plot the estimate of the latent state
84+ noParticles <- 20
85+ outputPF <- particleFilter(y , c(phi , sigmav , sigmae ), noParticles , initialState )
86+ outputKF <- kalmanFilter(y , c(phi , sigmav , sigmae ), initialState , 0.01 )
87+ difference <- outputPF $ xHatFiltered - outputKF $ xHatFiltered [- (T + 1 )]
88+
89+ grid <- seq(0 , T - 1 )
90+ plot(
91+ grid ,
92+ difference ,
93+ col = " #7570B3" ,
94+ type = " l" ,
95+ xlab = " time" ,
96+ ylab = " difference in state estimate" ,
97+ ylim = c(- 0.1 , 0.1 ),
98+ bty = " n"
99+ )
78100
79101# Compute bias and MSE
80- logBiasMSE = matrix ( 0 , nrow = 7 , ncol = 2 )
81- gridN = c( 10 , 20 , 50 , 100 , 200 , 500 , 1000 )
102+ logBiasMSE <- matrix (0 , nrow = 7 , ncol = 2 )
103+ gridN <- c( 10 , 20 , 50 , 100 , 200 , 500 , 1000 )
82104
83- for ( ii in 1 : length(gridN ) ) {
84- smEstimate <- sm(y ,phi ,sigmav ,sigmae ,gridN [ii ],T ,x0 )$ xh
85- kmEstimate <- outKF $ xh [- (T + 1 )]
105+ for (ii in 1 : length(gridN )) {
106+ pfEstimate <- particleFilter(y , c(phi , sigmav , sigmae ), gridN [ii ], initialState )
107+ pfEstimate <- pfEstimate $ xHatFiltered
108+ kfEstimate <- outputKF $ xHatFiltered [- (T + 1 )]
86109
87- logBiasMSE [ ii , 1 ] <- log( mean( abs( smEstimate - kmEstimate ) ) )
88- logBiasMSE [ ii , 2 ] <- log( mean( ( smEstimate - kmEstimate )^ 2 ) )
110+ logBiasMSE [ii , 1 ] <- log(mean(abs(pfEstimate - kfEstimate )))
111+ logBiasMSE [ii , 2 ] <- log(mean(( pfEstimate - kfEstimate )^ 2 ) )
89112}
90113
91114# Plot the bias and MSE for comparison
92- plot( gridN , logBiasMSE [ , 1 ], col = " #E7298A" , type = " l" , xlab = " no. particles (N)" , ylab = " log-bias" , ylim = c(- 7 ,- 3 ) )
93- points( gridN , logBiasMSE [ , 1 ], col = " #E7298A" , pch = 19 )
94-
95- plot( gridN , logBiasMSE [ , 2 ], col = " #66A61E" , lwd = 1.5 , type = " l" , xlab = " no. particles (N)" , ylab = " log-MSE" , ylim = c(- 12 ,- 6 ) )
96- points( gridN , logBiasMSE [ , 2 ], col = " #66A61E" , pch = 19 )
115+ plot(
116+ gridN ,
117+ logBiasMSE [, 1 ],
118+ col = " #E7298A" ,
119+ type = " l" ,
120+ xlab = " no. particles (N)" ,
121+ ylab = " log-bias" ,
122+ ylim = c(- 7 , - 3 ),
123+ bty = " n"
124+ )
125+ points(gridN , logBiasMSE [, 1 ], col = " #E7298A" , pch = 19 )
126+
127+ plot(
128+ gridN ,
129+ logBiasMSE [, 2 ],
130+ col = " #66A61E" ,
131+ lwd = 1.5 ,
132+ type = " l" ,
133+ xlab = " no. particles (N)" ,
134+ ylab = " log-MSE" ,
135+ ylim = c(- 12 , - 6 ),
136+ bty = " n"
137+ )
138+ points(gridN , logBiasMSE [, 2 ], col = " #66A61E" , pch = 19 )
139+
140+ # Save the workspace to file
141+ save(" example1-lgss.RData" )
97142
98143# ##################################################################################
99144# End of file
0 commit comments