I've been trying to understand Kalman filters. Here are some examples that have helped me so far:
- http://bilgin.esme.org/BitsBytes/KalmanFilterforDummies.aspx
- https://scipy-cookbook.readthedocs.io/items/KalmanFiltering.html
These use the algorithm to estimate some constant voltage. How could using a Kalman filter for this be better than just keeping a running average? Are these examples just oversimplified use cases of the filter?
(If so, what's an example where a running average doesn't suffice?)
EDIT:
For example, consider the following Java program and output. The Kalman output doesn't match the average, but they're very close. Why pick one over the other?
int N = 10; // Number of measurements // measurements with mean = .5, sigma = .1; double z[] = { 0, // place holder to start indexes at 1 0.3708435, 0.4985331, 0.4652121, 0.6829262, 0.5011293, 0.3867151, 0.6391352, 0.5533676, 0.4013915, 0.5864200 }; double Q = .000001, // Process variance R = .1*.1;// Estimation variance double[] xhat = new double[N+1],// estimated true value (posteri) xhat_prime = new double[N+1], // estimated true value (priori) p = new double[N+1], // estimated error (posteri) p_prime = new double[N+1],// estimated error (priori) k = new double[N+1]; // kalman gain double cur_ave = 0; // Initial guesses xhat[0] = 0; p[0] = 1; for(int i = 1; i <= N; i++) { // time update xhat_prime[i] = xhat[i-1]; p_prime[i] = p[i-1] + Q; // measurement update k[i] = p_prime[i]/(p_prime[i] + R); xhat[i] = xhat_prime[i] + k[i]*(z[i] - xhat_prime[i]); p[i] = (1-k[i])*p_prime[i]; // calculate running average cur_ave = (cur_ave*(i-1) + z[i])/((double)i); System.out.printf("%d\t%04f\t%04f\t%04f\n", i, z[i], xhat[i], cur_ave); }
output:
Iter Input Kalman Average 1 0.370844 0.367172 0.370844 2 0.498533 0.432529 0.434688 3 0.465212 0.443389 0.444863 4 0.682926 0.503145 0.504379 5 0.501129 0.502742 0.503729 6 0.386715 0.483419 0.484227 7 0.639135 0.505661 0.506356 8 0.553368 0.511628 0.512233 9 0.401392 0.499365 0.499917 10 0.586420 0.508087 0.508567