diff --git a/07_Kalman_Filter_Math/Kalman_Filter_Math.ipynb b/07_Kalman_Filter_Math/Kalman_Filter_Math.ipynb index 5a8d86f..05cd0cc 100644 --- a/07_Kalman_Filter_Math/Kalman_Filter_Math.ipynb +++ b/07_Kalman_Filter_Math/Kalman_Filter_Math.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:b7f65a1b7640cd43f95156970a5c73ee923fb430d06acbc4debe6508e5327549" + "signature": "sha256:dc1d96fdfafdd06f5b65eb11a1bda31f0fd112f7cceaa954c22732296e2889b1" }, "nbformat": 3, "nbformat_minor": 0, @@ -43,6 +43,8 @@ "html": [ "\n", + "\n" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 1, + "text": [ + "" + ] + } + ], + "prompt_number": 1 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## NumPy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SymPy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "SymPy is a Python package for performing symbolic mathematics. The full scope of its abilities are beyond this book, but it can perform algebra, integrate and differentiate equations, find solutions to differential equations, and much more. For example, we use use to to compute the Jacobian of matrices and the expected value integral computations.\n", + "\n", + "First, a simple example. We will import SymPy, initialize its pretty print functionality (which will print equations using LaTeX). We will then declare a symbol for Numpy to use." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "import sympy\n", + "from sympy import init_printing\n", + "#from sympy.interactive import printing\n", + "init_printing(use_latex='mathjax')\n", + "\n", + "phi, x = sympy.symbols('\\phi, x')\n", + "phi" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$\\phi$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 2, + "text": [ + "\\phi" + ] + } + ], + "prompt_number": 2 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice how we use a latex expression for the symbol `phi`. This is not necessary, but if you do it will render as LaTeX when output. Now let's do some math. What is the derivative of $\\sqrt{\\phi}$?" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "sympy.diff('sqrt(phi)')" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$\\frac{1}{2 \\sqrt{\\phi}}$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 3, + "text": [ + " 1 \n", + "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n", + " ___\n", + "2\u22c5\u2572\u2571 \u03c6 " + ] + } + ], + "prompt_number": 3 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can factor equations" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "sympy.factor(phi**3 -phi**2 + phi - 1)" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$\\left(\\phi - 1\\right) \\left(\\phi^{2} + 1\\right)$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 4, + "text": [ + " \u239b 2 \u239e\n", + "(\\phi - 1)\u22c5\u239d\\phi + 1\u23a0" + ] + } + ], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and we can expand them." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "((phi+1)*(phi-4)).expand()" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$\\phi^{2} - 3 \\phi - 4$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 8, + "text": [ + " 2 \n", + "\\phi - 3\u22c5\\phi - 4" + ] + } + ], + "prompt_number": 8 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can find the value of an equation by substituting in a value for a variable" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "w =x**2 -3*x +4\n", + "w.subs(x,4)" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$8$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 9, + "text": [ + "8" + ] + } + ], + "prompt_number": 9 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also use strings for equations that use symbols that you have not defined" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "x = sympy.expand('(t+1)*2')\n", + "x" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$2 t + 2$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 14, + "text": [ + "2\u22c5t + 2" + ] + } + ], + "prompt_number": 14 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's use SymPy to compute the Jacobian of a matrix. Let us have a function\n", + "\n", + "$$h=\\sqrt{(x^2 + z^2)}$$\n", + "\n", + "for which we want to find the Jacobian with respect to x, y, and z." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "x, y, z = sympy.symbols('x y z')\n", + "\n", + "H = sympy.Matrix([sympy.sqrt(x**2 + z**2)])\n", + "\n", + "state = sympy.Matrix([x, y, z])\n", + "H.jacobian(state)" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$\\left[\\begin{matrix}\\frac{x}{\\sqrt{x^{2} + z^{2}}} & 0 & \\frac{z}{\\sqrt{x^{2} + z^{2}}}\\end{matrix}\\right]$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 11, + "text": [ + "\u23a1 x z \u23a4\n", + "\u23a2\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u23a5\n", + "\u23a2 _________ _________\u23a5\n", + "\u23a2 \u2571 2 2 \u2571 2 2 \u23a5\n", + "\u23a3\u2572\u2571 x + z \u2572\u2571 x + z \u23a6" + ] + } + ], + "prompt_number": 11 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's compute the discrete process noise matrix $\\mathbf{Q}_k$ given the continuous process noise matrix \n", + "$$\\mathbf{Q} = \\Phi_s \\begin{bmatrix}0&0&0\\\\0&0&0\\\\0&0&1\\end{bmatrix}$$\n", + "\n", + "and the equation\n", + "\n", + "$$\\mathbf{Q} = \\int_0^{\\Delta t} \\Phi(t)\\mathbf{Q}\\Phi^T(t) dt$$\n", + "\n", + "where \n", + "$$\\Phi(t) = \\begin{bmatrix}1 & \\Delta t & {\\Delta t}^2/2 \\\\ 0 & 1 & \\Delta t\\\\ 0& 0& 1\\end{bmatrix}$$" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "dt = sympy.symbols('\\Delta{t}')\n", + "F_k = sympy.Matrix([[1, dt, dt**2/2],\n", + " [0, 1, dt],\n", + " [0, 0, 1]])\n", + "Q = sympy.Matrix([[0,0,0],\n", + " [0,0,0],\n", + " [0,0,1]])\n", + "\n", + "sympy.integrate(F_k*Q*F_k.T,(dt, 0, dt))" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "latex": [ + "$$\\left[\\begin{matrix}\\frac{\\Delta{t}^{5}}{20} & \\frac{\\Delta{t}^{4}}{8} & \\frac{\\Delta{t}^{3}}{6}\\\\\\frac{\\Delta{t}^{4}}{8} & \\frac{\\Delta{t}^{3}}{3} & \\frac{\\Delta{t}^{2}}{2}\\\\\\frac{\\Delta{t}^{3}}{6} & \\frac{\\Delta{t}^{2}}{2} & \\Delta{t}\\end{matrix}\\right]$$" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 12, + "text": [ + "\u23a1 5 4 3\u23a4\n", + "\u23a2\\Delta{t} \\Delta{t} \\Delta{t} \u23a5\n", + "\u23a2\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u23a5\n", + "\u23a2 20 8 6 \u23a5\n", + "\u23a2 \u23a5\n", + "\u23a2 4 3 2\u23a5\n", + "\u23a2\\Delta{t} \\Delta{t} \\Delta{t} \u23a5\n", + "\u23a2\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u23a5\n", + "\u23a2 8 3 2 \u23a5\n", + "\u23a2 \u23a5\n", + "\u23a2 3 2 \u23a5\n", + "\u23a2\\Delta{t} \\Delta{t} \u23a5\n", + "\u23a2\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \\Delta{t} \u23a5\n", + "\u23a3 6 2 \u23a6" + ] + } + ], + "prompt_number": 12 + } + ], + "metadata": {} + } + ] +} \ No newline at end of file