Skip to content

Commit

Permalink
minor update
Browse files Browse the repository at this point in the history
  • Loading branch information
mattiasvillani committed Dec 18, 2023
1 parent 5645470 commit 9af71e3
Show file tree
Hide file tree
Showing 4 changed files with 3 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/search.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,6 @@
"href": "tutorial/statespace/statespace.html#bonus-implementing-the-kalman-filter-from-scratch",
"title": "State-space models - filtering, smoothing and forecasting",
"section": "Bonus: Implementing the Kalman filter from scratch",
"text": "Bonus: Implementing the Kalman filter from scratch\nFor the curious, the code below implements the Kalman filter from scratch in R. Let us first implement a function kalmanfilter_update that does the update for a single time step:\n\nkalmanfilter_update <- function(mu, Omega, y, G, C, V, W) {\n \n # Prediction step - moving state forward without new measurement\n muPred <- G %*% mu\n omegaPred <- G %*% Omega %*% t(G) + W\n \n # Measurement update - updating the N(muPred, omegaPred) prior with the new data point\n K <- omegaPred %*% t(F) / (F %*% omegaPred %*% t(F) + V) # Kalman Gain\n mu <- muPred + K %*% (y - F %*% muPred)\n Omega <- (diag(length(mu)) - K %*% F) %*% omegaPred\n \n return(list(mu, Omega))\n}\n\nThen a function does all the Kalman iterations, using the kalmanfilter_update function above:\n\nkalmanfilter <- function(Y, G, F, V, W, mu0, Sigma0) {\n T <- dim(Y)[1] # Number of time steps\n n <- length(mu0) # Dimension of the state vector\n \n # Storage for the mean and covariance state vector trajectory over time\n mu_filter <- matrix(0, nrow = T, ncol = n)\n Sigma_filter <- array(0, dim = c(n, n, T))\n \n # The Kalman iterations\n mu <- mu0\n Sigma <- Sigma0\n for (t in 1:T) {\n result <- kalmanfilter_update(mu, Sigma, t(Y[t, ]), G, F, V, W)\n mu <- result[[1]]\n Sigma <- result[[2]]\n mu_filter[t, ] <- mu\n Sigma_filter[,,t] <- Sigma\n }\n \n return(list(mu_filter, Sigma_filter))\n}\n\nLet’s try it out on the Nile river data:\n\n# Analyzing the Nile river data\nprettycolors = c(\"#6C8EBF\", \"#c0a34d\", \"#780000\")\ny = as.vector(Nile)\nV = 100^2\nW = 100^2\nmu0 = 1000\nSigma0 = 1000^2\n\n# Set up state-space model for local level model\nT = length(y)\nG = 1\nF = 1\nY = matrix(0,T,1)\nY[,1] = y\nfilterRes = kalmanfilter(Y, G, F, V, W, mu0, Sigma0)\nmeanFilter = filterRes[[1]]\nstd_filter = sqrt(filterRes[[2]][,,, drop =TRUE])\n\nplot(seq(1:T), y, type = \"l\", col = prettycolors[1], lwd = 1.5, xlab = \"time, t\")\npolygon(c(seq(1:T), rev(seq(1:T))), \n c(meanFilter - 1.96*std_filter, rev(meanFilter + 1.96*std_filter)), \n col = \"#F0F0F0\", border = NA)\nlines(seq(1:T), y, type = \"l\", col = prettycolors[1], lwd = 1.5, xlab = \"time, t\")\nlines(seq(1:T), meanFilter, type = \"l\", col = prettycolors[3], lwd = 1.5)\nlegend(\"topright\", legend = c(\"time series\", \"filter mean\", \"95% intervals\"), lty = 1, lwd = 1.5,\n col = c(prettycolors[1], prettycolors[3], \"#F0F0F0\"))"
"text": "Bonus: Implementing the Kalman filter from scratch\nFor the curious, the code below implements the Kalman filter from scratch in R. Let us first implement a function kalmanfilter_update that does the update for a single time step:\n\nkalmanfilter_update <- function(mu, Omega, y, G, C, V, W) {\n \n # Prediction step - moving state forward without new measurement\n muPred <- G %*% mu\n omegaPred <- G %*% Omega %*% t(G) + W\n \n # Measurement update - updating the N(muPred, omegaPred) prior with the new data point\n K <- omegaPred %*% t(F) / (F %*% omegaPred %*% t(F) + V) # Kalman Gain\n mu <- muPred + K %*% (y - F %*% muPred)\n Omega <- (diag(length(mu)) - K %*% F) %*% omegaPred\n \n return(list(mu, Omega))\n}\n\nThen we implement a function that does all the Kalman iterations, using the kalmanfilter_update function above:\n\nkalmanfilter <- function(Y, G, F, V, W, mu0, Sigma0) {\n T <- dim(Y)[1] # Number of time steps\n n <- length(mu0) # Dimension of the state vector\n \n # Storage for the mean and covariance state vector trajectory over time\n mu_filter <- matrix(0, nrow = T, ncol = n)\n Sigma_filter <- array(0, dim = c(n, n, T))\n \n # The Kalman iterations\n mu <- mu0\n Sigma <- Sigma0\n for (t in 1:T) {\n result <- kalmanfilter_update(mu, Sigma, t(Y[t, ]), G, F, V, W)\n mu <- result[[1]]\n Sigma <- result[[2]]\n mu_filter[t, ] <- mu\n Sigma_filter[,,t] <- Sigma\n }\n \n return(list(mu_filter, Sigma_filter))\n}\n\nLet’s try it out on the Nile river data:\n\n# Analyzing the Nile river data\nprettycolors = c(\"#6C8EBF\", \"#c0a34d\", \"#780000\")\ny = as.vector(Nile)\nV = 100^2\nW = 100^2\nmu0 = 1000\nSigma0 = 1000^2\n\n# Set up state-space model for local level model\nT = length(y)\nG = 1\nF = 1\nY = matrix(0,T,1)\nY[,1] = y\nfilterRes = kalmanfilter(Y, G, F, V, W, mu0, Sigma0)\nmeanFilter = filterRes[[1]]\nstd_filter = sqrt(filterRes[[2]][,,, drop =TRUE])\n\nplot(seq(1:T), y, type = \"l\", col = prettycolors[1], lwd = 1.5, xlab = \"time, t\")\npolygon(c(seq(1:T), rev(seq(1:T))), \n c(meanFilter - 1.96*std_filter, rev(meanFilter + 1.96*std_filter)), \n col = \"#F0F0F0\", border = NA)\nlines(seq(1:T), y, type = \"l\", col = prettycolors[1], lwd = 1.5, xlab = \"time, t\")\nlines(seq(1:T), meanFilter, type = \"l\", col = prettycolors[3], lwd = 1.5)\nlegend(\"topright\", legend = c(\"time series\", \"filter mean\", \"95% intervals\"), lty = 1, lwd = 1.5,\n col = c(prettycolors[1], prettycolors[3], \"#F0F0F0\"))"
}
]
2 changes: 1 addition & 1 deletion docs/tutorial/statespace/statespace.html
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ <h2 class="anchored" data-anchor-id="bonus-implementing-the-kalman-filter-from-s
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a> <span class="fu">return</span>(<span class="fu">list</span>(mu, Omega))</span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a>}</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Then a function does all the Kalman iterations, using the <code>kalmanfilter_update</code> function above:</p>
<p>Then we implement a function that does all the Kalman iterations, using the <code>kalmanfilter_update</code> function above:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb20"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>kalmanfilter <span class="ot">&lt;-</span> <span class="cf">function</span>(Y, G, F, V, W, mu0, Sigma0) {</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a> T <span class="ot">&lt;-</span> <span class="fu">dim</span>(Y)[<span class="dv">1</span>] <span class="co"># Number of time steps</span></span>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion tutorial/statespace/statespace.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ kalmanfilter_update <- function(mu, Omega, y, G, C, V, W) {
}
```
Then a function does all the Kalman iterations, using the `kalmanfilter_update` function above:
Then we implement a function that does all the Kalman iterations, using the `kalmanfilter_update` function above:
```{r}
kalmanfilter <- function(Y, G, F, V, W, mu0, Sigma0) {
Expand Down

0 comments on commit 9af71e3

Please sign in to comment.