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