Moved naming conventions to FilterPy project.

That had no business in the book. I put it in the documentation
for filterPy.
This commit is contained in:
Roger Labbe 2015-07-16 08:16:05 -07:00
parent 335df7f42d
commit 60c17168b0

View File

@ -358,7 +358,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Host the Book Online for Free\n",
"## Host the Book Online for Free at SageMath\n",
"\n",
"Maybe you don't want to, or can't install IPython and associated libraries on your device, or maybe you move from device to device a lot and don't want to distribute the work you are doing in the book in multiple places. Maybe you have high school students with Chromebooks, and you want them to be able to run the code, and write new code for exercises you devise. Wouldn't it be nice if the book was in the cloud?\n",
"\n",
@ -537,54 +537,7 @@
"\n",
"A possible downside is that the equations that perform the filtering are hidden behind functions, which we could argue is a loss in a pedagogical text. I argue the converse. I want you to learn how to use Kalman filters in the real world, for real projects, and you shouldn't be cutting and pasting established algorithms all over the place. If you want to use Runge Kutta you call `ode45`, you don't re-implement it from scratch. We will do the same here.\n",
"\n",
"I use Python classes. I do not use inheritance or virtual functions or any of that sort of object oriented design. I use classes as a way to organize the data that the filters require. For example, the `KalmanFilter` class stores matrices called `x`, `P`, `R`, `Q`. I've seen procedural libraries for Kalman filters, and they require the programmer to maintain all of those matrices. This perhaps isn't so bad for a toy program, but program a bank of Kalman filters and you will not enjoy having to manage all of those matrices and other associated data.\n",
"\n",
"\n",
"## FilterPy's Naming Conventions\n",
"\n",
"A word on variable names. I am an advocate for descriptive variable names. In the Kalman filter literature the measurement noise covariance matrix is called `R`. The name `R` is not descriptive. I could reasonably call it `measurement_noise_covariance`, and I've seen libraries do that. I've chosen not to.\n",
"\n",
"In the end, Kalman filtering is math. To write a Kalman filter you are going to start by sitting down with a piece of paper and doing math. You will be writing and solving normal algebraic equations. Every Kalman filter text and source on the web uses the same equations. You cannot read about the Kalman filter without seeing this equation\n",
"\n",
"$$\\dot{\\mathbf{x}} = \\mathbf{Fx} + \\mathbf{Gu} + w$$\n",
"\n",
"One of my goals in this book is to bring you to the point where you can read the original literature on Kalman filtering. I take an optimistic tone in this book - that Kalman filtering is easy to learn - and in many ways it is. However, for nontrivial problems the difficulty is not the implementation of the equations, but learning how to set up the equations so they solve your problem. In other words, every Kalman filter implements $\\dot{\\mathbf{x}} = \\mathbf{Fx} + \\mathbf{Gu} + w$; the difficult part is figuring out what to put in the matrices $\\mathbf{F}$ and $\\mathbf{G}$ to make your filter work for your problem. Vast amounts of work have been done to apply Kalman filters in various domains, and it would be tragic to be unable to avail yourself of this research. \n",
"\n",
"I use the same equations in my book. You will need to know the variable names to understand them.\n",
"\n",
"So, like it or not you will need to learn that $\\mathbf{F}$ is the *state transition matrix* and that $\\mathbf{R}$ is the *measurement noise covariance*. Once you know that the code will become readable, and until then this book's math, and all publications and web articles on Kalman filters will be inaccessible to you. \n",
"\n",
"Finally, I think that mathematical programming is somewhat different than regular programming; what is readable in one domain is not readable in another. `q = x + m` is opaque in a normal context. On the other hand, `x = (.5*a)*t**2 + v_0*t + x_0` is to me the most readable way to program the Newtonian distance equation:\n",
"\n",
"$$ x = \\frac{1}{2}at^2 + v_0 t + x_0$$\n",
"\n",
"We could write it as \n",
"\n",
" distance = (.5 * constant_acceleration) * time_delta**2 + \n",
" initial_velocity * time_delta + initial_distance\n",
" \n",
"but I feel that obscures readability. This is debatable for this one equation; but most mathematical programs, and certainly Kalman filters, use systems of equations. I can most easily follow the code, and ensure that it does not have bugs, when it reads as close to the math as possible. Consider this equation from the Kalman filter:\n",
"\n",
"$$\\mathbf{K} = \\mathbf{PH}^\\mathsf{T}[\\mathbf{HPH}^\\mathsf{T} + \\mathbf{R}]^{-1}$$\n",
"\n",
"Python code for this would be\n",
"\n",
" K = dot(P, H.T).dot(inv(dot(H, P).dot(H.T) + R))\n",
" \n",
"It's already a bit hard to read because of the `dot` function calls (required because Python does not yet support an operator for matrix multiplication). But compare this to\n",
"\n",
" kalman_gain = (\n",
" dot(apriori_state_covariance, measurement_function_transpose).dot(\n",
" inv(dot(measurement_function, apriori_state_covariance).dot(\n",
" measurement_function_transpose) + measurement_noise_covariance)))\n",
"\n",
"which I adapted from a popular library. I grant you this version has more context, but I cannot glance at this and see what math it is implementing. In particular, the linear algebra $\\mathbf{HPH}^\\mathsf{T}$ is doing something very specific - multiplying $\\mathbf{P}$ by $\\mathbf{H}$ in a way that converts $\\mathbf{P}$ from *world space* to *measurement space* (we'll learn what that means). It is nearly impossible to see that the Kalman gain (`K`) is just a ratio of one number divided by a second number which has been converted to a different basis. This statement may not convey a lot of information to you before reading the book, but I assure you that $\\mathbf{K} = \\mathbf{PH}^\\mathsf{T}[\\mathbf{HPH}^\\mathsf{T} + \\mathbf{R}]^{-1}$ is saying something very succinctly. There are two key pieces of information here - we are finding a ratio, and we are doing it in measurement space. I can see that in my first Python line, I cannot see that in the second line. If you want a counter-argument, my version obscures the information that $\\mathbf{P}$ is in this context is a *prior* (we will learn what a *prior* is in the book). \n",
"\n",
"These comments apply to library code. The book's examples uses names like `sensor_noise`, or `gps_sensor_noise`, not `R`. Math code should read like math, and interface or glue code should read like normal code. Context is important.\n",
"\n",
"I will not *win* this argument, and some people will not agree with my naming choices. I will finish by stating, very truthfully, that I made two mistakes the first time I typed the second version and it took me awhile to find it. In any case, I aim for using the mathematical symbol names whenever possible, coupled with readable class and function names. So, it is `KalmanFilter.P`, not `KF.P` and not `KalmanFilter.apriori_state_covariance`. \n",
"\n",
"Let's learn some math."
"I use Python classes. I do not use inheritance or virtual functions or any of that sort of object oriented design. I use classes as a way to organize the data that the filters require. For example, the `KalmanFilter` class stores matrices called `x`, `P`, `R`, `Q`. I've seen procedural libraries for Kalman filters, and they require the programmer to maintain all of those matrices. This perhaps isn't so bad for a toy program, but program a bank of Kalman filters and you will not enjoy having to manage all of those matrices and other associated data."
]
},
{
@ -654,7 +607,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.4.3"
"version": "3.4.1"
}
},
"nbformat": 4,