{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "[Table of Contents](./table_of_contents.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Discrete Bayes Filter" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#format the book\n", "import book_format\n", "book_format.set_style()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Kalman filter belongs to a family of filters called *Bayesian filters*. Most textbook treatments of the Kalman filter present the Bayesian formula, perhaps shows how it factors into the Kalman filter equations, but mostly keeps the discussion at a very abstract level. \n", "\n", "That approach requires a fairly sophisticated understanding of several fields of mathematics, and it still leaves much of the work of understanding and forming an intuitive grasp of the situation in the hands of the reader.\n", "\n", "I will use a different way to develop the topic, to which I owe the work of Dieter Fox and Sebastian Thrun a great debt. It depends on building an intuition on how Bayesian statistics work by tracking an object through a hallway - they use a robot, I use a dog. I like dogs, and they are less predictable than robots which imposes interesting difficulties for filtering. The first published example of this that I can find seems to be Fox 1999 [1], with a fuller example in Fox 2003 [2]. Sebastian Thrun also uses this formulation in his excellent Udacity course Artificial Intelligence for Robotics [3]. In fact, if you like watching videos, I highly recommend pausing reading this book in favor of first few lessons of that course, and then come back to this book for a deeper dive into the topic.\n", "\n", "Let's now use a simple thought experiment, much like we did with the g-h filter, to see how we might reason about the use of probabilities for filtering and tracking." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tracking a Dog\n", "\n", "Let's begin with a simple problem. We have a dog friendly workspace, and so people bring their dogs to work. Occasionally the dogs wander out of offices and down the halls. We want to be able to track them. So during a hackathon somebody invented a sonar sensor to attach to the dog's collar. It emits a signal, listens for the echo, and based on how quickly an echo comes back we can tell whether the dog is in front of an open doorway or not. It also senses when the dog walks, and reports in which direction the dog has moved. It connects to the network via wifi and sends an update once a second.\n", "\n", "I want to track my dog Simon, so I attach the device to his collar and then fire up Python, ready to write code to track him through the building. At first blush this may appear impossible. If I start listening to the sensor of Simon's collar I might read **door**, **hall**, **hall**, and so on. How can I use that information to determine where Simon is?\n", "\n", "To keep the problem small enough to plot easily we will assume that there are only 10 positions in the hallway, which we will number 0 to 9, where 1 is to the right of 0. For reasons that will be clear later, we will also assume that the hallway is circular or rectangular. If you move right from position 9, you will be at position 0. \n", "\n", "When I begin listening to the sensor I have no reason to believe that Simon is at any particular position in the hallway. From my perspective he is equally likely to be in any position. There are 10 positions, so the probability that he is in any given position is 1/10. \n", "\n", "Let's represent our belief of his position in a NumPy array. I could use a Python list, but NumPy arrays offer functionality that we will be using soon." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]\n" ] } ], "source": [ "import numpy as np\n", "belief = np.array([1/10]*10)\n", "print(belief)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In [Bayesian statistics](https://en.wikipedia.org/wiki/Bayesian_probability) this is called a [*prior*](https://en.wikipedia.org/wiki/Prior_probability). It is the probability prior to incorporating measurements or other information. More completely, this is called the *prior probability distribution*. A [*probability distribution*](https://en.wikipedia.org/wiki/Probability_distribution) is a collection of all possible probabilities for an event. Probability distributions always sum to 1 because something had to happen; the distribution lists all possible events and the probability of each.\n", "\n", "I'm sure you've used probabilities before - as in \"the probability of rain today is 30%\". The last paragraph sounds like more of that. But Bayesian statistics was a revolution in probability because it treats probability as a belief about a single event. Let's take an example. I know that if I flip a fair coin infinitely many times I will get 50% heads and 50% tails. This is called [*frequentist statistics*](https://en.wikipedia.org/wiki/Frequentist_inference) to distinguish it from Bayesian statistics. Computations are based on the frequency in which events occur.\n", "\n", "I flip the coin one more time and let it land. Which way do I believe it landed? Frequentist probability has nothing to say about that; it will merely state that 50% of coin flips land as heads. In some ways it is meaningless to assign a probability to the current state of the coin. It is either heads or tails, we just don't know which. Bayes treats this as a belief about a single event - the strength of my belief or knowledge that this specific coin flip is heads is 50%. Some object to the term \"belief\"; belief can imply holding something to be true without evidence. In this book it always is a measure of the strength of our knowledge. We'll learn more about this as we go.\n", "\n", "Bayesian statistics takes past information (the prior) into account. We observe that it rains 4 times every 100 days. From this I could state that the chance of rain tomorrow is 1/25. This is not how weather prediction is done. If I know it is raining today and the storm front is stalled, it is likely to rain tomorrow. Weather prediction is Bayesian.\n", "\n", "In practice statisticians use a mix of frequentist and Bayesian techniques. Sometimes finding the prior is difficult or impossible, and frequentist techniques rule. In this book we can find the prior. When I talk about the probability of something I am referring to the probability that some specific thing is true given past events. When I do that I'm taking the Bayesian approach.\n", "\n", "Now let's create a map of the hallway. We'll place the first two doors close together, and then another door further away. We will use 1 for doors, and 0 for walls:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "hallway = np.array([1, 1, 0, 0, 0, 0, 0, 0, 1, 0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I start listening to Simon's transmissions on the network, and the first data I get from the sensor is **door**. For the moment assume the sensor always returns the correct answer. From this I conclude that he is in front of a door, but which one? I have no reason to believe he is in front of the first, second, or third door. What I can do is assign a probability to each door. All doors are equally likely, and there are three of them, so I assign a probability of 1/3 to each door. " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "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RbWTpHL33XfXuoya2rBhQyVJZcWKFbUupab+5E/+pHLdddfVuow+tXXr1sqxxx5baW9vr3zoQx+qXHjhhbUuqU995StfqZx44om1LqNmLrnkksrJJ59c6zKKcuGFF1aOOeaYyq5du2pdSp85/fTTK1OnTu2x9qlPfaryuc99rkYV9a1t27ZV+vXrV/mXf/mXHusnnnhiZc6cOTWqqgzutNfY9u3bs2rVqrS2tvZYb21tzcMPP1yjqqilzZs3J0kOPfTQGldSGzt37sxtt92WF198MePHj691OX1q5syZOf300/ORj3yk1qXUzFNPPZURI0akubk5n/3sZ/P000/XuqQ+c++992bcuHH5zGc+k8MOOyzvfe9788///M+1Lqtmtm/fnptvvjlTp05NQ0NDrcvpMyeffHL+7d/+Lb/61a+SJL/85S/z4IMP5mMf+1iNK+sbO3bsyM6dOzNo0KAe6wceeGAefPDBGlVVhqp/Iiqvr40bN2bnzp1pamrqsd7U1JT169fXqCpqpVKppK2tLSeffHLGjh1b63L61GOPPZbx48fnj3/8Y97ylrfk7rvvzjvf+c5al9VnbrvttqxatSqPPvporUupmQ9+8IP53ve+l3e84x353e9+lyuuuCITJkzI448/nqFDh9a6vDfc008/nUWLFqWtrS2XXXZZfv7zn+eCCy5IY2NjpkyZUuvy+tw999yT559/Pp///OdrXUqfuuSSS7J58+Ycf/zx6devX3bu3Jmvfe1r+au/+qtal9YnDj744IwfPz5f/epXM2bMmDQ1NeXWW2/Nf/zHf+TYY4+tdXk1JbQX4n/fRahUKnV1Z4GXfPGLX8x//ud/1uXdhOOOOy5r1qzJ888/nzvvvDPnnHNOVqxYURfB/Te/+U0uvPDCLF++vNfdpXoyadKk7v/9rne9K+PHj88xxxyT7373u2lra6thZX1j165dGTduXK688sokyXvf+948/vjjWbRoUV2G9iVLlmTSpEkZMWJErUvpU0uXLs3NN9+cW265JSeccELWrFmTWbNmZcSIETnnnHNqXV6fuOmmmzJ16tQcccQR6devX973vvflrLPOyi9+8Ytal1ZTQnuNDRs2LP369et1V33Dhg297r6zfzv//PNz77335oEHHsiRRx5Z63L63MCBA/P2t789STJu3Lg88sgj+da3vpXvfOc7Na7sjbdq1aps2LAhLS0t3Ws7d+7MAw88kKuvvjqdnZ3p169fDSusjYMOOijvete78tRTT9W6lD4xfPjwXn9JHTNmTO68884aVVQ7zz77bP71X/81d911V61L6XMXX3xxZs+enc9+9rNJXvoL7LPPPpv58+fXTWg/5phjsmLFirz44ovZsmVLhg8fnsmTJ6e5ubnWpdWUZ9prbODAgWlpael+h/xu7e3tmTBhQo2qoi9VKpV88YtfzF133ZV///d/r/v/U9qtUqmks7Oz1mX0iQ9/+MN57LHHsmbNmu6vcePG5a//+q+zZs2augzsSdLZ2Zm1a9dm+PDhtS6lT5x00km9Pu71V7/6VUaPHl2jimrnhhtuyGGHHZbTTz+91qX0uW3btuWAA3rGs379+tXVRz7udtBBB2X48OH5wx/+kPvuuy+f+MQnal1STbnTXoC2tracffbZGTduXMaPH5/Fixdn3bp1mT59eq1L6xMvvPBCfv3rX3cfP/PMM1mzZk0OPfTQjBo1qoaV9Y2ZM2fmlltuyQ9+8IMcfPDB3f/qcsghh+TAAw+scXV947LLLsukSZMycuTIbN26Nbfddlvuv//+/PjHP651aX3i4IMP7vUehoMOOihDhw6tq/c2fOlLX8oZZ5yRUaNGZcOGDbniiiuyZcuWurm7eNFFF2XChAm58sorc+aZZ+bnP/95Fi9enMWLF9e6tD61a9eu3HDDDTnnnHPSv3/9xZQzzjgjX/va1zJq1KiccMIJWb16da666qpMnTq11qX1mfvuuy+VSiXHHXdcfv3rX+fiiy/Occcdl3PPPbfWpdVWTT+7hm7XXHNNZfTo0ZWBAwdW3ve+99XVx/395Cc/qSTp9XXOOefUurQ+safek1RuuOGGWpfWZ6ZOndr9+n/b295W+fCHP1xZvnx5rcuqqXr8yMfJkydXhg8fXhkwYEBlxIgRlU996lOVxx9/vNZl9akf/vCHlbFjx1YaGxsrxx9/fGXx4sW1LqnP3XfffZUklSeffLLWpdTEli1bKhdeeGFl1KhRlUGDBlWOPvroypw5cyqdnZ21Lq3PLF26tHL00UdXBg4cWDn88MMrM2fOrDz//PO1LqvmGiqVSqU2f10AAAD2hmfaAQCgcEI7AAAUTmgHAIDCCe0AAFA4oR0AAAontAMAQOGEdgAAKJzQDgAAhRPaAQCgcEI7AAAUTmgHAIDCCe0AAFC4/x8ZaxCqnqE58QAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import kf_book.book_plots as book_plots\n", "from kf_book.book_plots import figsize, set_figsize\n", "import matplotlib.pyplot as plt\n", "\n", "belief = np.array([1/3, 1/3, 0, 0, 0, 0, 0, 0, 1/3, 0])\n", "book_plots.bar_plot(belief)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This distribution is called a [*categorical distribution*](https://en.wikipedia.org/wiki/Categorical_distribution), which is a discrete distribution describing the probability of observing $n$ outcomes. It is a [*multimodal distribution*](https://en.wikipedia.org/wiki/Multimodal_distribution) because we have multiple beliefs about the position of our dog. Of course we are not saying that we think he is simultaneously in three different locations, merely that we have narrowed down our knowledge to one of these three locations. My (Bayesian) belief is that there is a 33.3% chance of being at door 0, 33.3% at door 1, and a 33.3% chance of being at door 8.\n", "\n", "This is an improvement in two ways. I've rejected a number of hallway positions as impossible, and the strength of my belief in the remaining positions has increased from 10% to 33%. This will always happen. As our knowledge improves the probabilities will get closer to 100%.\n", "\n", "A few words about the [*mode*](https://en.wikipedia.org/wiki/Mode_%28statistics%29)\n", "of a distribution. Given a list of numbers, such as {1, 2, 2, 2, 3, 3, 4}, the *mode* is the number that occurs most often. For this set the mode is 2. A distribution can contain more than one mode. The list {1, 2, 2, 2, 3, 3, 4, 4, 4} contains the modes 2 and 4, because both occur three times. We say the former list is [*unimodal*](https://en.wikipedia.org/wiki/Unimodality), and the latter is *multimodal*.\n", "\n", "Another term used for this distribution is a [*histogram*](https://en.wikipedia.org/wiki/Histogram). Histograms graphically depict the distribution of a set of numbers. The bar chart above is a histogram.\n", "\n", "I hand coded the `belief` array in the code above. How would we implement this in code? We represent doors with 1, and walls as 0, so we will multiply the hallway variable by the percentage, like so;" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.333 0.333 0. 0. 0. 0. 0. 0. 0.333 0. ]\n" ] } ], "source": [ "belief = hallway * (1/3)\n", "print(belief)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extracting Information from Sensor Readings\n", "\n", "Let's put Python aside and think about the problem a bit. Suppose we were to read the following from Simon's sensor:\n", "\n", " * door\n", " * move right\n", " * door\n", " \n", "\n", "Can we deduce Simon's location? Of course! Given the hallway's layout there is only one place from which you can get this sequence, and that is at the left end. Therefore we can confidently state that Simon is in front of the second doorway. If this is not clear, suppose Simon had started at the second or third door. After moving to the right, his sensor would have returned 'wall'. That doesn't match the sensor readings, so we know he didn't start there. We can continue with that logic for all the remaining starting positions. The only possibility is that he is now in front of the second door. Our belief is:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "belief = np.array([0., 1., 0., 0., 0., 0., 0., 0., 0., 0.])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I designed the hallway layout and sensor readings to give us an exact answer quickly. Real problems are not so clear cut. But this should trigger your intuition - the first sensor reading only gave us low probabilities (0.333) for Simon's location, but after a position update and another sensor reading we know more about where he is. You might suspect, correctly, that if you had a very long hallway with a large number of doors that after several sensor readings and positions updates we would either be able to know where Simon was, or have the possibilities narrowed down to a small number of possibilities. This is possible when a set of sensor readings only matches one to a few starting locations.\n", "\n", "We could implement this solution now, but instead let's consider a real world complication to the problem." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Noisy Sensors\n", "\n", "Perfect sensors are rare. Perhaps the sensor would not detect a door if Simon sat in front of it while scratching himself, or misread if he is not facing down the hallway. Thus when I get **door** I cannot use 1/3 as the probability. I have to assign less than 1/3 to each door, and assign a small probability to each blank wall position. Something like\n", "\n", "```Python\n", "[.31, .31, .01, .01, .01, .01, .01, .01, .31, .01]\n", "```\n", "\n", "At first this may seem insurmountable. If the sensor is noisy it casts doubt on every piece of data. How can we conclude anything if we are always unsure?\n", "\n", "The answer, as for the problem above, is with probabilities. We are already comfortable assigning a probabilistic belief to the location of the dog; now we have to incorporate the additional uncertainty caused by the sensor noise. \n", "\n", "Say we get a reading of **door**, and suppose that testing shows that the sensor is 3 times more likely to be right than wrong. We should scale the probability distribution by 3 where there is a door. If we do that the result will no longer be a probability distribution, but we will learn how to fix that in a moment.\n", "\n", "Let's look at that in Python code. Here I use the variable `z` to denote the measurement. `z` or `y` are customary choices in the literature for the measurement. As a programmer I prefer meaningful variable names, but I want you to be able to read the literature and/or other filtering code, so I will start introducing these abbreviated names now." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "belief: [0.3 0.3 0.1 0.1 0.1 0.1 0.1 0.1 0.3 0.1]\n", "sum = 1.6000000000000003\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def update_belief(hall, belief, z, correct_scale):\n", " for i, val in enumerate(hall):\n", " if val == z:\n", " belief[i] *= correct_scale\n", "\n", "belief = np.array([0.1] * 10)\n", "reading = 1 # 1 is 'door'\n", "update_belief(hallway, belief, z=reading, correct_scale=3.)\n", "print('belief:', belief)\n", "print('sum =', sum(belief))\n", "plt.figure()\n", "book_plots.bar_plot(belief)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is not a probability distribution because it does not sum to 1.0. But the code is doing mostly the right thing - the doors are assigned a number (0.3) that is 3 times higher than the walls (0.1). All we need to do is normalize the result so that the probabilities correctly sum to 1.0. Normalization is done by dividing each element by the sum of all elements in the list. That is easy with NumPy:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.188, 0.188, 0.062, 0.062, 0.062, 0.062, 0.062, 0.062, 0.188,\n", " 0.062])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "belief / sum(belief)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "FilterPy implements this with the `normalize` function:\n", "\n", "```Python\n", "from filterpy.discrete_bayes import normalize\n", "normalize(belief)\n", "```\n", "\n", "It is a bit odd to say \"3 times as likely to be right as wrong\". We are working in probabilities, so let's specify the probability of the sensor being correct, and compute the scale factor from that. The equation for that is\n", "\n", "$$scale = \\frac{prob_{correct}}{prob_{incorrect}} = \\frac{prob_{correct}} {1-prob_{correct}}$$\n", "\n", "\n", "\n", "Also, the `for` loop is cumbersome. As a general rule you will want to avoid using `for` loops in NumPy code. NumPy is implemented in C and Fortran, so if you avoid for loops the result often runs 100x faster than the equivalent loop.\n", "\n", "How do we get rid of this `for` loop? NumPy lets you index arrays with boolean arrays. You create a boolean array with logical operators. We can find all the doors in the hallway with:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ True, True, False, False, False, False, False, False, True,\n", " False])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hallway == 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When you use the boolean array as an index to another array it returns only the elements where the index is `True`. Thus we can replace the `for` loop with\n", "\n", "```python\n", "belief[hall==z] *= scale\n", "```\n", "and only the elements which equal `z` will be multiplied by `scale`.\n", "\n", "Teaching you NumPy is beyond the scope of this book. I will use idiomatic NumPy constructs and explain them the first time I present them. If you are new to NumPy there are many blog posts and videos on how to use NumPy efficiently and idiomatically.\n", "\n", "Here is our improved version:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sum = 1.0\n", "probability of door = 0.1875\n", "probability of wall = 0.06249999999999999\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvYAAAFlCAYAAACA+6xQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAqG0lEQVR4nO3df1BV953/8RciXNQVtv4IYESClopEYxCMXgx2sgZcdB3b1EqbLdoqmzKYRGTarQQzFfODupso2iiGrQ2rHZXpGGuzQ1auu43oQm1Cwc1kbWsnJmQslGCqF/WbK8L5/uF4d28uGi4x9+DnPh8zdyb3w+ec+36/vRNeHi+HMMuyLAEAAAC4ow2zuwAAAAAAnx3BHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMMCggv3OnTuVlJSkqKgopaen6/jx4zfde+LECc2bN09jx47ViBEjlJKSoq1bt/rtO3jwoFJTU+VwOJSamqpDhw4NpjQAAAAgJAUc7Gtra1VcXKyysjK1tLQoKytLubm5amtr63f/qFGj9Pjjj6uhoUGnT5/Whg0btGHDBlVXV3v3NDU1KS8vT/n5+Tp16pTy8/O1fPlynTx5cvCdAQAAACEkzLIsK5AD5syZo1mzZqmqqsq7Nm3aNH3lK19RRUXFgM7xyCOPaNSoUdq7d68kKS8vT263W6+//rp3z9/+7d/qC1/4gvbv3x9IeQAAAEBIGh7I5qtXr6q5uVnr16/3Wc/JyVFjY+OAztHS0qLGxkY9++yz3rWmpiatW7fOZ9/ChQtVWVl50/N4PB55PB7v876+Pn300UcaO3aswsLCBlQLAAAAMJRZlqXu7m5NmDBBw4bd+sM2AQX7rq4u9fb2KjY21mc9NjZWHR0dtzx24sSJ+vDDD3Xt2jVt3LhRBQUF3q91dHQEfM6KigqVl5cHUj4AAABwR/rggw80ceLEW+4JKNjf8Mkr4pZlfepV8uPHj+vSpUv69a9/rfXr1+uLX/yivvnNbw76nKWlpSopKfE+v3jxoiZNmqSzZ89q9OjRgbRzx+jp6dGvfvUrPfTQQ4qIiLC7HFswA2YQ6v1LzEBiBhIzCPX+JWYghcYMuru7lZSUNKB8G1CwHzdunMLDw/2upHd2dvpdcf+kpKQkSdKMGTP05z//WRs3bvQG+7i4uIDP6XA45HA4/NbHjBmj6OjoAfVzp+np6dHIkSM1duxYY9+8n4YZMINQ719iBhIzkJhBqPcvMQMpNGZwo6+BfNQ8oLviREZGKj09XS6Xy2fd5XIpMzNzwOexLMvn8/FOp9PvnPX19QGdEwAAAAhlAX8Up6SkRPn5+crIyJDT6VR1dbXa2tpUWFgo6fpHZM6dO6c9e/ZIknbs2KFJkyYpJSVF0vX72r/wwgt64oknvOdcu3at5s+fr82bN2vp0qU6fPiwjh49qhMnTtyOHgEAAADjBRzs8/LydP78eW3atEnt7e2aPn266urqlJiYKElqb2/3uad9X1+fSktLdfbsWQ0fPlxTpkzRj370I333u9/17snMzNSBAwe0YcMGPf3005oyZYpqa2s1Z86c29AiAAAAYL5B/fBsUVGRioqK+v1aTU2Nz/MnnnjC5+r8zSxbtkzLli0bTDkAAABAyAv4N88CAAAAGHoI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEI9gAAAIABCPYAAACAAQj2AAAAgAEGFex37typpKQkRUVFKT09XcePH7/p3ldffVXZ2dkaP368oqOj5XQ6deTIEZ89NTU1CgsL83t8/PHHgykPAAAACDkBB/va2loVFxerrKxMLS0tysrKUm5urtra2vrd39DQoOzsbNXV1am5uVkPPfSQlixZopaWFp990dHRam9v93lERUUNrisAAAAgxAwP9IAtW7Zo9erVKigokCRVVlbqyJEjqqqqUkVFhd/+yspKn+fPP/+8Dh8+rNdee01paWne9bCwMMXFxQVaDgAAAAAFeMX+6tWram5uVk5Ojs96Tk6OGhsbB3SOvr4+dXd3a8yYMT7rly5dUmJioiZOnKi/+7u/87uiDwAAAODmArpi39XVpd7eXsXGxvqsx8bGqqOjY0DnePHFF3X58mUtX77cu5aSkqKamhrNmDFDbrdb27Zt07x583Tq1CklJyf3ex6PxyOPx+N97na7JUk9PT3q6ekJpK07xo2+TO1vIJgBMwj1/iVmIDEDiRmEev8SM5BCYwaB9BZmWZY10M1/+tOfdPfdd6uxsVFOp9O7/txzz2nv3r363e9+d8vj9+/fr4KCAh0+fFgPP/zwTff19fVp1qxZmj9/vrZv397vno0bN6q8vNxvfd++fRo5cuQAOwIAAACGritXrujRRx/VxYsXFR0dfcu9AV2xHzdunMLDw/2uznd2dvpdxf+k2tparV69Wj//+c9vGeoladiwYZo9e7bOnDlz0z2lpaUqKSnxPne73UpISFBOTs6nNn2n6unpkcvlUnZ2tiIiIuwuxxbMgBmEev8SM5CYgcQMQr1/iRlIoTGDG59KGYiAgn1kZKTS09Plcrn01a9+1bvucrm0dOnSmx63f/9+rVq1Svv379fixYs/9XUsy1Jra6tmzJhx0z0Oh0MOh8NvPSIiwtg/2BtCocdPwwyYQaj3LzEDiRlIzCDU+5eYgWT2DALpK+C74pSUlCg/P18ZGRlyOp2qrq5WW1ubCgsLJV2/kn7u3Dnt2bNH0vVQv2LFCm3btk1z5871Xu0fMWKEYmJiJEnl5eWaO3eukpOT5Xa7tX37drW2tmrHjh2BlgcAAACEpICDfV5ens6fP69Nmzapvb1d06dPV11dnRITEyVJ7e3tPve0f/nll3Xt2jWtWbNGa9as8a6vXLlSNTU1kqQLFy7oscceU0dHh2JiYpSWlqaGhgY98MADn7E9AAAAIDQEHOwlqaioSEVFRf1+7UZYv+GNN9741PNt3bpVW7duHUwpAAAAADSI3zwLAAAAYOgh2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGINgDAAAABiDYAwAAAAYg2AMAAAAGGFSw37lzp5KSkhQVFaX09HQdP378pntfffVVZWdna/z48YqOjpbT6dSRI0f89h08eFCpqalyOBxKTU3VoUOHBlMaAAAAEJICDva1tbUqLi5WWVmZWlpalJWVpdzcXLW1tfW7v6GhQdnZ2aqrq1Nzc7MeeughLVmyRC0tLd49TU1NysvLU35+vk6dOqX8/HwtX75cJ0+eHHxnAAAAQAgJONhv2bJFq1evVkFBgaZNm6bKykolJCSoqqqq3/2VlZX6x3/8R82ePVvJycl6/vnnlZycrNdee81nT3Z2tkpLS5WSkqLS0lItWLBAlZWVg24MAAAACCXDA9l89epVNTc3a/369T7rOTk5amxsHNA5+vr61N3drTFjxnjXmpqatG7dOp99CxcuvGWw93g88ng83udut1uS1NPTo56engHVcqe50Zep/Q0EM2AGod6/xAwkZiAxg1DvX2IGUmjMIJDeAgr2XV1d6u3tVWxsrM96bGysOjo6BnSOF198UZcvX9by5cu9ax0dHQGfs6KiQuXl5X7r9fX1Gjly5IBquVO5XC67S7AdM2AGod6/xAwkZiAxg1DvX2IGktkzuHLlyoD3BhTsbwgLC/N5blmW31p/9u/fr40bN+rw4cO66667PtM5S0tLVVJS4n3udruVkJCgnJwcRUdHD6SNO05PT49cLpeys7MVERFhdzm2YAbMINT7l5iBxAwkZhDq/UvMQAqNGdz4VMpABBTsx40bp/DwcL8r6Z2dnX5X3D+ptrZWq1ev1s9//nM9/PDDPl+Li4sL+JwOh0MOh8NvPSIiwtg/2BtCocdPwwyYQaj3LzEDiRlIzCDU+5eYgWT2DALpK6Afno2MjFR6errfP3e4XC5lZmbe9Lj9+/fr29/+tvbt26fFixf7fd3pdPqds76+/pbnBAAAAPC/Av4oTklJifLz85WRkSGn06nq6mq1tbWpsLBQ0vWPyJw7d0579uyRdD3Ur1ixQtu2bdPcuXO9V+ZHjBihmJgYSdLatWs1f/58bd68WUuXLtXhw4d19OhRnThx4nb1CQAAABgt4Ntd5uXlqbKyUps2bdL999+vhoYG1dXVKTExUZLU3t7uc0/7l19+WdeuXdOaNWsUHx/vfaxdu9a7JzMzUwcOHNArr7yi++67TzU1NaqtrdWcOXNuQ4sAAACA+Qb1w7NFRUUqKirq92s1NTU+z994440BnXPZsmVatmzZYMoBAAAAQl7AV+wBAAAADD0EewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAIO63SX8pe09E6RXStXGA+997q/Skp8c8DHMAACA6/ieCDtwxR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADAAwR4AAAAwAMEeAAAAMADBHgAAADDAoIL9zp07lZSUpKioKKWnp+v48eM33dve3q5HH31UU6dO1bBhw1RcXOy3p6amRmFhYX6Pjz/+eDDlAQAAACEn4GBfW1ur4uJilZWVqaWlRVlZWcrNzVVbW1u/+z0ej8aPH6+ysjLNnDnzpueNjo5We3u7zyMqKirQ8gAAAICQFHCw37Jli1avXq2CggJNmzZNlZWVSkhIUFVVVb/777nnHm3btk0rVqxQTEzMTc8bFhamuLg4nwcAAACAgRkeyOarV6+qublZ69ev91nPyclRY2PjZyrk0qVLSkxMVG9vr+6//34988wzSktLu+l+j8cjj8fjfe52uyVJPT096unp+Uy1QMxQQ3cGN+oaqvV93kK9f4kZSMxAYgah3n+wDdU5h8L7IJDeAgr2XV1d6u3tVWxsrM96bGysOjo6AjmVj5SUFNXU1GjGjBlyu93atm2b5s2bp1OnTik5ObnfYyoqKlReXu63Xl9fr5EjRw66lsFLteE1Pz91dXWDOIoZBJPL5bK7BFuFev8SM5CYgcQMhm7/fE8MpqH7Pvjsrly5MuC9AQX7G8LCwnyeW5bltxaIuXPnau7cud7n8+bN06xZs/TjH/9Y27dv7/eY0tJSlZSUeJ+73W4lJCQoJydH0dHRg65lsDYeeC/or/l5WrRoUcDHMIPg6OnpkcvlUnZ2tiIiIuwuJ+hCvX+JGUjMQGIGQ71/vicGx1B/H9wONz6VMhABBftx48YpPDzc7+p8Z2en31X8z2LYsGGaPXu2zpw5c9M9DodDDofDbz0iIsLYP9hgYoZDfwah/l4P9f4lZiAxA4kZhHr/wTLUZ2zy+yCQvgL64dnIyEilp6f7/XOHy+VSZmZmIKe6Jcuy1Nraqvj4+Nt2TgAAAMBkAX8Up6SkRPn5+crIyJDT6VR1dbXa2tpUWFgo6fpHZM6dO6c9e/Z4j2ltbZV0/QdkP/zwQ7W2tioyMlKpqdc/f1ZeXq65c+cqOTlZbrdb27dvV2trq3bs2HEbWgQAAADMF3Cwz8vL0/nz57Vp0ya1t7dr+vTpqqurU2JioqTrv5Dqk/e0/793t2lubta+ffuUmJio9957T5J04cIFPfbYY+ro6FBMTIzS0tLU0NCgBx544DO0BgAAAISOQf3wbFFRkYqKivr9Wk1Njd+aZVm3PN/WrVu1devWwZQCAAAAQIP4BVUAAAAAhh6CPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYACCPQAAAGAAgj0AAABgAII9AAAAYIBBBfudO3cqKSlJUVFRSk9P1/Hjx2+6t729XY8++qimTp2qYcOGqbi4uN99Bw8eVGpqqhwOh1JTU3Xo0KHBlAYAAACEpICDfW1trYqLi1VWVqaWlhZlZWUpNzdXbW1t/e73eDwaP368ysrKNHPmzH73NDU1KS8vT/n5+Tp16pTy8/O1fPlynTx5MtDyAAAAgJAUcLDfsmWLVq9erYKCAk2bNk2VlZVKSEhQVVVVv/vvuecebdu2TStWrFBMTEy/eyorK5Wdna3S0lKlpKSotLRUCxYsUGVlZaDlAQAAACEpoGB/9epVNTc3Kycnx2c9JydHjY2Ngy6iqanJ75wLFy78TOcEAAAAQsnwQDZ3dXWpt7dXsbGxPuuxsbHq6OgYdBEdHR0Bn9Pj8cjj8Xifu91uSVJPT496enoGXQuuY4ZDdwY36hqq9X3eQr1/iRlIzEBiBqHef7AN1TmHwvsgkN4CCvY3hIWF+Ty3LMtv7fM+Z0VFhcrLy/3W6+vrNXLkyM9Uy+Ck2vCan5+6urpBHMUMgsnlctldgq1CvX+JGUjMQGIGQ7d/vicG09B9H3x2V65cGfDegIL9uHHjFB4e7nclvbOz0++KeyDi4uICPmdpaalKSkq8z91utxISEpSTk6Po6OhB1zJYGw+8F/TX/DwtWrQo4GOYQXD09PTI5XIpOztbERERdpcTdKHev8QMJGYgMYOh3j/fE4NjqL8Pbocbn0oZiICCfWRkpNLT0+VyufTVr37Vu+5yubR06dJATuXD6XTK5XJp3bp13rX6+nplZmbe9BiHwyGHw+G3HhERYewfbDAxw6E/g1B/r4d6/xIzkJiBxAxCvf9gGeozNvl9EEhfAX8Up6SkRPn5+crIyJDT6VR1dbXa2tpUWFgo6fqV9HPnzmnPnj3eY1pbWyVJly5d0ocffqjW1lZFRkYqNfX6P1OtXbtW8+fP1+bNm7V06VIdPnxYR48e1YkTJwItDwAAAAhJAQf7vLw8nT9/Xps2bVJ7e7umT5+uuro6JSYmSrr+C6k+eU/7tLQ07383Nzdr3759SkxM1HvvvSdJyszM1IEDB7RhwwY9/fTTmjJlimprazVnzpzP0BoAAAAQOgb1w7NFRUUqKirq92s1NTV+a5Zlfeo5ly1bpmXLlg2mHAAAACDkBfwLqgAAAAAMPQR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwABhlmVZdhdxO7jdbsXExOjixYuKjo4O+uun7T0T9Nf8PLXkJwd8DDNgBpJZMwj1/iVmIDGDUO9fYgYSM5AGN4PbIZCMyxV7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAABHsAAADAAAR7AAAAwAAEewAAAMAAgwr2O3fuVFJSkqKiopSenq7jx4/fcv+xY8eUnp6uqKgoTZ48Wbt27fL5ek1NjcLCwvweH3/88WDKAwAAAEJOwMG+trZWxcXFKisrU0tLi7KyspSbm6u2trZ+9589e1aLFi1SVlaWWlpa9NRTT+nJJ5/UwYMHffZFR0ervb3d5xEVFTW4rgAAAIAQMzzQA7Zs2aLVq1eroKBAklRZWakjR46oqqpKFRUVfvt37dqlSZMmqbKyUpI0bdo0vfXWW3rhhRf0ta99zbsvLCxMcXFxg2wDAAAACG0BBfurV6+qublZ69ev91nPyclRY2Njv8c0NTUpJyfHZ23hwoXavXu3enp6FBERIUm6dOmSEhMT1dvbq/vvv1/PPPOM0tLSblqLx+ORx+PxPne73ZKknp4e9fT0BNIW+sEMmYHEDEK9f4kZSMwg1PuXmIHEDCT7ZhDI6wYU7Lu6utTb26vY2Fif9djYWHV0dPR7TEdHR7/7r127pq6uLsXHxyslJUU1NTWaMWOG3G63tm3bpnnz5unUqVNKTk7u97wVFRUqLy/3W6+vr9fIkSMDaes2SbXhNT8/dXV1gziKGTADyaQZhHr/EjOQmEGo9y8xA4kZSIOdwWd35cqVAe8NsyzLGujmP/3pT7r77rvV2Ngop9PpXX/uuee0d+9e/e53v/M75ktf+pK+853vqLS01Lv2X//1X3rwwQfV3t7e78dv+vr6NGvWLM2fP1/bt2/vt5b+rtgnJCSoq6tL0dHRA23ptnngwHtBf83P02++cU/AxzADZiCZNYNQ719iBhIzCPX+JWYgMQNpcDO4Hdxut8aNG6eLFy9+asYN6Ir9uHHjFB4e7nd1vrOz0++q/A1xcXH97h8+fLjGjh3b7zHDhg3T7NmzdebMmZvW4nA45HA4/NYjIiK8H+/B4DFDZiAxg1DvX2IGEjMI9f4lZiAxA8m+GQTyugHdFScyMlLp6elyuVw+6y6XS5mZmf0e43Q6/fbX19crIyPjpoValqXW1lbFx8cHUh4AAAAQsgK+3WVJSYl+8pOf6Kc//alOnz6tdevWqa2tTYWFhZKk0tJSrVixwru/sLBQ77//vkpKSnT69Gn99Kc/1e7du/W9733Pu6e8vFxHjhzRu+++q9bWVq1evVqtra3ecwIAAAC4tYBvd5mXl6fz589r06ZNam9v1/Tp01VXV6fExERJUnt7u8897ZOSklRXV6d169Zpx44dmjBhgrZv3+5zq8sLFy7oscceU0dHh2JiYpSWlqaGhgY98MADt6FFAAAAwHwBB3tJKioqUlFRUb9fq6mp8Vv78pe/rN/+9rc3Pd/WrVu1devWwZQCAAAAQIP4KA4AAACAoYdgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGGBQwX7nzp1KSkpSVFSU0tPTdfz48VvuP3bsmNLT0xUVFaXJkydr165dfnsOHjyo1NRUORwOpaam6tChQ4MpDQAAAAhJAQf72tpaFRcXq6ysTC0tLcrKylJubq7a2tr63X/27FktWrRIWVlZamlp0VNPPaUnn3xSBw8e9O5pampSXl6e8vPzderUKeXn52v58uU6efLk4DsDAAAAQkjAwX7Lli1avXq1CgoKNG3aNFVWViohIUFVVVX97t+1a5cmTZqkyspKTZs2TQUFBVq1apVeeOEF757KykplZ2ertLRUKSkpKi0t1YIFC1RZWTnoxgAAAIBQMjyQzVevXlVzc7PWr1/vs56Tk6PGxsZ+j2lqalJOTo7P2sKFC7V792719PQoIiJCTU1NWrdund+eWwV7j8cjj8fjfX7x4kVJ0kcffaSenp5A2rotev/fpaC/5ufp/PnzAR/DDJiBZNYMQr1/iRlIzCDU+5eYgcQMpMHN4Hbo7u6WJFmW9al7Awr2XV1d6u3tVWxsrM96bGysOjo6+j2mo6Oj3/3Xrl1TV1eX4uPjb7rnZueUpIqKCpWXl/utJyUlDbQd3MK479pdgf2YATMI9f4lZiAxg1DvX2IGEjOQ7J9Bd3e3YmJibrknoGB/Q1hYmM9zy7L81j5t/yfXAz1naWmpSkpKvM/7+vr00UcfaezYsbc87k7mdruVkJCgDz74QNHR0XaXYwtmwAxCvX+JGUjMQGIGod6/xAyk0JiBZVnq7u7WhAkTPnVvQMF+3LhxCg8P97uS3tnZ6XfF/Ya4uLh+9w8fPlxjx4695Z6bnVOSHA6HHA6Hz9pf//VfD7SVO1p0dLSxb96BYgbMINT7l5iBxAwkZhDq/UvMQDJ/Bp92pf6GgH54NjIyUunp6XK5XD7rLpdLmZmZ/R7jdDr99tfX1ysjI0MRERG33HOzcwIAAADwFfBHcUpKSpSfn6+MjAw5nU5VV1erra1NhYWFkq5/RObcuXPas2ePJKmwsFAvvfSSSkpK9A//8A9qamrS7t27tX//fu85165dq/nz52vz5s1aunSpDh8+rKNHj+rEiRO3qU0AAADAbAEH+7y8PJ0/f16bNm1Se3u7pk+frrq6OiUmJkqS2tvbfe5pn5SUpLq6Oq1bt047duzQhAkTtH37dn3ta1/z7snMzNSBAwe0YcMGPf3005oyZYpqa2s1Z86c29CiORwOh374wx/6fQQplDADZhDq/UvMQGIGEjMI9f4lZiAxg08KswZy7xwAAAAAQ1rAv6AKAAAAwNBDsAcAAAAMQLAHAAAADECwBwAAAAxAsL+D7Ny5U0lJSYqKilJ6erqOHz9ud0lB09DQoCVLlmjChAkKCwvTL37xC7tLCqqKigrNnj1bo0eP1l133aWvfOUr+v3vf293WUFVVVWl++67z/tLSJxOp15//XW7y7JNRUWFwsLCVFxcbHcpQbNx40aFhYX5POLi4uwuK+jOnTunb33rWxo7dqxGjhyp+++/X83NzXaXFTT33HOP3/sgLCxMa9assbu0oLh27Zo2bNigpKQkjRgxQpMnT9amTZvU19dnd2lB1d3dreLiYiUmJmrEiBHKzMzUm2++aXdZtiPY3yFqa2tVXFyssrIytbS0KCsrS7m5uT63FjXZ5cuXNXPmTL300kt2l2KLY8eOac2aNfr1r38tl8ula9euKScnR5cvX7a7tKCZOHGifvSjH+mtt97SW2+9pb/5m7/R0qVL9c4779hdWtC9+eabqq6u1n333Wd3KUF37733qr293ft4++237S4pqP7yl79o3rx5ioiI0Ouvv67/+Z//0Ysvvhgyv3lduv7+/7/vgRu/4PLrX/+6zZUFx+bNm7Vr1y699NJLOn36tP7pn/5J//zP/6wf//jHdpcWVAUFBXK5XNq7d6/efvtt5eTk6OGHH9a5c+fsLs1eFu4IDzzwgFVYWOizlpKSYq1fv96miuwjyTp06JDdZdiqs7PTkmQdO3bM7lJs9YUvfMH6yU9+YncZQdXd3W0lJydbLpfL+vKXv2ytXbvW7pKC5oc//KE1c+ZMu8uw1Q9+8APrwQcftLuMIWXt2rXWlClTrL6+PrtLCYrFixdbq1at8ll75JFHrG9961s2VRR8V65cscLDw61/+7d/81mfOXOmVVZWZlNVQwNX7O8AV69eVXNzs3JycnzWc3Jy1NjYaFNVsNPFixclSWPGjLG5Env09vbqwIEDunz5spxOp93lBNWaNWu0ePFiPfzww3aXYoszZ85owoQJSkpK0je+8Q29++67dpcUVL/85S+VkZGhr3/967rrrruUlpamf/mXf7G7LNtcvXpVP/vZz7Rq1SqFhYXZXU5QPPjgg/qP//gP/eEPf5AknTp1SidOnNCiRYtsrix4rl27pt7eXkVFRfmsjxgxQidOnLCpqqEh4N88i+Dr6upSb2+vYmNjfdZjY2PV0dFhU1Wwi2VZKikp0YMPPqjp06fbXU5Qvf3223I6nfr444/1V3/1Vzp06JBSU1PtLitoDhw4oObmZr311lt2l2KLOXPmaM+ePfrSl76kP//5z3r22WeVmZmpd955R2PHjrW7vKB49913VVVVpZKSEj311FP6zW9+oyeffFIOh0MrVqywu7yg+8UvfqELFy7o29/+tt2lBM0PfvADXbx4USkpKQoPD1dvb6+ee+45ffOb37S7tKAZPXq0nE6nnnnmGU2bNk2xsbHav3+/Tp48qeTkZLvLsxXB/g7yyasRlmWFzBUK/K/HH39c//3f/x2SVyWmTp2q1tZWXbhwQQcPHtTKlSt17NixkAj3H3zwgdauXav6+nq/q1ShIjc31/vfM2bMkNPp1JQpU/Sv//qvKikpsbGy4Onr61NGRoaef/55SVJaWpreeecdVVVVhWSw3717t3JzczVhwgS7Swma2tpa/exnP9O+fft07733qrW1VcXFxZowYYJWrlxpd3lBs3fvXq1atUp33323wsPDNWvWLD366KP67W9/a3dptiLY3wHGjRun8PBwv6vznZ2dflfxYbYnnnhCv/zlL9XQ0KCJEyfaXU7QRUZG6otf/KIkKSMjQ2+++aa2bduml19+2ebKPn/Nzc3q7OxUenq6d623t1cNDQ166aWX5PF4FB4ebmOFwTdq1CjNmDFDZ86csbuUoImPj/f7i+y0adN08OBBmyqyz/vvv6+jR4/q1VdftbuUoPr+97+v9evX6xvf+Iak63/Jff/991VRURFSwX7KlCk6duyYLl++LLfbrfj4eOXl5SkpKcnu0mzFZ+zvAJGRkUpPT/f+5P8NLpdLmZmZNlWFYLIsS48//rheffVV/ed//mfI/4/rBsuy5PF47C4jKBYsWKC3335bra2t3kdGRob+/u//Xq2trSEX6iXJ4/Ho9OnTio+Pt7uUoJk3b57frW7/8Ic/KDEx0aaK7PPKK6/orrvu0uLFi+0uJaiuXLmiYcN841t4eHjI3e7yhlGjRik+Pl5/+ctfdOTIES1dutTukmzFFfs7RElJifLz85WRkSGn06nq6mq1tbWpsLDQ7tKC4tKlS/rjH//ofX727Fm1trZqzJgxmjRpko2VBceaNWu0b98+HT58WKNHj/b+601MTIxGjBhhc3XB8dRTTyk3N1cJCQnq7u7WgQMH9MYbb+jf//3f7S4tKEaPHu33MxWjRo3S2LFjQ+ZnLb73ve9pyZIlmjRpkjo7O/Xss8/K7XaH1FXKdevWKTMzU88//7yWL1+u3/zmN6qurlZ1dbXdpQVVX1+fXnnlFa1cuVLDh4dWlFmyZImee+45TZo0Sffee69aWlq0ZcsWrVq1yu7SgurIkSOyLEtTp07VH//4R33/+9/X1KlT9Z3vfMfu0uxl6z15EJAdO3ZYiYmJVmRkpDVr1qyQutXhr371K0uS32PlypV2lxYU/fUuyXrllVfsLi1oVq1a5X3/jx8/3lqwYIFVX19vd1m2CrXbXebl5Vnx8fFWRESENWHCBOuRRx6x3nnnHbvLCrrXXnvNmj59uuVwOKyUlBSrurra7pKC7siRI5Yk6/e//73dpQSd2+221q5da02aNMmKioqyJk+ebJWVlVkej8fu0oKqtrbWmjx5shUZGWnFxcVZa9assS5cuGB3WbYLsyzLsuevFAAAAABuFz5jDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGIBgDwAAABiAYA8AAAAYgGAPAAAAGOD/Ax+PYQewmFLyAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from filterpy.discrete_bayes import normalize\n", "\n", "def scaled_update(hall, belief, z, z_prob): \n", " scale = z_prob / (1. - z_prob)\n", " belief[hall==z] *= scale\n", " normalize(belief)\n", "\n", "belief = np.array([0.1] * 10)\n", "scaled_update(hallway, belief, z=1, z_prob=.75)\n", "\n", "print('sum =', sum(belief))\n", "print('probability of door =', belief[0])\n", "print('probability of wall =', belief[2])\n", "book_plots.bar_plot(belief, ylim=(0, .3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " We can see from the output that the sum is now 1.0, and that the probability of a door vs wall is still three times larger. The result also fits our intuition that the probability of a door must be less than 0.333, and that the probability of a wall must be greater than 0.0. Finally, it should fit our intuition that we have not yet been given any information that would allow us to distinguish between any given door or wall position, so all door positions should have the same value, and the same should be true for wall positions.\n", " \n", "This result is called the [*posterior*](https://en.wikipedia.org/wiki/Posterior_probability), which is short for *posterior probability distribution*. All this means is a probability distribution *after* incorporating the measurement information (posterior means 'after' in this context). To review, the *prior* is the probability distribution before including the measurement's information. \n", "\n", "Another term is the [*likelihood*](https://en.wikipedia.org/wiki/Likelihood_function). When we computed `belief[hall==z] *= scale` we were computing how *likely* each position was given the measurement. The likelihood is not a probability distribution because it does not sum to one.\n", "\n", "The combination of these gives the equation\n", "\n", "$$\\mathtt{posterior} = \\frac{\\mathtt{likelihood} \\times \\mathtt{prior}}{\\mathtt{normalization}}$$ \n", "\n", "When we talk about the filter's output we typically call the state after performing the prediction the *prior* or *prediction*, and we call the state after the update either the *posterior* or the *estimated state*. \n", "\n", "It is very important to learn and internalize these terms as most of the literature uses them extensively.\n", "\n", "Does `scaled_update()` perform this computation? It does. Let me recast it into this form:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def scaled_update(hall, belief, z, z_prob): \n", " scale = z_prob / (1. - z_prob)\n", " likelihood = np.ones(len(hall))\n", " likelihood[hall==z] *= scale\n", " return normalize(likelihood * belief)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function is not fully general. It contains knowledge about the hallway, and how we match measurements to it. We always strive to write general functions. Here we will remove the computation of the likelihood from the function, and require the caller to compute the likelihood themselves.\n", "\n", "Here is a full implementation of the algorithm:\n", "\n", "```python\n", "def update(likelihood, prior):\n", " return normalize(likelihood * prior)\n", "```\n", "\n", "Computation of the likelihood varies per problem. For example, the sensor might not return just 1 or 0, but a `float` between 0 and 1 indicating the probability of being in front of a door. It might use computer vision and report a blob shape that you then probabilistically match to a door. It might use sonar and return a distance reading. In each case the computation of the likelihood will be different. We will see many examples of this throughout the book, and learn how to perform these calculations.\n", "\n", "FilterPy implements `update`. Here is the previous example in a fully general form:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.188, 0.188, 0.062, 0.062, 0.062, 0.062, 0.062, 0.062, 0.188,\n", " 0.062])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from filterpy.discrete_bayes import update\n", "\n", "def lh_hallway(hall, z, z_prob):\n", " \"\"\" compute likelihood that a measurement matches\n", " positions in the hallway.\"\"\"\n", " \n", " try:\n", " scale = z_prob / (1. - z_prob)\n", " except ZeroDivisionError:\n", " scale = 1e8\n", "\n", " likelihood = np.ones(len(hall))\n", " likelihood[hall==z] *= scale\n", " return likelihood\n", "\n", "belief = np.array([0.1] * 10)\n", "likelihood = lh_hallway(hallway, z=1, z_prob=.75)\n", "update(likelihood, belief) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Incorporating Movement\n", "\n", "Recall how quickly we were able to find an exact solution when we incorporated a series of measurements and movement updates. However, that occurred in a fictional world of perfect sensors. Might we be able to find an exact solution with noisy sensors?\n", "\n", "Unfortunately, the answer is no. Even if the sensor readings perfectly match an extremely complicated hallway map, we cannot be 100% certain that the dog is in a specific position - there is, after all, a tiny possibility that every sensor reading was wrong! Naturally, in a more typical situation most sensor readings will be correct, and we might be close to 100% sure of our answer, but never 100% sure. This may seem complicated, but let's go ahead and program the math.\n", "\n", "First let's deal with the simple case - assume the movement sensor is perfect, and it reports that the dog has moved one space to the right. How would we alter our `belief` array?\n", "\n", "I hope that after a moment's thought it is clear that we should shift all the values one space to the right. If we previously thought there was a 50% chance of Simon being at position 3, then after he moved one position to the right we should believe that there is a 50% chance he is at position 4. The hallway is circular, so we will use modulo arithmetic to perform the shift." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "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0ZKkV155xat948aNOn36tOf1mowfP17//Oc/1aNHjyrnUJvC/qOPPtL+/fu92l599VW1bNlSAwcOrHHbESNG6JprrtGBAweqjD9o0CCFhYWpefPmGjJkiDZt2uR1lvvkyZPaunXrZec4duxYffrpp56PW6tSecCpzRmXhIQEhYeH++z7f//73/rb3/5Wq30PwJ4qKir0hz/8QT169NDbb7/t83jkkUdUVFRU5R1gKlWXj5o1a6abb75Z+fn56tevX5U5s6qzyVZUl2dHjhx52f8RGT9+vIwxOnLkSJVz69u3ryRp2LBhcrlc+uMf/+i1fW5u7mUvZwkPD9dNN92k1157rcZPla3kdH8cT9F4cMYelv3zn//03C7yxIkT2rRpk9xutyZOnOg5m3LHHXfoj3/8o5KTkzVnzhwNGTJEoaGh+ve//623335bEyZM0MSJE6uNkZiYqDFjxujRRx9VSUmJRowYoQ8//FBPPPGE4uLilJKSctl5LliwQG63W8OHD9dDDz2k66+/XmfPntXhw4eVk5Oj1atXX/bjzk6dOul//a//pfT0dHXs2FGvvPKK3G63Fi1adNl7Grdo0ULPPvuspk2bpm+++UaTJk1S+/btdezYMe3fv1/Hjh3TqlWrJEm/+c1vdOuttyoxMVGPPPKIKioqtGjRIjVv3lzffPNNjXHmzp2r7OxsTZgwQfPmzdOQIUN05swZ7dy5U+PHj9fNN9+sli1bKjo6Wlu2bNHo0aPVunVrtW3btsozR9dcc40ef/xx/frXv9bUqVN155136sSJE8rIyJDL5dITTzxR844HYFtvvvmmvvrqKy1atKjKH5fq06ePnnvuOb344osaP358lWPUlI+WLVumG2+8USNHjtQvfvELdevWTSdPntRnn32mrVu31ngCozZCQkKUmJio1NRUXbhwQYsWLVJJSYnnFsk1GTFihO677z7953/+p95//32NGjVKzZs3V1FRkfbs2aO+ffvqF7/4ha699lr98pe/1JNPPqkZM2bo9ttv15dffqn09PRaXV65ZMkS3XjjjRo6dKjmzZun//iP/9DXX3+t119/Xc8//7xatmzp+aXfNWvWqGXLlnK5XIqJianyf3z8cTxFIxLMb+6icanqrjitWrUyAwYMMEuWLPG6ZZYxxpSXl5vFixeb/v37G5fLZVq0aGFiY2PN/fffbw4e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KTg5n3zvi8K+lrKzszV37lzNnz9f+fn5GjlypMaOHavCwsKAxTx9+rT69++v5557LmAxLrVz507Nnj1b7777rtxut86fP6+kpCSdPn06oHG7dOmip59+Wu+//77ef/99/fjHP9aECRP00UcfBTRupb1792rNmjXq169fvcS74YYbVFRU5Hn84x//CGi8b7/9ViNGjFBoaKjefPNNHThwQM8880xAf71z7969Xmus/FGi22+/PWAxJWnRokVavXq1nnvuOX388cf63e9+p9///vd69tlnAxp3xowZcrvdevnll/WPf/xDSUlJuuWWW3TkyJGAxkVgkPMDl/PJ9/bL91Jwcj75vgrBvt9mYzFkyBAzc+ZMr7bY2Fgzb968eokvyWzevLleYv3Q0aNHjSSve1fXl2uvvda88MILAY9z8uRJ07NnT+N2u81NN91k5syZE9B4TzzxhOnfv39AY1zq0UcfNTfeeGO9xrzUnDlzTI8ePcyFCxcCGmfcuHHm3nvv9Wr76U9/au6+++6AxSwtLTUhISHmjTfe8Grv37+/mT9/fsDiInDI+fWb88n3/tMQ8r0x9ZPzyfe+OGNfC+fOndO+ffuUlJTk1Z6UlKTc3Nwgzap+fP/995Kk1q1b11vMiooKbdiwQadPn1ZCQkLA482ePVvjxo3TLbfcEvBYlQ4ePKhOnTopJiZGd9xxhz7//POAxnv99dc1aNAg3X777Wrfvr3i4uL0v//3/w5ozB86d+6cXnnlFd17771yOBwBjXXjjTfqr3/9qz799FNJ0v79+7Vnzx4lJycHLOb58+dVUVEhl8vl1R4eHs4vqjZC5Pz6y/nke/8Ldr6X6i/nk++rEOz/s2gMjhw5YiSZv//9717tTz31lLnuuuvqZQ4KwtmbCxcumNtuu63e/s//ww8/NM2bNzchISGmVatW5i9/+UvAY65fv97ccMMN5syZM8YYUy9ncHJycsyf/vQn8+GHH3rOGkVGRprjx48HLKbT6TROp9OkpaWZDz74wKxevdq4XC7zhz/8IWAxfyg7O9uEhISYI0eOBDzWhQsXzLx584zD4TBNmzY1DofD/Pa3vw143ISEBHPTTTeZI0eOmPPnz5uXX37ZOByOessR8B9yfuBzPvnevvnemPrL+eR7XxT2tVCZ5HNzc73an3zySXP99dfXyxyCkeRnzZploqOjzZdfflkv8crKyszBgwfN3r17zbx580zbtm3NRx99FLB4hYWFpn379qagoMDTVh+J/lKnTp0ykZGR5plnnglYjNDQUJOQkODV9uCDD5phw4YFLOYPJSUlmfHjx9dLrPXr15suXbqY9evXmw8//NCsW7fOtG7d2mRlZQU07meffWZGjRplJJmQkBAzePBg8/Of/9z06tUroHHhf+T8wOd88r19870x9Zfzyfe+KOxroayszISEhJhNmzZ5tT/00ENm1KhR9TKH+k7yDzzwgOnSpYv5/PPP6y3mpUaPHm3uu+++gI2/efNmzz/Kyock43A4TEhIiDl//nzAYl/qlltu8bme15+6du1qpk+f7tW2cuVK06lTp4DFrHT48GHTpEkT8+c//zngsYwxpkuXLua5557zavvNb35TbwXZqVOnzFdffWWMMWby5MkmOTm5XuLCf8j59Y987z/BzPfG1G/OJ9/74hr7WggLC1N8fLznG96V3G63hg8fHqRZBYYxRg888IA2bdqkv/3tb4qJiQnqXMrKygI2/ujRo/WPf/xDBQUFnsegQYP085//XAUFBQoJCQlY7B8qKyvTxx9/rI4dOwYsxogRI3xuYffpp58qOjo6YDErvfTSS2rfvr3GjRsX8FiSVFpaqiZNvFNbSEhIwG9/Vql58+bq2LGjvv32W23btk0TJkyol7jwH3J+cOZBvvePYOZ7qX5zPvm+CsH9/4rGY8OGDSY0NNS8+OKL5sCBA2bu3LmmefPm5vDhwwGLefLkSZOfn2/y8/ONJLNkyRKTn59vvvjii4DF/MUvfmFatWpl3nnnHVNUVOR5lJaWBiymMcakpaWZXbt2mUOHDpkPP/zQ/PrXvzZNmjQx27dvD2jcS9XHR7OPPPKIeeedd8znn39u3n33XTN+/HjTsmXLgL6X/ud//sc0bdrUPPXUU+bgwYPmj3/8o2nWrJl55ZVXAhbTGGMqKipM165dzaOPPhrQOD80bdo007lzZ/PGG2+YQ4cOmU2bNpm2bduaX/3qVwGN+9Zbb5k333zTfP7552b79u2mf//+ZsiQIebcuXMBjYvAIOcHLueT7+2Z742p/5xPvvdFYW/BihUrTHR0tAkLCzMDBw4M+O3A3n77bSPJ5zFt2rSAxawqniTz0ksvBSymMcbce++9nn3brl07M3r06HpP8sbUT6KfMmWK6dixowkNDTWdOnUyP/3pTwN6bWmlrVu3mj59+hin02liY2PNmjVrAh5z27ZtRpL517/+FfBYlUpKSsycOXNM165djcvlMt27dzfz5883ZWVlAY2bnZ1tunfvbsLCwkyHDh3M7NmzzXfffRfQmAgscn5gkO/tme+Nqf+cT7735TDGmPr6dAAAAABAYHCNPQAAAGADFPYAAACADVDYAwAAADZAYQ8AAADYAIU9AAAAYAMU9gAAAIANUNgDAAAANkBhDwAAANgAhT0AAABgAxT2AAAAgA1Q2AMAAAA2QGEPAAAA2MD/B7qSt02nOmRsAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def perfect_predict(belief, move):\n", " \"\"\" move the position by `move` spaces, where positive is \n", " to the right, and negative is to the left\n", " \"\"\"\n", " n = len(belief)\n", " result = np.zeros(n)\n", " for i in range(n):\n", " result[i] = belief[(i-move) % n]\n", " return result\n", " \n", "belief = np.array([.35, .1, .2, .3, 0, 0, 0, 0, 0, .05])\n", "plt.subplot(121)\n", "book_plots.bar_plot(belief, title='Before prediction', ylim=(0, .4))\n", "\n", "belief = perfect_predict(belief, 1)\n", "plt.subplot(122)\n", "book_plots.bar_plot(belief, title='After prediction', ylim=(0, .4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that we correctly shifted all values one position to the right, wrapping from the end of the array back to the beginning. \n", "\n", "The next cell animates this so you can see it in action. Use the slider to move forwards and backwards in time. This simulates Simon walking around and around the hallway. It does not yet incorporate new measurements so the probability distribution does not change shape, only position." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c65bc79da49448efb42e0bfd882986e4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=0, description='time_step', max=19), Output()), _dom_classes=('widget-in…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from ipywidgets import interact, IntSlider\n", "\n", "belief = np.array([.35, .1, .2, .3, 0, 0, 0, 0, 0, .05])\n", "perfect_beliefs = []\n", "\n", "for _ in range(20):\n", " # Simon takes one step to the right\n", " belief = perfect_predict(belief, 1)\n", " perfect_beliefs.append(belief)\n", "\n", "def simulate(time_step):\n", " book_plots.bar_plot(perfect_beliefs[time_step], ylim=(0, .4))\n", " plt.show()\n", " \n", "interact(simulate, time_step=IntSlider(value=0, max=len(perfect_beliefs)-1));" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Terminology\n", "\n", "Let's pause a moment to review terminology. I introduced this terminology in the last chapter, but let's take a second to help solidify your knowledge. \n", "\n", "The *system* is what we are trying to model or filter. Here the system is our dog. The *state* is its current configuration or value. In this chapter the state is our dog's position. We rarely know the actual state, so we say our filters produce the *estimated state* of the system. In practice this often gets called the state, so be careful to understand the context.\n", " \n", "One cycle of prediction and updating with a measurement is called the state or system *evolution*, which is short for *time evolution* [7]. Another term is *system propagation*. It refers to how the state of the system changes over time. For filters, time is usually a discrete step, such as 1 second. For our dog tracker the system state is the position of the dog, and the state evolution is the position after a discrete amount of time has passed.\n", "\n", "We model the system behavior with the *process model*. Here, our process model is that the dog moves one or more positions at each time step. This is not a particularly accurate model of how dogs behave. The error in the model is called the *system error* or *process error*. \n", "\n", "The prediction is our new *prior*. Time has moved forward and we made a prediction without benefit of knowing the measurements. \n", "\n", "Let's work an example. The current position of the dog is 17 m. Our epoch is 2 seconds long, and the dog is traveling at 15 m/s. Where do we predict he will be in two seconds? \n", "\n", "Clearly,\n", "\n", "$$ \\begin{aligned}\n", "\\bar x &= 17 + (15*2) \\\\\n", "&= 47\n", "\\end{aligned}$$\n", "\n", "I use bars over variables to indicate that they are priors (predictions). We can write the equation for the process model like this:\n", "\n", "$$ \\bar x_{k+1} = f_x(\\bullet) + x_k$$\n", "\n", "$x_k$ is the current position or state. If the dog is at 17 m then $x_k = 17$.\n", "\n", "$f_x(\\bullet)$ is the state propagation function for x. It describes how much the $x_k$ changes over one time step. For our example it performs the computation $15 \\cdot 2$ so we would define it as \n", "\n", "$$f_x(v_x, t) = v_k t$$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adding Uncertainty to the Prediction\n", "\n", "`perfect_predict()` assumes perfect measurements, but all sensors have noise. What if the sensor reported that our dog moved one space, but he actually moved two spaces, or zero? This may sound like an insurmountable problem, but let's model it and see what happens.\n", "\n", "Assume that the sensor's movement measurement is 80% likely to be correct, 10% likely to overshoot one position to the right, and 10% likely to undershoot to the left. That is, if the movement measurement is 4 (meaning 4 spaces to the right), the dog is 80% likely to have moved 4 spaces to the right, 10% to have moved 3 spaces, and 10% to have moved 5 spaces.\n", "\n", "Each result in the array now needs to incorporate probabilities for 3 different situations. For example, consider the reported movement of 2. If we are 100% certain the dog started from position 3, then there is an 80% chance he is at 5, and a 10% chance for either 4 or 6. Let's try coding that:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAu0AAAF0CAYAAACXPwdxAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAq4UlEQVR4nO3dfXRU9Z3H8c+QhwmgwZJASHgIwcUKZUUboAZFUCAsIFJxCx5UVOBsY0AIqVVi3GNANC2tHFQM6AKyIIX4AK61UZizIg9GK2BSXaHVFTAKCZjYkkjs5Om3f7jJaUzATJg782Pyfp2TP+Zy7/38LjP5zofJMHEZY4wAAAAAWKtTsBcAAAAA4Nwo7QAAAIDlKO0AAACA5SjtAAAAgOUo7QAAAIDlKO0AAACA5SjtAAAAgOUo7QAAAIDlKO0AAACA5SjtCBk5OTlyuVwqLy/36/n+0ZgxYzRmzJh2na+mpkZpaWmKj49XWFiYrrzyyvNfJADAL/r376+77ror2MsAzio82AsALiR5eXntPnb16tV65pln9NRTTyk5OVkXXXSRH1cGADgf27dvV3R0dLCXAZwVpR3wweDBg9t97P/8z/+oc+fOmj9/vh9XBAA4H9988406d+6sq666ym/nrK+vV11dndxut9/OCfD2GISczz//XNOmTVN0dLS6deum22+/XV9++WWzffLz85WSkqKuXbvqoosu0oQJE1RUVPS9527t7TE1NTVatmyZLr/8crndbvXo0UN33313s0yXy6W1a9fqm2++kcvlksvl0oYNG/xxuQDQ4TW+nbGoqOic879///668cYbtW3bNl111VWKiorSkiVLmv7su2+PKSkp0e23366ePXvK7XZr0KBBevzxx9XQ0NC0z7Fjx+RyubR8+XItW7ZMSUlJcrvd2rVrV0CuHR0Hr7Qj5Nx8882aPn260tLS9NFHH+nf//3fdejQIf3xj39URESEHnvsMT300EO6++679dBDD6mmpka/+c1vNGrUKL333ns+vZre0NCgqVOnau/evbr//vs1cuRIffbZZ3r44Yc1ZswYHThwQJ07d9Y777yjRx55RLt27dKbb74pSbr00kud+isAgA7p++a/JL3//vs6fPiwHnroISUlJalr166tnuvLL7/UyJEjVVNTo0ceeUT9+/fXa6+9pvvuu0+ffvppi7dLPvnkk7rsssv029/+VtHR0Ro4cKDj14uOhdKOkDNt2jQtX75ckpSamqq4uDjddttteuGFF3Tdddfp4Ycf1vz58/Xkk082HTN+/HgNHDhQS5YsUX5+fpuzXnjhBb3xxht6+eWXNW3atKbtQ4cO1fDhw7Vhwwbdc889uvrqq9WjRw916tRJV199tf8uFgDQ5Fzz/7bbbpMknTp1SocOHdJll112znOtWLFCx48f1x//+EeNGDFCkjRhwgTV19drzZo1ysjIaHaOqKgo7dixo+kfB4C/8fYYhJzGwdxo+vTpCg8P165du7Rjxw7V1dVp1qxZqqura/qKiorS6NGj9dZbb/mU9dprr+mSSy7RlClTmp3vyiuvVK9evXw+HwCg/c41/xtdccUV31vYJenNN9/U4MGDmwp7o7vuukvGmKafmja66aabKOxwFK+0I+T06tWr2e3w8HDFxMSooqJCJ0+elCQNHz681WM7dfLt37EnT57U3/72N0VGRrb65/76+EkAwPc71/xvFB8f36ZzVVRUqH///i22JyQkNP35P2rreYH2orQj5JSVlal3795Nt+vq6lRRUaGYmBjFxsZKkl566SUlJiaed1ZsbKxiYmL0xhtvtPrnF1988XlnAADa5lzzv9F3f//G2cTExKi0tLTF9hMnTkhS0/OJr+cF2ovSjpCzefNmJScnN91+4YUXVFdXpzFjxujaa69VeHi4Pv30U91yyy3nnXXjjTdq69atqq+v109+8pPzPh8AoP3ONf99NXbsWOXm5ur999/Xj3/846btGzdulMvl0vXXX++PJQNtRmlHyNm2bZvCw8M1fvz4pk8PGDp0qKZPn67IyEgtXbpU2dnZOnLkiP7lX/5FP/jBD3Ty5Em999576tq1a9PHf7XFrbfeqs2bN2vSpElauHChRowYoYiICH3xxRfatWuXpk6dqptvvtnBqwUANDrX/PfVokWLtHHjRk2ePFlLly5VYmKi/vCHPygvL0/33HNPm94XD/gTpR0hZ9u2bcrJydHq1avlcrk0ZcoUrVy5sul951lZWRo8eLCeeOIJbdmyRV6vV7169dLw4cOVlpbmU1ZYWJheffVVPfHEE9q0aZNyc3MVHh6uPn36aPTo0frnf/5nJy4RANCK75v/vujRo4cKCwuVlZWlrKwsVVZWasCAAVq+fLkyMzMdWD1wbi5jjAn2IgAAANor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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def predict_move(belief, move, p_under, p_correct, p_over):\n", " n = len(belief)\n", " prior = np.zeros(n)\n", " for i in range(n):\n", " prior[i] = (\n", " belief[(i-move) % n] * p_correct +\n", " belief[(i-move-1) % n] * p_over +\n", " belief[(i-move+1) % n] * p_under) \n", " return prior\n", "\n", "belief = [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.]\n", "prior = predict_move(belief, 2, .1, .8, .1)\n", "book_plots.plot_belief_vs_prior(belief, prior)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It appears to work correctly. Now what happens when our belief is not 100% certain?" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0. , 0. , 0.04, 0.38, 0.52, 0.06, 0. , 0. , 0. ])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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KycnR1988UWje82BUMFHPgIAAACWo7QDAAAAluP2GAAAAMByjt9p37FjhyZMmKCEhAR5PB69/PLL33vM9u3blZycrKioKPXp00crVqxoyVoBAAHEvAcAezgu7adOndLAgQO1fPnyZu1/6NAhjRs3TsOGDVNRUZHuv/9+zZkzRy+++KLjxQIAAod5DwD2OKfbYzwej1566SX97Gc/O+M+9913n1555RXt37+/fltaWpr+9re/6e23325pNAAggJj3ABBcrn9O+9tvv63U1NQG28aMGaNVq1apqqpKERERjY7x+/3y+/31j2tra/Xll18qJiaGXxMMIOQZY1RRUaGEhAS1a3f+fF4A8x4AnHEy710v7ceOHVNcXFyDbXFxcaqurlZpaani4+MbHbN48WJHv5USAELRZ599ph49egR7Gc3GvAeAlmnOvA/Ib0T97rsldXfknOldlKysrAa/bezkyZPq1auXDh06pAsvvNC1dVZVVWnr1q269tprm3xHKFQyg5XLtYZeZrByQ/1aKyoqlJSU5Oq8cwvz3r5crjU0c9tKZrBybZz3rpf2bt266dixYw22nThxQuHh4YqJiWnyGK/XK6/X22h7586dFR0d7co6pW+eoA4dOigmJiag3xSBzgxWLtcaepnByg31a6079/l2ewjz3s5crjU0c9tKZrBybZz3rt8smZKSIp/P12Dbli1bNGjQoIA+4QAAdzHvAcA9jkv7V199pb1792rv3r2SvvmIr71796q4uFjSNz/qnDZtWv3+aWlp+vTTT5WZman9+/dr9erVWrVqle65557WuQIAgCuY9wBgD8e3x+zevVvXXntt/eO6exFvu+02rVmzRiUlJfUDXZKSkpJUUFCgefPm6cknn1RCQoIef/xx3XTTTa2wfACAW5j3AGAPx6V9xIgROttHu69Zs6bRtuHDh+u9995zGgUACCLmPQDY4/z5AGAAAACgjaK0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJZrUWnPzc1VUlKSoqKilJycrJ07d551//Xr12vgwIHq0KGD4uPjdccdd6isrKxFCwYABA7zHgDs4Li05+fnKyMjQwsWLFBRUZGGDRumsWPHqri4uMn933zzTU2bNk0zZszQhx9+qOeff167du3SzJkzz3nxAAD3MO8BwB6OS/vSpUs1Y8YMzZw5U/369dOyZcvUs2dP5eXlNbn/O++8o969e2vOnDlKSkrS1VdfrTvvvFO7d+8+58UDANzDvAcAezgq7ZWVldqzZ49SU1MbbE9NTVVhYWGTxwwdOlSff/65CgoKZIzR8ePH9cILL2j8+PEtXzUAwFXMewCwS7iTnUtLS1VTU6O4uLgG2+Pi4nTs2LEmjxk6dKjWr1+vKVOm6J///Keqq6t1ww036Iknnjhjjt/vl9/vr39cXl4uSaqqqlJVVZWTJTtSd243M2zIDFYu1xp6mcHKDfVrDfR1NYV5Hzq5XGto5raVzGDl2jjvPcYY09ydjx49qu7du6uwsFApKSn12x9++GGtW7dO//M//9PomH379mnUqFGaN2+exowZo5KSEv3617/W4MGDtWrVqiZzsrOzlZOT02j7H//4R3Xo0KG5ywWA89Lp06c1depUnTx5UtHR0UFZA/MeANznZN47Ku2VlZXq0KGDnn/+ed1444312+fOnau9e/dq+/btjY659dZb9c9//lPPP/98/bY333xTw4YN09GjRxUfH9/omKbeeenZs6dKS0tdfQGrqqqSz+fT6NGjFRER4VpOsDODlcu1hl5msHJD/VrLy8sVGxsb1NLOvA+dXK41NHPbSmawcm2c945uj4mMjFRycrJ8Pl+DIe7z+TRx4sQmjzl9+rTCwxvGhIWFSZLO9PcFr9crr9fbaHtERERAnqxA5QQ7M1i5XGvoZQYrN1SvNRjX9F3M+9DL5VpDM7etZAYr16Z57/jTYzIzM7Vy5UqtXr1a+/fv17x581RcXKy0tDRJUlZWlqZNm1a//4QJE7Rp0ybl5eXp4MGDeuuttzRnzhwNGTJECQkJTuMBAAHCvAcAezh6p12SpkyZorKyMi1cuFAlJSUaMGCACgoKlJiYKEkqKSlp8Bm+t99+uyoqKrR8+XL96le/0kUXXaTrrrtOv/3tb1vvKgAArY55DwD2cFzaJSk9PV3p6elN/tmaNWsabbv77rt19913tyQKABBEzHsAsIPj22MAAAAABBalHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwHKUdAAAAsBylHQAAALAcpR0AAACwXItKe25urpKSkhQVFaXk5GTt3LnzrPv7/X4tWLBAiYmJ8nq9uvjii7V69eoWLRgAEDjMewCwQ7jTA/Lz85WRkaHc3FxdddVVeuqppzR27Fjt27dPvXr1avKYyZMn6/jx41q1apX+5V/+RSdOnFB1dfU5Lx4A4B7mPQDYw3FpX7p0qWbMmKGZM2dKkpYtW6bNmzcrLy9PixcvbrT/66+/ru3bt+vgwYPq3LmzJKl3797ntmoAgOuY9wBgD0elvbKyUnv27NH8+fMbbE9NTVVhYWGTx7zyyisaNGiQlixZonXr1qljx4664YYb9NBDD6l9+/ZNHuP3++X3++sfl5eXS5KqqqpUVVXlZMmO1J3bzQwbMoOVy7WGXmawckP9WgN9XU1h3odOLtcamrltJTNYuTbOe48xxjR356NHj6p79+566623NHTo0PrtjzzyiP7whz/oo48+anTMT3/6U23btk2jRo3Sf/zHf6i0tFTp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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "belief = [0, 0, .4, .6, 0, 0, 0, 0, 0, 0]\n", "prior = predict_move(belief, 2, .1, .8, .1)\n", "book_plots.plot_belief_vs_prior(belief, prior)\n", "prior" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here the results are more complicated, but you should still be able to work it out in your head. The 0.04 is due to the possibility that the 0.4 belief undershot by 1. The 0.38 is due to the following: the 80% chance that we moved 2 positions (0.4 $\\times$ 0.8) and the 10% chance that we undershot (0.6 $\\times$ 0.1). Overshooting plays no role here because if we overshot both 0.4 and 0.6 would be past this position. **I strongly suggest working some examples until all of this is very clear, as so much of what follows depends on understanding this step.**\n", "\n", "If you look at the probabilities after performing the update you might be dismayed. In the example above we started with probabilities of 0.4 and 0.6 in two positions; after performing the update the probabilities are not only lowered, but they are strewn out across the map.\n", "\n", "This is not a coincidence, or the result of a carefully chosen example - it is always true of the prediction. If the sensor is noisy we lose some information on every prediction. Suppose we were to perform the prediction an infinite number of times - what would the result be? If we lose information on every step, we must eventually end up with no information at all, and our probabilities will be equally distributed across the `belief` array. Let's try this with 100 iterations. The plot is animated; use the slider to change the step number." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final Belief: [0.104 0.103 0.101 0.099 0.097 0.096 0.097 0.099 0.101 0.103]\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "67b1c6758fff4724b590d76d758d0de5", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=1, description='step'), Output()), _dom_classes=('widget-interact',))" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "belief = np.array([1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0])\n", "predict_beliefs = []\n", " \n", "for i in range(100):\n", " belief = predict_move(belief, 1, .1, .8, .1)\n", " predict_beliefs.append(belief)\n", "\n", "print('Final Belief:', belief)\n", "\n", "# make interactive plot\n", "def show_prior(step):\n", " book_plots.bar_plot(predict_beliefs[step-1])\n", " plt.title(f'Step {step}')\n", " plt.show()\n", "\n", "interact(show_prior, step=IntSlider(value=1, max=len(predict_beliefs)));" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final Belief: [0.104 0.103 0.101 0.099 0.097 0.096 0.097 0.099 0.101 0.103]\n" ] } ], "source": [ "print('Final Belief:', belief)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After 100 iterations we have lost almost all information, even though we were 100% sure that we started in position 0. Feel free to play with the numbers to see the effect of differing number of updates. For example, after 100 updates a small amount of information is left, after 50 a lot is left, but by 200 iterations essentially all information is lost." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And, if you are viewing this online here is an animation of that output.\n", "\n", "\n", "I will not generate these standalone animations through the rest of the book. Please see the preface for instructions to run this book on the web, for free, or install IPython on your computer. This will allow you to run all of the cells and see the animations. It's very important that you practice with this code, not just read passively." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generalizing with Convolution\n", "\n", "We made the assumption that the movement error is at most one position. But it is possible for the error to be two, three, or more positions. As programmers we always want to generalize our code so that it works for all cases. \n", "\n", "This is easily solved with [*convolution*](https://en.wikipedia.org/wiki/Convolution). Convolution modifies one function with another function. In our case we are modifying a probability distribution with the error function of the sensor. The implementation of `predict_move()` is a convolution, though we did not call it that. Formally, convolution is defined as\n", "\n", "$$ (f \\ast g) (t) = \\int_0^t \\!f(\\tau) \\, g(t-\\tau) \\, \\mathrm{d}\\tau$$\n", "\n", "where $f\\ast g$ is the notation for convolving f by g. It does not mean multiply.\n", "\n", "Integrals are for continuous functions, but we are using discrete functions. We replace the integral with a summation, and the parenthesis with array brackets.\n", "\n", "$$ (f \\ast g) [t] = \\sum\\limits_{\\tau=0}^t \\!f[\\tau] \\, g[t-\\tau]$$\n", "\n", "Comparison shows that `predict_move()` is computing this equation - it computes the sum of a series of multiplications.\n", "\n", "[Khan Academy](https://www.khanacademy.org/math/differential-equations/laplace-transform/convolution-integral/v/introduction-to-the-convolution) [4] has a good introduction to convolution, and Wikipedia has some excellent animations of convolutions [5]. But the general idea is already clear. You slide an array called the *kernel* across another array, multiplying the neighbors of the current cell with the values of the second array. In our example above we used 0.8 for the probability of moving to the correct location, 0.1 for undershooting, and 0.1 for overshooting. We make a kernel of this with the array `[0.1, 0.8, 0.1]`. All we need to do is write a loop that goes over each element of our array, multiplying by the kernel, and summing the results. To emphasize that the belief is a probability distribution I have named it `pdf`." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "def predict_move_convolution(pdf, offset, kernel):\n", " N = len(pdf)\n", " kN = len(kernel)\n", " width = int((kN - 1) / 2)\n", "\n", " prior = np.zeros(N)\n", " for i in range(N):\n", " for k in range (kN):\n", " index = (i + (width-k) - offset) % N\n", " prior[i] += pdf[index] * kernel[k]\n", " return prior" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This illustrates the algorithm, but it runs very slow. SciPy provides a convolution routine `convolve()` in the `ndimage.filters` module. We need to shift the pdf by `offset` before convolution; `np.roll()` does that. The move and predict algorithm can be implemented with one line:\n", "\n", "```python\n", "convolve(np.roll(pdf, offset), kernel, mode='wrap')\n", "```\n", "\n", "FilterPy implements this with `discrete_bayes`' `predict()` function." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "image/png": "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qalp/XjnnXdczfvHP/6hiRMnKi4uTs8995x27typu+66y/XfKvnGG2+02WfLL9X5yU9+4lrmv//7v2vt2rW69957tWvXLt1xxx367W9/q9/97neuZUrSokWLFAwGtXHjRr3zzjsKBAK65JJLVF1d7Wou3OHFzI/0vJe8mfnMe3fnveTNzO9O816yeOYbmHPPPddkZ2e3OTZy5EizZMmSiK1BknnqqacilmeMMfv37zeSzEsvvRTRXGOMOe2008wDDzzges6hQ4fM8OHDTTAYNBdeeKG58cYbXc1bunSpGTt2rKsZR/vlL39pzj///IhmduTGG280Z5xxhmlubnYtY/r06WbBggVtjl1++eXmqquuci3zyJEjJiYmxjzzzDNtjo8dO9YUFBS4lgv3eD3zvZj3xng385n34WXDzI/WeW+M3TO/299pr6+vV0VFhQKBQJvjgUBA5eXlHq0qMg4ePChJ6tu3b8Qym5qatHnzZn355ZfKyspyPW/x4sWaPn26LrnkEtezWnzwwQcaNGiQ0tPTdcUVV2j37t2u5j399NPKzMzUT37yE/Xv31/jxo3Tf/7nf7qaebT6+no98sgjWrBggXw+n2s5559/vv7rv/5L77//viTpv//7v/XKK69o2rRprmU2NjaqqalJCQkJbY737NlTr7zyimu5cAczP3Izn3nvDq9nfjTPe8nyme/pXxksUF1dbSSZV199tc3xlStXmhEjRkRsHYrwnZfm5mYzY8aMiP1t/e233za9e/c2MTExpk+fPubZZ591PXPTpk3mzDPPNF999ZUxxkTkzktpaal54oknzNtvv916tyclJcUcOHDAtUy/32/8fr/Jz883b731llm7dq1JSEgwv//9713LPFpJSYmJiYkx1dXVruY0NzebJUuWGJ/PZ2JjY43P5zO33367q5nGGJOVlWUuvPBCU11dbRobG83GjRuNz+eL6IxAeNgw8yM9742J7Mxn3rs3743xfuZH+7w3xt6ZT2n//wFeXl7e5viKFSvMd77znYitI9JDPCcnx6SlpZlPPvkkInmhUMh88MEH5o033jBLliwxycnJ5t1333Utr6qqyvTv39/s2LGj9VgkhvjRDh8+bFJSUsxdd93lWkZcXJzJyspqc+yGG24w5513nmuZRwsEAuayyy5zPWfTpk1myJAhZtOmTebtt982GzZsMH379jXr1693Nfd///d/zQUXXGAkmZiYGDN+/Hhz5ZVXmlGjRrmai/CzYeZ7UdojOfOZ9+7Ne2O8n/nRPu+NsXfmd/vSHgqFTExMjNmyZUub47/4xS/MBRdcELF1RHKIX3/99WbIkCFm9+7dEcnryOTJk83Pf/5z167/1FNPtf6freVDkvH5fCYmJsY0Nja6ln20Sy65pN37Z8Np6NChZuHChW2OFRUVmUGDBrmW+c/27NljevToYf74xz+6njVkyBBz7733tjl22223RaxsHT582Ozdu9cYY8zs2bPNtGnTIpKL8LFh5ke6tHs985n34eXlzO9O894Y+2Z+t39Pe3x8vDIyMlr/JXSLYDCoCRMmeLQqdxhjdP3112vLli168cUXlZ6e7ulaQqGQa9efPHmy3nnnHe3YsaP1IzMzU1deeaV27NihmJgY17L/WSgU0q5duzRw4EDXMiZOnNjux7i9//77SktLcy3znz388MPq37+/pk+f7nrWkSNH1KNH27EVExMTkR8BJkm9e/fWwIED9Y9//EMvvPCCZs6cGZFchA8z35t1MO/Dx8uZ353mvWThzPf0rwyW2Lx5s4mLizMPPvig2blzp8nNzTW9e/c2e/bscTX30KFDprKy0lRWVhpJZvXq1aaystJ8/PHHruRdd911pk+fPmb79u2mpqam9ePIkSOu5LXIz883L7/8svnoo4/M22+/bX71q1+ZHj16mK1bt7qae7RIfLv0X//1X8327dvN7t27zWuvvWYuu+wyc+qpp7r6Z+n11183sbGxZuXKleaDDz4wjz76qOnVq5d55JFHXMts0dTUZIYOHWp++ctfup5ljDFXX321GTx4sHnmmWfMRx99ZLZs2WKSk5PNLbfc4mru888/b5577jmze/dus3XrVjN27Fhz7rnnmvr6eldz4Q4vZn6k570x3sx85r27894Y72Z+d5n3xtg78ynt/+++++4zaWlpJj4+3pxzzjkR+ZFY27ZtM5LafVx99dWu5HWUJck8/PDDruS1WLBgQetr269fPzN58uSID3BjIjPE58yZYwYOHGji4uLMoEGDzOWXX+7qezlb/PnPfzZjxowxfr/fjBw50qxbt871TGOMeeGFF4wk895770Ukr66uztx4441m6NChJiEhwZx++ummoKDAhEIhV3NLSkrM6aefbuLj482AAQPM4sWLzRdffOFqJtwV6Zkf6XlvjDczn3nv/rw3xpuZ313mvTH2znyfMcZE6q4+AAAAAOe6/XvaAQAAANtR2gEAAADLUdoBAAAAy1HaAQAAAMtR2gEAAADLUdoBAAAAy1HaAQAAAMtR2gEAAADLUdoBAAAAy1HaAQAAAMtR2gEAAADLUdoBAAAAy/0fDXbEgbqKXvMAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from filterpy.discrete_bayes import predict\n", "\n", "belief = [.05, .05, .05, .05, .55, .05, .05, .05, .05, .05]\n", "prior = predict(belief, offset=1, kernel=[.1, .8, .1])\n", "book_plots.plot_belief_vs_prior(belief, prior, ylim=(0,0.6))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All of the elements are unchanged except the middle ones. The values in position 4 and 6 should be \n", "$$(0.1 \\times 0.05)+ (0.8 \\times 0.05) + (0.1 \\times 0.55) = 0.1$$\n", "\n", "Position 5 should be $$(0.1 \\times 0.05) + (0.8 \\times 0.55)+ (0.1 \\times 0.05) = 0.45$$\n", "\n", "Let's ensure that it shifts the positions correctly for movements greater than one and for asymmetric kernels." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "image/png": "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ou/PkFe5nSXTq1zW2rk6y8k4mvfGgcrKSiPJvP766y22L1++3AwZMqTNYwYPHmyWL1/eYtvrr79uJJl9+/a1ecySJUuMJB48ePDo1I9PP/3UyYgOK+Y9Dx48eETu0Z557+hOexOfz9fiuTGm1bZv2r+t7U3y8vKUm5vb/LyxsVGff/65kpKSTppzqmpqapSamqpPP/1UiYmJruV4nelVLmuNvkyvcqN9rcYYHTlyRP369XMto72Y96d/LmuNztzOkulVro3z3lFpT05OVkxMjPbv399i+4EDB5SSktLmMX369Glz/9jYWCUlJbV5jN/vl9/vb7HtW9/6lpNLPSWJiYkR/cPoVaZXuaw1+jK9yo3mtfbo0cPV838T5n305bLW6MztLJle5do07x39Q9T4+HhlZGQoGAy22B4MBjV27Ng2j8nMzGy1/9atWzV69Og2398IAPAe8x4A7OL402Nyc3P18MMP69FHH9WuXbt06623qqKiQllZWZK+/lHn3Llzm/fPysrSJ598otzcXO3atUuPPvqoHnnkEd12223hWwUAIOyY9wBgD8fvaZ85c6aqq6u1bNkyVVVVacSIESouLlZaWpokqaqqqsVn+Kanp6u4uFi33nqrHnzwQfXr10/333+/fvSjH4VvFWHi9/u1ZMmSVj+qjbZMr3JZa/RlepXbmdbqJeZ9dOSy1ujM7SyZXuXaOO99xnj4mWIAAAAAvpHjt8cAAAAAiCxKOwAAAGA5SjsAAABgOUo7AAAAYDlK+/8rLCxUenq6EhISlJGRoZKSEtczX331VU2dOlX9+vWTz+fTH//4R1fzVqxYoTFjxujMM89U79699cMf/lAffPCBq5mStHr1ap133nnNv6AgMzNTL774ouu5/2zFihXy+XzKyclxNaegoEA+n6/Fo0+fPq5mSlJlZaVmz56tpKQkdevWTeeff77KyspczRw0aFCrtfp8Pi1cuNC1zPr6et1+++1KT09X165ddfbZZ2vZsmVqbGx0LVOSjhw5opycHKWlpalr164aO3as3nrrLVcz4a5Iz/xIz3vJm5nPvHd/3kuRn/mdad5L9s58SrukoqIi5eTkKD8/X+Xl5Ro/frwmTZrU4qPM3PDll19q5MiReuCBB1zNafLKK69o4cKFeuONNxQMBlVfX69AIKAvv/zS1dwBAwboN7/5jd5++229/fbb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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "prior = predict(belief, offset=3, kernel=[.05, .05, .6, .2, .1])\n", "book_plots.plot_belief_vs_prior(belief, prior, ylim=(0,0.6))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The position was correctly shifted by 3 positions and we give more weight to the likelihood of an overshoot vs an undershoot, so this looks correct.\n", "\n", "Make sure you understand what we are doing. We are making a prediction of where the dog is moving, and convolving the probabilities to get the prior.\n", "\n", "If we weren't using probabilities we would use this equation that I gave earlier:\n", "\n", "$$ \\bar x_{k+1} = x_k + f_{\\mathbf x}(\\bullet)$$\n", "\n", "The prior, our prediction of where the dog will be, is the amount the dog moved plus his current position. The dog was at 10, he moved 5 meters, so he is now at 15 m. It couldn't be simpler. But we are using probabilities to model this, so our equation is:\n", "\n", "$$ \\bar{ \\mathbf x}_{k+1} = \\mathbf x_k \\ast f_{\\mathbf x}(\\bullet)$$\n", "\n", "We are *convolving* the current probabilistic position estimate with a probabilistic estimate of how much we think the dog moved. It's the same concept, but the math is slightly different. $\\mathbf x$ is bold to denote that it is an array of numbers. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Integrating Measurements and Movement Updates\n", "\n", "The problem of losing information during a prediction may make it seem as if our system would quickly devolve into having no knowledge. However, each prediction is followed by an update where we incorporate the measurement into the estimate. The update improves our knowledge. The output of the update step is fed into the next prediction. The prediction degrades our certainty. That is passed into another update, where certainty is again increased.\n", "\n", "Let's think about this intuitively. Consider a simple case - you are tracking a dog while he sits still. During each prediction you predict he doesn't move. Your filter quickly *converges* on an accurate estimate of his position. Then the microwave in the kitchen turns on, and he goes streaking off. You don't know this, so at the next prediction you predict he is in the same spot. But the measurements tell a different story. As you incorporate the measurements your belief will be smeared along the hallway, leading towards the kitchen. On every epoch (cycle) your belief that he is sitting still will get smaller, and your belief that he is inbound towards the kitchen at a startling rate of speed increases.\n", "\n", "That is what intuition tells us. What does the math tell us?\n", "\n", "We have already programmed the update and predict steps. All we need to do is feed the result of one into the other, and we will have implemented a dog tracker!!! Let's see how it performs. We will input measurements as if the dog started at position 0 and moved right one position each epoch. As in a real world application, we will start with no knowledge of his position by assigning equal probability to all positions. " ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/png": "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HThwQOPGjWtyPpfLpWHDhukXv/iFLr/8cp+57Xa79fXXXzd5zKRJk/TnP/9Z/fr104gRI5rczi3tLdGpUyd973vf05YtW3wy6+vrtWnTJvXq1atFL88EJJ5pR4jbsmWLwsPDlZaW1viOBMOGDdMdd9zh97kWLFigjRs3auLEicrLy1NiYqJef/115efn65577mHwAkArXWhWR0ZG6u6779avfvUrdejQQePHj29895iEhAQtWLBA0jevSc/Pz9ett96qvn37yhijLVu26Msvv1RaWlpj1jXXXKPt27fr1VdfVc+ePdW5c2cNHDhQeXl58ng8Gj16tO6//34NHDhQf//733X48GEVFRVp7dq1TZ7pb4lly5YpLS1NY8eO1YMPPqjIyEjl5+frz3/+szZv3swz62gxSjtC2pYtW5Sbm6s1a9bI5XJp8uTJWrVqlSIjI/0+V/fu3VVcXKycnBzl5OSoqqpKffv21fLly5WVlRWAqweA9uHbZvWaNWvUr18/rV+/XqtXr1aXLl30ox/9SMuWLWt8+Uz//v11+eWXa/ny5Tp69KgiIyM1cOBAFRQUaObMmY1ZzzzzjObPn6+f/exnOnPmjG688UZt375dPXv21Pvvv6/HH39cTz31lD777DN17txZSUlJ+tGPfqSuXbu2am833nijtm3bpkWLFumuu+5SfX29hg0bpj/+8Y+aNGnSxX/y0G64jDHG6YsA2lpubq4WL16sEydONHm9IADADsxqoOV4TTsAAABgOUo7AAAAYDleHgMAAABYrlXPtOfn5yspKUlRUVFKSUnRzp07z3vs9u3b5XK5mtz+53/+p9UXDQAIDuY9ANjB79JeWFiozMxMLVy4UKWlpRozZozGjx+vsrKyCz7u4MGDqqioaLz179+/1RcNAAg85j0A2MPvl8d873vf03e/+12tWbOmcS05OVm33nqrli1b1uT47du3a+zYsfriiy90+eWXX/QFAwCCg3kPAPbw633aa2pqVFJS0uRXAaenp6u4uPiCjx0+fLj+/ve/6+qrr9ajjz56wd8e6fV65fV6G+/X19fr888/V7du3fglBABCnjFG1dXVio+PV4cOzrxfAPMeAALPn3nvV2k/efKkzp49q7i4OJ/1uLg4HTt2rNnH9OzZU+vWrVNKSoq8Xq+ef/55jRs3Ttu3b9cNN9zQ7GOWLVumxYsX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xIgR+ulPf6oePXpo+PDh+rd/+7eAZp6rpqZGmzZt0qxZs+RyuQKW8/3vf19/+tOf9Je//EWS9N///d/atWuXJkyYELDMuro6nT17VlFRUT7rHTt21K5duwKWi8Bg5gdv5jPvA8PpmR/K816yfOY7+r8MFigvLzeSzO7du33WlyxZYgYMGBC061CQn3mpr683kydPDtr/re/bt8906tTJhIWFmS5dupjXX3894JmbN282gwcPNl9//bUxxgTlmZeioiLz+9//3uzbt6/x2Z64uDhz8uTJgGW63W7jdrtNTk6O+eCDD8zatWtNVFSUee655wKWea7CwkITFhZmysvLA5pTX19vsrOzjcvlMuHh4cblcpmlS5cGNNMYY1JTU82NN95oysvLTV1dnXn++eeNy+UK6oxA27Bh5gd73hsT3JnPvA/cvDfG+Zkf6vPeGHtnPqX9/wd4cXGxz/oTTzxhBg4cGLTrCPYQz8jIMImJiebIkSNByfN6vebjjz82e/bsMdnZ2SY2NtZ89NFHAcsrKyszPXr0MHv37m1cC8YQP9dXX31l4uLizNNPPx2wjIiICJOamuqzdt9995lRo0YFLPNc6enpZtKkSQHP2bx5s+nVq5fZvHmz2bdvn9m4caO54oorTEFBQUBz//d//9fccMMNRpIJCwsz1113nbnzzjtNcnJyQHPR9myY+U6U9mDOfOZ94Oa9Mc7P/FCf98bYO/PbfWn3er0mLCzMbNmyxWf9/vvvNzfccEPQriOYQ/zee+81vXr1Mp988klQ8pozbtw4c/fddwfs/H/4wx8av9gabpKMy+UyYWFhpq6uLmDZ57r55pubvH62LfXu3dvMnj3bZy0/P9/Ex8cHLPMfHT582HTo0MG88sorAc/q1auXefbZZ33WHn/88aCVra+++socPXrUGGPMHXfcYSZMmBCUXLQdG2Z+sEu70zOfed+2nJz57WneG2PfzG/3r2mPjIxUSkpK409CN/B4PBo9erRDVxUYxhjde++92rJli7Zt26akpCRHr8Xr9Qbs/OPGjdOHH36ovXv3Nt5GjBihO++8U3v37lVYWFjAsv+R1+vVgQMH1LNnz4BlXH/99U3exu0vf/mLEhMTA5b5jzZs2KAePXpo4sSJAc86c+aMOnTwHVthYWFBeQswSerUqZN69uypL774Qm+++aZuueWWoOSi7TDznbkO5n3bcXLmt6d5L1k48x39XwZLvPTSSyYiIsKsX7/e7N+/32RmZppOnTqZw4cPBzS3urralJaWmtLSUiPJrFy50pSWlppPP/00IHn33HOP6dKli9m+fbupqKhovJ05cyYgeQ1ycnLM22+/bQ4dOmT27dtnHnnkEdOhQwezdevWgOaeKxjfLv3nf/5ns337dvPJJ5+Yd99910yaNMl07tw5oH+X/uu//suEh4ebJUuWmI8//ti88MILJjo62mzatClgmQ3Onj1revfubR5++OGAZxljzMyZM81VV11lXnvtNXPo0CGzZcsWExsbax566KGA5v7nf/6neeONN8wnn3xitm7daoYNG2ZGjhxpampqApqLwHBi5gd73hvjzMxn3gd23hvj3MxvL/PeGHtnPqX9/61evdokJiaayMhI893vfjcob4n11ltvGUlNbjNnzgxIXnNZksyGDRsCktdg1qxZjZ/b7t27m3HjxgV9gBsTnCE+ZcoU07NnTxMREWHi4+PN7bffHtDXcjZ49dVXzZAhQ4zb7TaDBg0y69atC3imMca8+eabRpI5ePBgUPKqqqrMAw88YHr37m2ioqJM3759zcKFC43X6w1obmFhoenbt6+JjIw0V155pZk/f7758ssvA5qJwAr2zA/2vDfGmZnPvA/8vDfGmZnfXua9MfbOfJcxxgTrWX0AAAAA/mv3r2kHAAAAbEdpBwAAACxHaQcAAAAsR2kHAAAALEdpBwAAACxHaQcAAAAsR2kHAAAALEdpBwAAACxHaQcAAAAsR2kHAAAALEdpBwAAACxHaQcAAAAs93/9/r8hbB0W7QAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from filterpy.discrete_bayes import update\n", "\n", "hallway = np.array([1, 1, 0, 0, 0, 0, 0, 0, 1, 0])\n", "prior = np.array([.1] * 10)\n", "likelihood = lh_hallway(hallway, z=1, z_prob=.75)\n", "posterior = update(likelihood, prior)\n", "book_plots.plot_prior_vs_posterior(prior, posterior, ylim=(0,.5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After the first update we have assigned a high probability to each door position, and a low probability to each wall position. " ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAu0AAAF0CAYAAACXPwdxAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAsWUlEQVR4nO3de3SU9Z3H8c+Qy4QgQUwgEgkhUC4RBGmQEixaxKTltl7aSotcPMARDF5C1qOJ6BKigItIsZVA2VIQUcy2UrdqXJlTLgJRF2NYrLDUrWAwhCJRCYKdJOS3f7jJ6ZAQMyEzz4/J+3XOnOM8eeb5PL+QfOfjk8nEZYwxAgAAAGCtDk6fAAAAAIDmUdoBAAAAy1HaAQAAAMtR2gEAAADLUdoBAAAAy1HaAQAAAMtR2gEAAADLUdoBAAAAy1HaAQAAAMtR2tHuLVmyRK+88kpAjn3kyBG5XC5t2LAhIMcHALSN3r1766677nL6NIALchljjNMnATjpsssu009+8pOAFGuv16vS0lL17dtX3bp1a/PjAwDaRmlpqWJiYtS3b1+nTwVoUrjTJwCEonPnzqm2tlZut1sjR45ss+N+/fXXioqKksvlarNjAkB79vXXX6tjx44aNmxYmx3zH58DgLbCy2Nglby8PLlcLpWWlur2229XTEyMunTpoqlTp+qzzz5r2K+urk7Lli3TwIED5Xa71b17d02fPl2ffvqpz/FKS0s1ceJEde/eXW63WwkJCZowYULDfi6XS2fOnNFzzz0nl8sll8ulH/zgBw2PP378uObMmaOePXsqMjJSycnJWrRokWpraxv2qX8JzLJly/TEE08oOTlZbrdb27dvv+DLY3bv3q2xY8eqc+fOio6O1qhRo/T666/77LNhwwa5XC5t3bpVM2fOVLdu3RQdHS2v19tGn20ACA0tfe7o3bu3Jk6cqC1btmjYsGGKiorSokWLGj52/stjysrKNHXq1IbnkJSUFD399NOqq6tr2Ke55wCgLXGlHVa67bbbdMcdd2ju3Ln68MMP9dhjj+nAgQN69913FRERoXvuuUdr167Vvffeq4kTJ+rIkSN67LHHtGPHDr3//vuKi4vTmTNnlJ6eruTkZK1atUrx8fE6fvy4tm/frtOnT0uS3n77bd10000aM2aMHnvsMUlSTEyMpG8K+4gRI9ShQwf9y7/8i/r27au3335bTzzxhI4cOaL169f7nPMvf/lL9e/fX8uXL1dMTIz69evX5Np27typ9PR0DRkyROvWrZPb7VZBQYEmTZqkzZs3a/LkyT77z5w5UxMmTNDzzz+vM2fOKCIioq0/3QAQEr7tuUOS3n//fR08eFCPPvqokpOT1alTpyaP9dlnn2nUqFGqrq7W448/rt69e+u1117Tgw8+qL/+9a8qKCjw2b+lzwFAqxnAIgsXLjSSzPz58322v/DCC0aS2bRpkzl48KCRZDIzM332effdd40k88gjjxhjjHnvvfeMJPPKK680m9mpUyczY8aMRtvnzJljLrvsMvPJJ5/4bF++fLmRZD788ENjjDGHDx82kkzfvn1NdXW1z771H1u/fn3DtpEjR5ru3bub06dPN2yrra01gwcPNj179jR1dXXGGGPWr19vJJnp06c3e/4A0N615LnDGGOSkpJMWFiYOXToUKNjJCUl+TwX5OTkGEnm3Xff9dnvnnvuMS6Xq+EYzT0HAG2Jl8fASnfeeafP/TvuuEPh4eHavn17w48cz/8x5ogRI5SSkqI//elPkqTvfOc76tq1qx5++GGtWbNGBw4c8OscXnvtNY0ZM0YJCQmqra1tuI0bN07SN1fM/9E//dM/fetV8DNnzujdd9/VT37yE1122WUN28PCwjRt2jR9+umnOnTokM9jfvzjH/t13gDQXjX33FFvyJAh6t+//7cea9u2bbr66qs1YsQIn+133XWXjDHatm2bz/aWPAcAF4PSDitdeeWVPvfDw8MVGxuryspKVVZWSpJ69OjR6HEJCQkNH+/SpYt27typa6+9Vo888ogGDRqkhIQELVy4UDU1Nd96Dn/729/06quvKiIiwuc2aNAgSdLJkyd99m/qfM73xRdfyBhzwXOX1HD+/hwXAND8c0e9ls7UyspKZjWswmvaYaXjx4/rqquuarhfW1uryspKxcbGKjY2VpJUUVGhnj17+jzu2LFjiouLa7h/zTXX6KWXXpIxRvv379eGDRuUn5+vjh07Kicnp9lziIuL05AhQ7R48eImP14/uOu15B1dunbtqg4dOqiioqLRx44dO9aQ6+9xAQDNP3fUa+lMjY2NZVbDKlxph5VeeOEFn/v//u//rtraWv3gBz/QTTfdJEnatGmTzz579+7VwYMHNXbs2EbHc7lcGjp0qH7xi1/o8ssv1/vv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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "kernel = (.1, .8, .1)\n", "prior = predict(posterior, 1, kernel)\n", "book_plots.plot_prior_vs_posterior(prior, posterior, True, ylim=(0,.5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The predict step shifted these probabilities to the right, smearing them about a bit. Now let's look at what happens at the next sense." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "image/png": "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cOCAhg8fXuN4Ho9H/fv3169+9StdffXVAXPb6/Xqm2++qfGY0aNH6y9/+Yu6du2qgQMH1rhdWNrromXLlvrBD36gTZs2BWRWVlZq3bp16tixY52englIXGlHmNu0aZMiIyOVlpZW/Y4E/fv319133x30sWbOnKk1a9Zo1KhRmjt3rpKSkvTmm28qLy9P999/P4MXAOrpUrM6Ojpa9913n37zm9+oWbNmGjFiRPW7xyQmJmrmzJmSvn1Oel5enu644w516dJFxhht2rRJX331ldLS0qqzrr/+em3dulWvv/66OnTooFatWqlHjx6aO3eufD6fhgwZooceekg9evTQP/7xDx05ckT5+flavnx5jSv9dbFgwQKlpaVp2LBheuSRRxQdHa28vDz95S9/0fr167myjjqjtCOsbdq0Sbm5uVq2bJk8Ho/GjBmjJUuWKDo6OuhjtWvXTrt27VJOTo5ycnJUWlqqLl26aOHChcrKynJg9QDQNFxuVi9btkxdu3bVypUrtXTpUrVu3Vo/+clPtGDBguqnz3Tr1k1XX321Fi5cqGPHjik6Olo9evTQ6tWrNWnSpOqs559/XjNmzNAvfvELnTt3Trfccou2bt2qDh066MMPP9RTTz2lZ599Vp9//rlatWql5ORk/eQnP1GbNm3qdW633HKLtmzZotmzZ+vee+9VZWWl+vfvrz/96U8aPXr0lX/z0GR4jDHG7UUADS03N1dz5szRyZMnazxfEABgB2Y1UHc8px0AAACwHKUdAAAAsBxPjwEAAAAsV68r7Xl5eUpOTlZMTIxSUlK0ffv2i+67detWeTyeGrf/+Z//qfeiAQChwbwHADsEXdo3btyozMxMzZo1SwUFBRo6dKhGjBihwsLCSz7u4MGDKi4urr5169at3osGADiPeQ8A9gj66TE/+MEP9P3vf1/Lli2r3tarVy/dcccdWrBgQY39t27dqmHDhunLL7/U1VdffcULBgCEBvMeAOwR1Pu0l5WVac+ePTU+Cjg9PV27du265GMHDBigf/zjH+rdu7eeeOKJS356pN/vl9/vr75fWVmpL774Qm3btuVDCACEPWOMzpw5o4SEBDVr5s77BTDvAcB5wcz7oEr7qVOndP78ecXHxwdsj4+P1/Hjx2t9TIcOHbRixQqlpKTI7/dr7dq1Gj58uLZu3aqbb7651scsWLBAc+bM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VqxYocLCQk2fPl3St3/qLCoq0po1ayRJS5cuVadOndSzZ09J376P76JFi/Tggw824GkAABoa8x4A7BF0aR87dqxKSko0d+5cFRcXq2/fvsrPz1dSUpIkqbi4WIWFhdX7V1ZWKicnR4cPH1ZkZKS6du2qZ555RtOmTWu4swAANDjmPQDYo14vRM3IyFBGRkatX1u9enXA/QcffJCrLADQSDHvAcAOQX+4EgAAAIDQorQDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJajtAMAAACWo7QDAAAAlqO0AwAAAJarV2nPy8tTcnKyYmJilJKSou3bt190302bNiktLU3t2rVTbGysUlNT9fbbb9d7wQCA0GHeA4Adgi7tGzduVGZmpmbNmqWCggINHTpUI0aMUGFhYa37v/vuu0pLS1N+fr727NmjYcOGacyYMSooKLjixQMAnMO8BwB7BF3aFy9erClTpmjq1Knq1auXlixZosTERC1btqzW/ZcsWaJHH31UN954o7p166b58+erW7duev3116948QAA5zDvAcAekcHsXFZWpj179ig7Oztge3p6unbt2lWnY1RWVurMmTO65pprLrqP3++X3++vvl9aWipJKi8vV3l5eTBLDkrVsZ3MsCHTrVzONfwy3coN93MN9XnVhnlvjytdY7j/vrid6VZuU8l0K9fGee8xxpi67nzs2DFdd9112rlzp4YMGVK9ff78+XrppZd08ODByx7j2Wef1TPPPKMDBw6offv2te6Tm5urOXPm1Nj+yiuvqEWLFnVdLgA0SufO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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "likelihood = lh_hallway(hallway, z=1, z_prob=.75)\n", "posterior = update(likelihood, prior)\n", "book_plots.plot_prior_vs_posterior(prior, posterior, ylim=(0,.5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice the tall bar at position 1. This corresponds with the (correct) case of starting at position 0, sensing a door, shifting 1 to the right, and sensing another door. No other positions make this set of observations as likely. Now we will add an update and then sense the wall." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "image/png": "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IWDsySefDFnY+vrrr83Ro0eNMcbcddddZuTIkSGpi8ZjQ88PdWh3u+fT7xuXmz2/KfV7Y+zr+U3+nvbo6GilpqbWvBK6ms/n0+DBg11alTOMMbr//vu1ceNGbd68WSkpKa6uxe/3O3b+4cOH6+OPP9aePXtqHgMGDNDdd9+tPXv2KCIiwrHa/8jv92v//v1q3769YzWGDBlS623c/vKXvyg5Odmxmv9o5cqVateunUaNGuV4rXPnzqlZs8C2FREREZK3AJOkFi1aqH379vryyy/19ttv67bbbgtJXTQeer4766DfNx43e35T6veShT3f1f9lsMT69etNVFSUWbFihdm3b5/JysoyLVq0MIcPH3a07pkzZ0xRUZEpKioyksyiRYtMUVGR+eyzzxypd99995lWrVqZLVu2mNLS0prHuXPnHKlXLTc317z77rvm0KFDZu/eveaxxx4zzZo1M5s2bXK07oVC8evSf/7nfzZbtmwxn376qXn//ffN6NGjTcuWLR39u/Rf//VfJjIy0sydO9ccPHjQvPzyyyY2NtasXbvWsZrVzp8/bzp27GgeffRRx2sZY8ykSZPMddddZ9544w1z6NAhs3HjRhMfH28eeeQRR+v+53/+p3nrrbfMp59+ajZt2mT69etnBg4caMrLyx2tC2e40fND3e+Ncafn0++d7ffGuNfzm0q/N8benk9o/z9LliwxycnJJjo62nz/+98PyVtivfPOO0ZSrcekSZMcqVdXLUlm5cqVjtSrNnny5Jrvbdu2bc3w4cND3sCNCU0THzt2rGnfvr2JiooyiYmJ5s4773T0Xs5qr7/+uunTp4/xer2mR48eZvny5Y7XNMaYt99+20gyBw4cCEm9srIy89BDD5mOHTuamJgY07lzZzNr1izj9/sdrbthwwbTuXNnEx0dba699lozY8YM89VXXzlaE84Kdc8Pdb83xp2eT793vt8b407Pbyr93hh7e77HGGNCdVUfAAAAQPCa/D3tAAAAgO0I7QAAAIDlCO0AAACA5QjtAAAAgOUI7QAAAIDlCO0AAACA5QjtAAAAgOUI7QAAAIDlCO0AAACA5QjtAAAAgOUI7QAAAIDlCO0AAACA5f4fU5vPEvx0T6sAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "prior = predict(posterior, 1, kernel)\n", "likelihood = lh_hallway(hallway, z=0, z_prob=.75)\n", "posterior = update(likelihood, prior)\n", "book_plots.plot_prior_vs_posterior(prior, posterior, ylim=(0,.5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is exciting! We have a very prominent bar at position 2 with a value of around 35%. It is over twice the value of any other bar in the plot, and is about 4% larger than our last plot, where the tallest bar was around 31%. Let's see one more cycle." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "image/png": "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/z5o9Ywx5uTJk0aS2blzZ1DrGmNMp06dzK9//WvH61RXV5s+ffoYj8djbrrpJvPQQw85Wm/hwoVm6NChjtY436OPPmp++MMfBrVmcx566CHTu3dvU19f71iNCRMmmBkzZviM3XHHHebuu+92rObZs2dNVFSUef31133Ghw4dahYsWOBYXTgn1D0/FP3emND1fPp9YNnQ88O13xtjd8+P+DPtNTU1KikpUWZmps94Zmam9uzZE6JZBcfp06clSVdddVXQap47d04vv/yyzpw5o/T0dMfrzZ07VxMmTNAtt9zieK0Ghw8fVlJSklJTU/Wzn/1Mn3zyiaP1/vCHP2j48OH66U9/qq5du2rYsGH693//d0drnq+mpkabNm3SjBkz5HK5HKvzwx/+UH/84x/15z//WZL0P//zP9q1a5fGjx/vWM26ujqdO3dOcXFxPuNt27bVrl27HKsLZ9Dzg9fz6ffOCHXPD+d+L1ne80P6vwwWKC8vN5LM7t27fcYXL15s+vbtG7R5KMhnXurr682kSZOC9n/r+/fvN+3btzdRUVGmY8eO5o033nC85ubNm82gQYPMN998Y4wxQTnzUlRUZH73u9+Z/fv3N57tSUxMNKdOnXKsptvtNm632+Tm5poPP/zQrFmzxsTFxZkXXnjBsZrn27Jli4mKijLl5eWO1qmvrzfz5883LpfLREdHG5fLZZYsWeJoTWOMSU9PNzfddJMpLy83dXV1ZuPGjcblcgW1RyAwbOj5we73xgS359Pvnev3xoS+54d7vzfG3p5PaP//DXzPnj0+40899ZTp169f0OYR7CaelZVlUlJSzLFjx4JSz+v1msOHD5u9e/ea+fPnm4SEBPPxxx87Vq+srMx07drV7Nu3r3EsGE38fF9//bVJTEw0zz77rGM1YmJiTHp6us/YAw88YEaOHOlYzfNlZmaaiRMnOl5n8+bNpnv37mbz5s1m//79ZsOGDeaqq64yhYWFjtb9v//7P3PjjTcaSSYqKspcf/315q677jIDBgxwtC4Cz4aeH4rQHsyeT793rt8bE/qeH+793hh7e37Eh3av12uioqLM1q1bfcYffPBBc+ONNwZtHsFs4vfff7/p3r27+eSTT4JSrzljx4419957r2PH//3vf9/4w9bwkGRcLpeJiooydXV1jtU+3y233NLk+tlA6tGjh5k5c6bPWEFBgUlKSnKs5t87evSoadOmjXn11Vcdr9W9e3fz/PPP+4w9+eSTQQtbX3/9tTl+/Lgxxpg777zTjB8/Pih1ETg29Pxgh/ZQ93z6fWCFsudHUr83xr6eH/HXtMfGxiotLa3xL6EbeDwejRo1KkSzcoYxRvfff7+2bt2q7du3KzU1NaRz8Xq9jh1/7Nix+uijj7Rv377Gx/Dhw3XXXXdp3759ioqKcqz23/N6vTp48KC6devmWI0bbrihyW3c/vznPyslJcWxmn9v/fr16tq1qyZMmOB4rbNnz6pNG9+2FRUVFZRbgElS+/bt1a1bN3355Zd66623dOuttwalLgKHnh+aedDvAyeUPT+S+r1kYc8P6f8yWOLll182MTExZt26debAgQMmOzvbtG/f3hw9etTRutXV1aa0tNSUlpYaSWbFihWmtLTUfPrpp47Uu++++0zHjh3Njh07TEVFRePj7NmzjtRrkJuba9555x1z5MgRs3//fvPYY4+ZNm3amG3btjla93zB+HXpv/zLv5gdO3aYTz75xLz33ntm4sSJpkOHDo6+l/77v//bREdHm8WLF5vDhw+bF1980bRr185s2rTJsZoNzp07Z3r06GEeffRRx2sZY8z06dPNNddcY15//XVz5MgRs3XrVpOQkGAeeeQRR+v+13/9l3nzzTfNJ598YrZt22aGDh1qRowYYWpqahytC2eEoucHu98bE5qeT793tt8bE7qeHyn93hh7ez6h/f9btWqVSUlJMbGxseb73/9+UG6J9fbbbxtJTR7Tp093pF5ztSSZ9evXO1KvwYwZMxq/t126dDFjx44NegM3JjhNfPLkyaZbt24mJibGJCUlmTvuuMPRazkbvPbaa2bw4MHG7Xab/v37m7Vr1zpe0xhj3nrrLSPJHDp0KCj1qqqqzEMPPWR69Ohh4uLiTK9evcyCBQuM1+t1tO6WLVtMr169TGxsrLn66qvN3LlzzVdffeVoTTgr2D0/2P3emND0fPq98/3emND0/Ejp98bY2/NdxhgTrLP6AAAAAPwX8de0AwAAALYjtAMAAACWI7QDAAAAliO0AwAAAJYjtAMAAACWI7QDAAAAliO0AwAAAJYjtAMAAACWI7QDAAAAliO0AwAAAJYjtAMAAACWI7QDAAAAlvt/C+DcduLePiwAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "prior = predict(posterior, 1, kernel)\n", "likelihood = lh_hallway(hallway, z=0, z_prob=.75)\n", "posterior = update(likelihood, prior)\n", "book_plots.plot_prior_vs_posterior(prior, posterior, ylim=(0,.5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I ignored an important issue. Earlier I assumed that we had a motion sensor for the predict step; then, when talking about the dog and the microwave I assumed that you had no knowledge that he suddenly began running. I mentioned that your belief that the dog is running would increase over time, but I did not provide any code for this. In short, how do we detect and/or estimate changes in the process model if we aren't directly measuring it?\n", "\n", "For now I want to ignore this problem. In later chapters we will learn the mathematics behind this estimation; for now it is a large enough task just to learn this algorithm. It is profoundly important to solve this problem, but we haven't yet built enough of the mathematical apparatus that is required, and so for the remainder of the chapter we will ignore the problem by assuming we have a sensor that senses movement." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Discrete Bayes Algorithm\n", "\n", "This chart illustrates the algorithm:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "image/png": "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Pixfvhx5eXlYunQpnnnmmRaPT05OxuTJk6FQKPDggw9i1KhR2LJlC2bOnIn6+nqTfR944AG8+OKLMBgMePTRRxEfH493330XTz75ZIfua9q0abjnnnsAAFOnTsWKFSuML09PzzaP7cl7++STT3DbbbchNTUVixYtwjPPPIOZM2ciJyenw8mOKIrYs2cPYmNjTe5l2LBhePPNN43/fv75543J1ssvv4zffvsNABAYGIh169Z16FotGT9+PABg165dXT4HERFRl4mdNG3aNBGAuGPHjg4fs2/fPhGAOGDAALGiosJYXlFRIcbGxooAxP379xvLd+/eLQIQAYibNm0yOdcf/vAHEYD4zTffmO0/dOhQsbq62liem5sr+vr6igDEe+65x+Q8GRkZZuXN51mxYkWL99HSMT19byNGjBBVKpVYVFRkFk9JSUmLcd7o/PnzIgDxrrvuMttmMBjE+Ph4Y0zTp08X9+/fL8pkMhGAKAiCmJiY2KHrtEar1YoAxClTpnTrPERERF3R6ZqdwsJCAECfPn06fMyGDRsAXGsqur5zr0ajwYoVK0z2ud6UKVOwZMkSk7J7770XAHD8+HFj2VdffQUAePXVV+Hq6mosDwkJ6XDNTlf19L0B1/oKKZVKs3P4+Ph0KMbc3FwAaLEmThAEbNy4Ef7+/gCA3bt3Y86cOcbmv6effhqzZs3q0HVa4+7uDicnJ2McREREvalXeouePHkSwLWmohs1l506dcps24gRI8zKmpOsiooKY9np06cBAJMnTzbbv6UyS+rpe1u8eDFqamoQFxeHZ599Fj///LPJ9o5o7iju5eXV4vaAgACsX7/e+O/q6moAwPDhw02aua63fv16DB48GGq1GoGBgXjooYfajMvb2xslJSWdipuIiMgSOp3sBAYGAgDy8vI6fIxWq4VMJoOfn5/ZtoCAAMhkMlRWVppta2mIt0JxbQCZXq83llVWVkImk8HX17fF8/eknr63559/Hp9//jkCAwPx7rvvYt68efDz88OCBQuQkZHRoRidnZ0BXBsl15r4+HhER0eblN1///1QqVRm+65Zswb33nsvzp07h9DQUGi1WqxduxYJCQkmsV+vrq4OLi4uHYqXiIjIkjqd7EycOBEAOjWyxsPDAwaDAcXFxWbbioqKYDAY4OHh0dlQjDQaDQwGQ4s1B1evXu3yeTuip+9NEAQsX74cycnJKC4uxvfff49bb70VP/74I2655ZZWk4vrNSdiZWVlre7zxhtvIDU11aTslVdeMUtqGxoajHMn/elPf8Lly5dx5MgRCIKAw4cP47///a/ZuQ0GAyorK1tMCImIiHpap5OdpUuXQi6X47PPPmvxF/z1GhoaAFxrDgGuDbu+0d69ewFcGxnUVUOHDgUA7N+/32xbS2WtkcvlANChBKJZT9/b9Xx8fLBw4UJs3rwZM2bMwMWLF5GWltbucYMGDYJMJjNLZpodOXIEr732mvHfzXMJlZWV4Y9//CNEUTRuS05ONiZNzcPYhwwZgqioKABAUlKS2flTU1NhMBgwePDgDt4pERGR5XQ62YmKisLzzz+PkpISzJkzp8WmlPr6erz77rvGZQmah3SvWrXKZNkArVZrnIuneZ+u+OMf/wgAeO2111BTU2Msz8vLw/vvv9/h83h7ewNApzrS9vS9JSYmoqmpyaRMp9MZE47mJqq2eHp6YsiQIUhOTjZJXACgqqoKd911l/EaDz30EBITE421Ubt27cLbb79t3D8nJ8f49+ZOzcD/mguv397s6NGjAK4N6SciIuptXZpB+fXXX0d9fT3ee+899O/fHzNmzEBcXByUSiUyMjKwY8cOlJaW4vXXXwdwbeTR448/jg8//BBxcXH43e9+B1EU8d///hc5OTl44oknMGXKlC7fxLRp07Bs2TJjp9lFixahoaEBmzdvxrhx4/Dzzz936DyxsbEIDg7Gpk2b4OLigj59+kAQBDz88MOtLhHR0/e2ZMkSuLi4YNKkSQgNDYVOp8Ovv/6KCxcuYMmSJejXr1+HzrNw4UKsXLkSx48fN1ku4tFHH0V6ejoAICIiAm+//Tbc3Nzw/vvvY9myZQCuNWfddNNNGDlypFmy1Ky5XBAEs22//vor5HI55s6d26l7JyIisojujFs/fvy4eO+994pRUVGis7OzqFarxbCwMPGOO+4Qk5KSzPZft26dOHr0aNHFxUV0cXERR48eLa5bt85sv7bmu2lprhtRFMWmpibxzTffFCMiIkSVSiVGRESIb7zxhpiWltbheXZEURSPHDkiTp06VXR3dzfOPZORkdHmMT15b2vWrBHnz58vhoaGik5OTqKPj484duxYce3ataJOpzM7R2tyc3NFuVwuPv7448ayb775xniPMplM3Ldvn8kxCxcu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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "book_plots.predict_update_chart()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This filter is a form of the g-h filter. Here we are using the percentages for the errors to implicitly compute the $g$ and $h$ parameters. We could express the discrete Bayes algorithm as a g-h filter, but that would obscure the logic of this filter.\n", "\n", "The filter equations are:\n", "\n", "$$\\begin{aligned} \\bar {\\mathbf x} &= \\mathbf x \\ast f_{\\mathbf x}(\\bullet)\\, \\, &\\text{Predict Step} \\\\\n", "\\mathbf x &= \\|\\mathcal L \\cdot \\bar{\\mathbf x}\\|\\, \\, &\\text{Update Step}\\end{aligned}$$\n", "\n", "$\\mathcal L$ is the usual way to write the likelihood function, so I use that. The $\\|\\|$ notation denotes taking the norm. We need to normalize the product of the likelihood with the prior to ensure $x$ is a probability distribution that sums to one.\n", "\n", "We can express this in pseudocode.\n", "\n", "**Initialization**\n", "\n", " 1. Initialize our belief in the state\n", " \n", "**Predict**\n", "\n", " 1. Based on the system behavior, predict state for the next time step\n", " 2. Adjust belief to account for the uncertainty in prediction\n", " \n", "**Update**\n", "\n", " 1. Get a measurement and associated belief about its accuracy\n", " 2. Compute how likely it is the measurement matches each state\n", " 3. Update state belief with this likelihood\n", "\n", "When we cover the Kalman filter we will use this exact same algorithm; only the details of the computation will differ.\n", "\n", "Algorithms in this form are sometimes called *predictor correctors*. We make a prediction, then correct them.\n", "\n", "Let's animate this. First Let's write functions to perform the filtering and to plot the results at any step. I've plotted the position of the doorways in black. Prior are drawn in orange, and the posterior in blue. I draw a thick vertical line to indicate where Simon really is. This is not an output of the filter - we know where Simon is only because we are simulating his movement." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "scrolled": true }, "outputs": [], "source": [ "def discrete_bayes_sim(prior, kernel, measurements, z_prob, hallway):\n", " posterior = np.array([.1]*10)\n", " priors, posteriors = [], []\n", " for i, z in enumerate(measurements):\n", " prior = predict(posterior, 1, kernel)\n", " priors.append(prior)\n", "\n", " likelihood = lh_hallway(hallway, z, z_prob)\n", " posterior = update(likelihood, prior)\n", " posteriors.append(posterior)\n", " return priors, posteriors\n", "\n", "\n", "def plot_posterior(hallway, posteriors, i):\n", " plt.title('Posterior')\n", " book_plots.bar_plot(hallway, c='k')\n", " book_plots.bar_plot(posteriors[i], ylim=(0, 1.0))\n", " plt.axvline(i % len(hallway), lw=5)\n", " plt.show()\n", " \n", "def plot_prior(hallway, priors, i):\n", " plt.title('Prior')\n", " book_plots.bar_plot(hallway, c='k')\n", " book_plots.bar_plot(priors[i], ylim=(0, 1.0), c='#ff8015')\n", " plt.axvline(i % len(hallway), lw=5)\n", " plt.show()\n", "\n", "def animate_discrete_bayes(hallway, priors, posteriors):\n", " def animate(step):\n", " step -= 1\n", " i = step // 2 \n", " if step % 2 == 0:\n", " plot_prior(hallway, priors, i)\n", " else:\n", " plot_posterior(hallway, posteriors, i)\n", " \n", " return animate" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's run the filter and animate it." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "30b640471e4c4f91a079e8f32994f7f3", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=1, description='step'), Output()), _dom_classes=('widget-interact',))" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# change these numbers to alter the simulation\n", "kernel = (.1, .8, .1)\n", "z_prob = 1.0\n", "hallway = np.array([1, 1, 0, 0, 0, 0, 0, 0, 1, 0])\n", "\n", "# measurements with no noise\n", "zs = [hallway[i % len(hallway)] for i in range(50)]\n", "\n", "priors, posteriors = discrete_bayes_sim(prior, kernel, zs, z_prob, hallway)\n", "interact(animate_discrete_bayes(hallway, priors, posteriors), step=IntSlider(value=1, max=len(zs)*2));" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can see the results. You can see how the prior shifts the position and reduces certainty, and the posterior stays in the same position and increases certainty as it incorporates the information from the measurement. I've made the measurement perfect with the line `z_prob = 1.0`; we will explore the effect of imperfect measurements in the next section. Finally, \n", "\n", "Another thing to note is how accurate our estimate becomes when we are in front of a door, and how it degrades when in the middle of the hallway. This should make intuitive sense. There are only a few doorways, so when the sensor tells us we are in front of a door this boosts our certainty in our position. A long stretch of no doors reduces our certainty." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Effect of Bad Sensor Data\n", "\n", "You may be suspicious of the results above because I always passed correct sensor data into the functions. However, we are claiming that this code implements a *filter* - it should filter out bad sensor measurements. Does it do that?\n", "\n", "To make this easy to program and visualize I will change the layout of the hallway to mostly alternating doors and hallways, and run the algorithm on 6 correct measurements:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "32ba45c576874b9d965aa34b6cbb2002", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=12, description='step', max=12), Output()), _dom_classes=('widget-intera…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "hallway = np.array([1, 0, 1, 0, 0]*2)\n", "kernel = (.1, .8, .1)\n", "prior = np.array([.1] * 10)\n", "zs = [1, 0, 1, 0, 0, 1]\n", "z_prob = 0.75\n", "priors, posteriors = discrete_bayes_sim(prior, kernel, zs, z_prob, hallway)\n", "interact(animate_discrete_bayes(hallway, priors, posteriors), step=IntSlider(value=12, max=len(zs)*2));" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have identified the likely cases of having started at position 0 or 5, because we saw this sequence of doors and walls: 1,0,1,0,0. Now I inject a bad measurement. The next measurement should be 0, but instead we get a 1:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAu0AAAF0CAYAAACXPwdxAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAq2ElEQVR4nO3df1RVdb7/8deRn2JQCYmggOiYUpQVNAXKmsygq479coqujZo/7o0rpcjkVXPWFU2jsZvLJlPz5o/RJnN5tbK7KDljhT+7KcLkUm/ltaRRiAulEIyHX/v7R1+ZmHM0j+nZnzjPx1pnLc+Hvc9+f97ss32x2WfjsCzLEgAAAABjdbG7AAAAAADnR2gHAAAADEdoBwAAAAxHaAcAAAAMR2gHAAAADEdoBwAAAAxHaAcAAAAMR2gHAAAADEdoBwAAAAxHaAcAA6xdu1YOh6P9ERgYqN69e2vChAk6ceLEJd1WY2OjCgoK9MEHH1zS1z3rgw8+kMPhuGyvDwD+KNDuAgAAf7NmzRoNHDhQf/3rX7Vjxw4VFhaqpKREBw8eVLdu3S7JNhobGzVv3jxJ0h133HFJXvP7brnlFu3du1fXXXfdJX9tAPBXhHYAMEhycrJSU1MlSUOHDlVra6uefvppvfnmm3rkkUdsru78mpub5XA4FBERodtvv/2SvW5jY6PCwsIu2esBwE8Rl8cAgMHOht/jx4/rzJkzmj17thITExUcHKxevXopNzdXp06d6rDOe++9pzvuuEORkZHq2rWr4uPjNXr0aDU2NuqLL77QNddcI0maN29e++U4jz76aPv6n332mcaMGaMePXooJCRESUlJeumllzps4+wlMOvXr9dvfvMb9erVSyEhITp69Og5L4/ZunWr0tLSFBYWpvDwcGVmZmrv3r0dlikoKJDD4dCBAwf0q1/9SldffbX69et3aZoJAD9hnGkHAIMdPXpUknTNNdfovvvu0/bt2zV79mxlZGTo448/1ty5c7V3717t3btXISEh+uKLLzRy5EhlZGRo9erVuuqqq3TixAm9++67ampqUkxMjN599139wz/8gyZNmqTJkye3v74kHT58WOnp6YqPj9fzzz+vnj17atu2bZo6dapqamo0d+7cDvXNnj1baWlpWrFihbp06aIePXqoqqrKbR6vvfaaHnnkEWVlZWnDhg1yuVxatGiR7rjjDm3fvl1DhgzpsPwDDzyghx9+WDk5OWpoaLgcrQWAnxRCOwAYpLW1VS0tLTpz5oxKSkq0YMEChYeHKyIiQtu2bdOiRYs0Y8YMSVJmZqbi4uKUnZ2tdevW6Z/+6Z9UWlqqM2fO6LnnntOgQYPaX3fMmDHt/05JSZEk9e7d2+0ylvz8fIWHh2vXrl2KiIho347L5dKzzz6rqVOn6uqrr25fvl+/ftq0adN559TW1qYZM2bohhtu0DvvvKMuXb77Je+IESPUr18/zZw5U7t37+6wzvjx49uvuwcAcHkMABjl9ttvV1BQkMLDw/XLX/5SPXv21DvvvKMDBw5IUofLWCTpwQcfVLdu3bR9+3ZJ0k033aTg4GD98z//s/7whz/o2LFjF7ztM2fOaPv27br//vsVFhamlpaW9seIESN05swZffjhhx3WGT169A++7ieffKKTJ09q7Nix7YFdkq644gqNHj1aH374oRobG71+XQDwJ4R2ADDIunXrtG/fPpWVlenkyZP6+OOPNXjwYNXW1iowMLD9MpazHA6HevbsqdraWknfnfn+05/+pB49eig3N1f9+vVTv3799MILL/zgtmtra9XS0qIXX3xRQUFBHR4jRoyQJNXU1HRYJyYm5oJe91zLxsbGqq2tTd98843XrwsA/oTLYwDAIElJSe13j/m+yMhItbS06P/+7/86BHfLslRVVaVbb721fSwjI0MZGRlqbW3V/v379eKLLyovL0/R0dF6+OGHz7ntq6++WgEBARo7dqxyc3M9LpOYmNjhucPh+ME5RUZGSpIqKyvdvnby5El16dKlwyU3F/q6AOBPONMOAD8Bw4YNkyS9+uqrHcY3b96shoaG9q9/X0BAgG677bb2O7+cvcQmJCREkvTXv/61w/JhYWEaOnSoysrKdOONNyo1NdXtcTaAe2PAgAHq1auXXnvtNVmW1T7e0NCgzZs3t99RBgBwbpxpB4CfgMzMTN19992aOXOm6urqNHjw4Pa7x9x8880aO3asJGnFihV67733NHLkSMXHx+vMmTNavXq1JOmuu+6SJIWHhyshIUFvvfWWhg0bpu7duysqKkp9+vTRCy+8oCFDhigjI0P/8i//oj59+qi+vl5Hjx7V22+/rffee8/r2rt06aJFixbpkUce0S9/+Us99thjcrlceu6553Tq1Ck9++yzl65RANBJEdoB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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "measurements = [1, 0, 1, 0, 0, 1, 1]\n", "priors, posteriors = discrete_bayes_sim(prior, kernel, measurements, z_prob, hallway);\n", "plot_posterior(hallway, posteriors, 6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That one bad measurement has significantly eroded our knowledge. Now let's continue with a series of correct measurements." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "image/png": "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Rqh9qRVrBGuEtdcINh71tGLFCvHy8hKDwSD9+vVT7XaB3333nQCotEyePFmV/KqyAcgnn3yiSv6UKVNMz3vbtm1l2LBhmjYdIuoWlvHjx0uHDh1Er9eLm5ubjBs3TrX3t1T48ssvpWfPnmJnZyc+Pj6yevVqVfP37NkjAOTcuXOq5oqI5OfnS0REhHh6eoq9vb107txZZs+eLUVFRarNITk5WTp37iwGg0FcXV0lPDxcbt26pVo+1U6r+iCibY3Quj6IWF+NULvxYI1gjbD2GqETEVHr7AoRERERETVPfI8HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HUT1t3LgR8fHxms5h9uzZ6Nu3L9q0aQN7e3t07twZ06dPx+XLlzWdFxFRc2cNNeJBv/zyC7p27QqdTod3331X6+lQM8XGg6ierKGo3Lp1C3/4wx/w6aefYvfu3fj73/+OHTt24IknnsCNGzc0nRsRUXNmDTXiQW+99RYKCwu1ngY1cy20ngAR1d+KFSvMvh4yZAi8vb0xcuRIbN++HVOmTNFoZkREZC2+//57fPDBB0hMTMTzzz+v9XSoGeMZD6Iq/PTTT5g+fTo8PDxgZ2eHtm3bIigoCF9//TWA+//gf/XVV7h8+TJ0Op1pqVBcXIz58+fDx8fHtP0rr7yCn376ySynU6dOGDVqFLZu3YrevXubLpdatmxZvefetm1bAECLFnxdgYhICY2pRhQXF2PKlCkIDw+Hv79/wzwBRPXE/0yIqjBx4kQcP34ccXFx6Nq1K27duoXjx4+bLl9KSEjA9OnTcf78eWzdutVs2/LycowZMwYHDx7ErFmzMHDgQFy+fBmxsbEYMmQIjh07BgcHB9P6mZmZiIyMxJw5c+Dq6orExERERESguLgYf//73+s039LSUpSUlODf//43IiMj0bVrV4wbN67hnhAiIjJpTDXi7bffRmFhIebNm1epsSFSnRBRJY888ohERkbWuE5oaKh4eXlVGk9KShIAsnnzZrPxtLQ0ASAJCQmm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1VYjKlh8qRVw/7T3g0Sk0lhVkpKSMGfOHGzfvt1UVABgwIABGDBggOnroKAg9OvXDx988AGWLVtW5WPFxMQgKirK9HV+fj48PDwQEhJS4w43lJKSEqSkpCA4OBh6vV7xPOZbV741zIH5zFczv+KsQW1YH+5rbscH85nP/OadX9caYVHj4eLiAltbW+Tl5ZmNX7t2De3bt69x2+TkZEydOhWfffYZhg8fXuO6NjY26N+/P7Kysqpdx87ODnZ2dpXG9Xq9qj9ktfOYb1351jAH5jNfjfzaMlgfqtZcjg+l8/uur/7nXb3HMWdzjkVbZEys+ixafTWV57+55/P4q1tWXVjUeBgMBvj5+SElJQVjx441jaekpGDMmDHVbpeUlIQpU6YgKSkJoaGhteaICDIzM9GrVy9Lpke/kuW/WI9jzqZLFm3R0L9U1HTU+w87j0GrwPpARES1sfhSq6ioKEycOBH+/v4IDAzE6tWrkZ2djbCwMAD3T3Hn5ORg3bp1AO4XlUmTJuH999/HgAEDTK+GOTg4oFWrVgCAuXPnYsCAAejSpQvy8/OxbNkyZGZmYsWKFQ21n0REpDDWByIiqonFjcf48eNx48YNvP3228jNzUXPnj2xc+dOeHl5AQByc3PN7tn+4YcforS0FOHh4QgPDzeNT548GWvXrgUA3Lp1C9OnT0deXh5atWqFvn374sCBAwgICPiVu0dERGphfSAioprU683lM2bMwIwZM6r8XkWxqLBv375aH++9997De++9V5+pEBGRFWF9ICKi6lj8yeVERERERESWYuNBRERERESKY+NBRERERESKY+NBRERERESKY+NBRERERESKY+NBRERERESKq9ftdImIiEg9fddn1WOrxzFn0yWLtsiY2KUeOdTU8fijhsLG4//hLxVpTY1jkMcfERERaYWXWhERERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeJ4O12i/4e3syUt8ZbeRETU1LHxICIiIqoBXxggrVl+DFrn8cdLrYiIiIiISHFsPIiIiIiISHFsPIiIiIiISHH1eo9HQkICFi9ejNzcXPTo0QPx8fF46qmnql1///79iIqKwunTp+Hm5oZZs2YhLCzMbJ3Nmzfjrbfewvnz5/HYY48hLi4OY8eOrc/0qJFqKtcvUuPE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uHfvHnbt2oXVq1fj6aefxujRoxV9noiImqPGUiMA4N1338XQoUPxzDPP4PXXX4dOp8OSJUtw/fp1vseDtKH1u9uJrM29e/ckLCxMevfuLUajURwcHKRbt24SGxtrdgeRmzdvynPPPSetW7cWnU4nD/46lZSUyLvvviu+vr5ib28vjzzyiPj4+Mif/vQnycrKMq3n5eUloaGh8vnnn0uPHj3EYDBIp06dZOnSpbXOMysrS0aOHCkdO3YUOzs7sbe3l169eklcXJzcu3evYZ8UIiISkcZTIyocPHhQBg8eLI6OjuLo6ChPP/20pKamNsyTQWQhnYiI1s0PUXPVqVMn9OzZEzt27NB6KkREZGVYI6ip4TuLiIiIiIhIcWw8iIiIiIhIcbzUioiIiIiIFMczHkREREREpDg2HkREREREpDg2HkREREREpLgm8wGC5eXluHr1KpycnKDT6bSeDhFRkyIiKCgogJubG2xsGtdrVqwPRETKqmuNaDKNx9WrV+Hh4aH1NIiImrQrV67A3d1d62lYhPWBiEgdtdWIJtN4ODk5Abi/w0ajUfG8kpIS7N27FyEhIdDr9YrnMd+68q1hDsxnvpr5+fn58PDwMP2tbUzUrg9A8zs+mM985jfv/LrWiCbTeFScPjcajao1Ho6OjjAajZodVMzXLt8a5sB85muR3xgvVVK7PgDN9/hgPvOZ37zza6sRjetCXSIiIiIiapTYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeKazAcIEhERKaXv+qx6bPU45my6ZNEWGRO71COHmjoef9RU8IwHEREREREpjo0HEREREREprl6NR0JCAry9vWFvbw8/Pz8cPHiw2nW3bNmC4OBgtG3bFkajEYGBgdizZ4/ZOmvXroVOp6u03Lt3rz7TIyIijbA+EBFRdSxuPJKTkxEZGYnZs2cjIyMDTz31FEaMGIHs7Owq1z9w4ACCg4Oxc+dOpKenY+jQoRg9ejQyMjLM1jMajcjNzTVb7O3t67dXRESkOtYHIiKqicVvLl+6dCmmTp2KadOmAQDi4+OxZ88erFy5EgsXLqy0fnx8vNnXCxYswPbt2/Hll1+ib9++pnGdTgdXV1dLp0PUYNR48x7fuEfVaQpvHmV9ICKimljUeBQXFyM9PR3R0dFm4yEhITh8+HCdHqO8vBwFBQVo06aN2fidO3fg5eWFsrIy9OnTB/PmzTMrPA8rKipCUVGR6ev8/HwAQElJCUpKSuq6S/VWkaFGFvOtL7++GnK+Wj8HzG9ex2Bt27E+NIyGmp/Wxyfzm9ffh+oep7k+/80xv65ZFjUe169fR1lZGdq3b2823r59e+Tl5dXpMZYsWYLCwkK88MILpjEfHx+sXbsWvXr1Qn5+Pt5//30EBQXhxIkT6NKl6lfnFi5ciLlz51Ya37t3LxwdHS3Yq18nJSVFtSzmK53/eAM+VtV27tzZ4I/ZtH4GzTlf+eMPqP8xePfu3Rq/3/Trg3X/fKrTdH4/mns+jz/mW3d+bTWigk5EpK4PevXqVXTs2BGHDx9GYGCgaTwuLg7r16/Hv//97xq3T0pKwrRp07B9+3YMHz682vXKy8vRr18/DBo0CMuWLatynape0fLw8MD169dhNBrrukv1VlJSgpSUFAQHB0Ov1yuex3zl8wMsvGSlPr5/sVODPVZT/Bk053w1jj+g/sdgfn4+XFxccPv27Sr/xjb1+mDtP5+HNbXfj+aez+OP+daeX1uNqGDRGQ8XFxfY2tpWevXq2rVrlV7lelhycjKmTp2Kzz77rMaiAgA2Njbo378/srKqv+bZzs4OdnZ2lcb1er2qP2S185hvXfmWUmKuWj8HzG8ex2Bt27E+NIyGnp/W+8x86z/mHsTjj/m/JqsuLLqrlcFggJ+fX6VTNykpKRg4cGC12yUlJeGPf/wjNm7ciNDQ0FpzRASZmZno0KGDJdMjIiKNsD4QEVFtLL6rVVRUFCZOnAh/f38EBgZi9erVyM7ORlhYGAAgJiYGOTk5WLduHYD7RWXSpEl4//33MWDAANOrYQ4ODmjVqhUAYO7cuRgwYAC6dOmC/Px8LFu2DJmZmVixYkVD7ScRESmM9YGIiGpiceMxfvx43LhxA2+//TZyc3PRs2dP7Ny5E15eXgCA3Nxcs3u2f/jhhygtLUV4eDjCw8NN45MnT8batWsBALdu3cL06dORl5eHVq1aoW/fvjhw4AACAgJ+5e4REZFaWB+IiKgmFjceADBjxgzMmDGjyu9VFIsK+/btq/Xx3nvvPbz33nv1mQoREVkR1gciIqqOxZ9cTkREREREZCk2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpDg2HkREREREpLgWWk+AiIiIrFvf9Vn12OpxzNl0yaItMiZ2qUcONXU8/poONh5kNSz/w8I/KtRwWNiIiIiUxUutiIiIiIhIcTzjYSX4aitpTY1jkMcfERFR88XGg0x4qRNpic03ERFR08bGg4iIiKgGfGGEtNZUXhyuV+ORkJCAxYsXIzc3Fz169EB8fDyeeuqpatffv38/oqKicPr0abi5uWHWrFkICwszW2fz5s146623cP78eTz22GOIi4vD2LFj6zO9euEfFdIaL3WipqAp1gciImoYFjceycnJiIyMREJCAoKCgvDhhx9ixIgROHPmDDw9PSutf/HiRYwcORKvvvoqNmzYgNTUVMyYMQNt27bF73//ewDAkSNHMH78eMybNw9jx47F1q1b8cILL+DQoUN44oknfv1eEhGR4lgflNPcXxxr7vuvteb+/Df3/W9IFt/VaunSpZg6dSqmTZuG7t27Iz4+Hh4eHli5cmWV669atQqenp6Ij49H9+7dMW3aNEyZMgXvvvuuaZ34+HgEBwcjJiYGPj4+iImJwbBhwxAfH1/vHSMiInWxPhARUU0sOuNRXFyM9PR0REdHm42HhITg8OHDVW5z5MgRhISEmI0988wzWLNmDUpKSqDX63HkyBH89a9/rbROTYWlqKgIRUVFpq9v374NALh58yZKSkos2S0AQNkvdyzepj5u3LhhlflqzYH5zNcyv6Y5NPf82hQUFAAARKTK7zfl+gBo//NhPvOZ33zz1ZpDfesDUHuNMBEL5OTkCABJTU01G4+Li5OuXbtWuU2XLl0kLi7ObCw1NVUAyNWrV0VERK/XS2Jiotk6iYmJYjAYqp1LbGysAODChQsXLiouV65cYX3gwoULFy5VLtXViAr1enO5Tqcz+1pEKo3Vtv7D45Y+ZkxMDKKiokxfl5eX4+bNm3B2dq5xu4aSn58PDw8PXLlyBUajUfE85ltXvjXMgfnMVzNfRFBQUAA3N7ca12N9uK+5HR/MZz7zm3d+XWuERY2Hi4sLbG1tkZeXZzZ+7do1tG/fvsptXF1dq1y/RYsWcHZ2rnGd6h4TAOzs7GBnZ2c21rp167ruSoMxGo2a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TfVBRLsaYU31QUS9GmGN9UGENUJNrBG143s8LGQwGODn52e6U0KFlJQUDBw4UKNZqUdEMHPmTGzZsgXffvstvL29tZ4SRARFRUWqZA0bNgynTp1CZmamafH398dLL72EzMxM2NraqjKPCkVFRTh79iw6dOigSl5QUFCl22P+8MMP8PLyUiW/wieffIJ27dohNDRU1dy7d+/Cxsb8z6atra2qt0qs0LJlS3To0AE///wz9uzZgzFjxqg+BzLH+mB99QFQr0ZYW30AWCNYI6ywRmjb9zROmzZtEr1eL2vWrJEzZ85IZGSktGzZUi5duqR4dkFBgWRkZEhGRoYAkKVLl0pGRoZcvnxZ8WwRkddee01atWol+/btk9zcXNNy9+5dVfJjYmLkwIEDcvHiRTl58qS88cYbYmNjI3v37lUlvypqnkr/29/+Jvv27ZMLFy7I0aNHZdSoUeLk5KTKsSci8v3330uLFi0kLi5OsrKyJDExURwdHWXDhg2q5IuIlJWViaenp7z++uuqZVaYPHmydOzYUXbs2CEXL16ULVu2iIuLi8yaNUu1OezevVt27dolFy5ckL1794qvr68EBARIcXGxanOg6mlZH0S0rRFa1wcR66sRal9qxRrBGmHtNYKNRz2tWLFCvLy8xGAwSL9+/VS7XeB3330nACotkydPViW/qmwA8sknn6iSP2XKFNPz3rZtWxk2bJimTYeIuoVl/Pjx0qFDB9Hr9eLm5ibjxo1T7f0tFb788kvp2bOn2NnZiY+Pj6xevVrV/D179ggAOXfunKq5IiL5+fkSEREhnp6eYm9vL507d5bZs2dLUVGRanNITk6Wzp07i8FgEFdXVwkPD5dbt26plk+106o+iGhbI7SuDyLWVyPUbjxYI1gjrL1G6ERE1Dq7QkREREREzRPf40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FERERERIpj40FUTxs3bkR8fLxm+ZcuXYJOp6t2+e1vf6vZ3IiImjutawQAFBUVYfHixejZsydatmyJ9u3bY8SIETh8+LCm86LmSyciovUkiBqjUaNG4V//+hcuXbqkSX5RUREyMjIqjW/btg2LFi3CqlWr8Kc//UmDmRERkdY1AgAmTZqExMRExMTE4Omnn8bNmzfxzjvv4MSJE0hNTUVAQIBmc6PmqYXWEyCi+rGzs8OAAQMqjcfExMDR0RF/+MMfNJgVERFZg6KiImzcuBETJkzA/PnzTeNBQUFwc3NDYmIiGw9SHS+1IqrCTz/9hOnTp8PDwwN2dnZo27YtgoKC8PXXXwMAhgwZgq+++gqXL182u7ypQnFxMebPnw8fHx/T9q+88gp++ukns5xOnTph1KhR2Lp1K3r37g17e3t07twZy5Ytq9e8z58/j/379+OFF16A0Wis/xNARETVagw1wsbGBjY2NmjVqpXZuNFohI2NDezt7RvgmSCyDM94EFVh4sSJOH78OOLi4tC1a1fcunULx48fx40bNwAACQkJmD59Os6fP4+tW7eabVteXo4xY8bg4MGDmDVrFgYOHIjLly8jNjYWQ4YMwbFjx+Dg4GBaPzMzE5GRkZgzZw5cXV2RmJiIiIgIFBcX4+9//7tF8/4//+f/QEQwbdq0X/8kEBFRlRpDjdDr9ZgxYwbWrFmD4cOHmy61euONN9CqVSu8+uqryjw5RDURIqrkkUcekcjIyBrXCQ0NFS8vr0rjSUlJAkA2b95sNp6WliYAJCEhwTTm5eUlOp1OMjMzzdYNDg4Wo9EohYWFdZ5zaWmpdOzYUXx8fOq8DRERWa6x1Ijy8nL5xz/+ITY2NgJAAIinp6dkZGTUvINECuGlVkRVCAgIwNq1azF//nwcPXoUJSUldd52x44daN26NUaPHo3S0lLT0qdPH7i6umLfvn1m6/fo0QO+vr5mYxMmTEB+fj6OHz9e59zdu3cjJycHU6dOrfM2RERkucZSI+Li4vDuu+9izpw5+O6777B9+3Z069YNwcHBVd6chEhpbDyIqpCcnIzJkyfj448/RmBgINq0aYNJkyYhLy+v1m3/+9//4tatWzAYDNDr9WZLXl4erl+/bra+q6trpceoGKs4bV8Xa9asgV6vx6RJk+q8DRERWa4x1IizZ8/iH//4B+bOnYu33noLQ4YMwbPPPouvvvoKrVu3RlRUlIV7TfTr8T0eRFVwcXFBfHw84uPjkZ2djS+++ALR0dG4du0adu/eXeu2zs7O1a7n5ORk9nVVhapizNnZuU7zvXbtGnbs2IFnn30W7dq1q9M2RERUP42hRpw4cQIigv79+5uN6/V6+Pr6Yv/+/TXOk0gJbDyIauHp6YmZM2fim2++QWpqqmnczs4Ov/zyS6X1R40ahU2bNqGsrAxPPPFErY9/+vRpnDhxwuxU+saNG+Hk5IR+/frVaY7r1q1DSUkJL7MiIlKZtdYINzc3AMDRo0cxePBg03hRURGOHz8Od3f3Ou0fUUNi40H0kNu3b2Po0KGYMGECfHx84OTkhLS0NOzevRvjxo0zrderVy9s2bIFK1euhJ+fH2xsbODv748XX3wRiYmJGDlyJCIiIhAQEAC9Xo///Oc/+O677zBmzBiMHTvW9Dhubm549tlnMWfOHHTo0AEbNmxASkoKFi1aBEdHxzrNec2aNfDw8MAzzzzT4M8HERH9r8ZSI5588kn0798fc+bMwd27dzFo0CDcvn0bH3zwAS5evIj169cr+jwRVUnrd7cTWZt79+5JWFiY9O7dW4xGozg4OEi3bt0kNjbW7A4iN2/elOeee05at24tOp1OHvx1KikpkXfffVd8fX3F3t5eHnnkEfHx8ZE//elPkpWVZVrPy8tLQkND5fPPP5cePXqIwWCQTp06ydKlS+s839TUVAEg//jHPxrmCSAiomo1phpx69YtmT17tnTv3l0cHR2lXbt2MmTIENm5c2fDPSFEFtCJiGjc+xA1W506dULPnj2xY8cOradCRERWhjWCmhre1YqIiIiIiBTHxoOIiIiIiBTHS62IiIiIiEhxPONBRERERESKY+NBRERERESKY+NBRERERESKazIfIFheXo6rV6/CyckJOp1O6+kQETUpIoKCggK4ubnBxqZxvWbF+kBEpKy61ogm03hcvXoVHh4eWk+DiKhJu3LlCtzd3bWehkVYH4iI1FFbjWgyjYeTkxOA+ztsNBoVzyspKcHevXsREhICvV6veB7zrSvfGubAfOarmZ+fnw8PDw/T39rGRO36ADS/44P5zGd+886va41oMo1Hxelzo9GoWuPh6OgIo9Go2UHFfO3yrWEOzGe+FvmN8VIltesD0HyPD+Yzn/nNO7+2GtG4LtQlIiIiIqJGiY0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREpjo0HEREREREprl6NR0JCAry9vWFvbw8/Pz8cPHiw2nW3bNmC4OBgtG3bFkajEYGBgdizZ4/ZOmvXroVOp6u03Lt3rz7TIyIijbA+EBFRdSxuPJKTkxEZGYnZs2cjIyMDTz31FEaMGIHs7Owq1z9w4ACCg4Oxc+dOpKenY+jQoRg9ejQyMjLM1jMajcjNzTVb7O3t67dXRESkOtYHIiKqSQtLN1i6dCmmTp2KadOmAQDi4+OxZ88erFy5EgsXLqy0fnx8vNnXCxYswPbt2/Hll1+ib9++pnGdTgdXV1dLp0NERFaC9aHp6rs+qx5bPY45my5ZtEXGxC71yKGmjsdf02FR41FcXIz09HRER0ebjYeEhODw4cN1eozy8nIUFBSgTZs2ZuN37tyBl5cXysrK0KdPH8ybN8+s8DysqKgIRUVFpq/z8/MBACUlJSgpKanrLtVbRYYaWcy3vnxrmAPzma9mfm05rA/mmtvx0VAaar5a7z/zefw15OM1hvy6ZulEROr6oFevXkXHjh2RmpqKgQMHmsYXLFiATz/9FOfOnav1MRYvXox33nkHZ8+eRbt27QAAR48exY8//ohevXohPz8f77//Pnbu3IkTJ06gS5equ885c+Zg7ty5lcY3btwIR0fHuu4SERHVwd27dzFhwgTcvn0bRqOx0vdZH5q2OfmPq5NjPKNKDjUuPP6sX201okK9Go/Dhw8jMDDQNB4XF4f169fj3//+d43bJyUlYdq0adi+fTuGDx9e7Xrl5eXo168fBg0ahGXLllW5TlWvaHl4eOD69es17nBDKSkpQUpKCoKDg6HX6xXPY7515VvDHJjPfDXz8/Pz4eLiUmvjwfpwX1M7PgIsvGSlvr5/sVODPE5Te/6bez6PP+vPr61GVLDoUisXFxfY2toiLy/PbPzatWto3759jdsmJydj6tSp+Oyzz2osKgBgY2OD/v37Iyur+mv67OzsYGdnV2lcr9er+kNWO4/51pVvDXNgPvPVyK8tg/Whas3l+GgoDT1Xrfef+Tz+msvzX9cci+5qZTAY4Ofnh5SUFLPxlJQUs1PrD0tKSsIf//hHbNy4EaGhobXmiAgyMzPRoUMHS6ZHREQaYX0gIqLaWHxXq6ioKEycOBH+/v4IDAzE6tWrkZ2djbCwMABATEwMcnJysG7dOgD3i8qkSZPw/vvvY8CAAaZXwxwcHNCqVSsAwNy5czFgwAB06dIF+fn5WLZsGTIzM7FixYqG2k8iIlIY6wMREdXE4sZj/PjxuHHjBt5++23k5uaiZ8+e2LlzJ7y8vAAAubm5Zvds//DDD1FaWorw8HCEh4ebxidPnoy1a9cCAG7duoXp06cjLy8PrVq1Qt++fXHgwAEEBAT8yt0jIiK1sD4QEVFNLG48AGDGjBmYMWNGld+rKBYV9u3bV+vjvffee3jvvffqMxUiIrIirA9ERFQdiz+5nIiIiIiIyFJsPIiIiIiISHFsPIiIiIiISHH1eo8HNby+66u/J331HsccCz9UJ2Ni1Z/0S6TGMcjjj4iIqPniGQ8iIiIiIlIcGw8iIiIiIlIcGw8iIiIiIlIc3+Px//A9FqQ1vseCiIiImjI2HmRi+T++bLyo4bD5JyIiatp4qRURERERESmOjQcRERERESmOjQcRERERESmOjQcRERERESmOjQcRERERESmOjQcRERERESmOt9MlIiKycs39dtPNff+11tyf/+a+/w2JjQcREVEt+I8HaYnHHzUVbDzIavADDElLLOxERETK4ns8iIiIiIhIcfVqPBISEuDt7Q17e3v4+fnh4MGDNa6/f/9++Pn5wd7eHp07d8aqVasqrbN582Y8/vjjsLOzw+OPP46tW7fWZ2pERKQh1gciIqqOxZdaJScnIzIyEgkJCQgKCsKHH36IESNG4MyZM/D09Ky0/sWLFzFy5Ei8+uqr2LBhA1JTUzFjxgy0bdsWv//97wEAR44cwfjx4zFv3jyMHTsWW7duxQsvvIBDhw7hiSee+PV7SUREimN9oKaKl2KS1prK5egWNx5Lly7F1KlTMW3aNABAfHw89uzZg5UrV2LhwoWV1l+1ahU8PT0RHx8PAOjevTuOHTuGd99911RY4uPjERwcjJiYGABATEwM9u/fj/j4eCQlJdV334gsokZhYVGh6jSFf2xYH4iIqCYWNR7FxcVIT09HdHS02XhISAgOHz5c5TZHjhxBSEiI2dgzzzyDNWvWoKSkBHq9HkeOHMFf//rXSutUFKOqFBUVoaioyPT17du3AQA3b95ESUmJJbsFACj75Y7F29THjRs3rDJfrTkwn/la5tc0h+aeX5uCggIAgIhU+f2mXB8A7X8+zGc+85tvvlpzqG99AGqvESZigZycHAEgqampZuNxcXHStWvXKrfp0qWLxMXFmY2lpqYKALl69aqIiOj1eklMTDRbJzExUQwGQ7VziY2NFQBcuHDhwkXF5cqVK6wPXLhw4cKlyqW6GlGhXrfT1el0Zl+LSKWx2tZ/eNzSx4yJiUFUVJTp6/Lycty8eRPOzs41btdQ8vPz4eHhgStXrsBoNCqex3zryreGOTCf+WrmiwgKCgrg5uZW43qsD/c1t+OD+cxnfvPOr2uNsKjxcHFxga2tLfLy8szGr127hvbt21e5jaura5Xrt2jRAs7OzjWuU91jAoCdnR3s7OzMxlq3bl3XXWkwRqNRs398ma99vjXMgfnMVyu/VatW1X6P9aFqzen4YD7zmd+882uqERUsup2uwWCAn58fUlJSzMZTUlIwcODAKrcJDAystP7evXvh7+8PvV5f4zrVPSYREVkX1gciIqqNxZdaRUVFYeLEifD390dgYCBWr16N7OxshIWFAbh/ijsnJwfr1q0DAISFhWH58uWIiorCq6++iiNHjmDNmjVmdyOJiIjAoEGDsGjRIowZMwbbt2/H119/jUOHDjXQbhIRkdJYH4iIqEY1vgOkGitWrBAvLy8xGAzSr18/2b9/v+l7kydPlsGDB5utv2/fPunbt68YDAbp1KmTrFy5stJjfvbZZ9KtWzfR6/Xi4+Mjmzdvrs/UVHPv3j2JjY2Ve/fuMb8Z5lvDHJjPfK1/B6rC+nCf1j8f5jOf+cy3tvogIqITqe2+V0RERERERL+ORe/xICIiIiIiqg82HkREREREpDg2HkREREREpDg2HkREREREpDg2HvWUkJAAb29v2Nvbw8/PDwcPHlQl98CBAxg9ejTc3Nyg0+mwbds2VXIrLFy4EP3794eTkxPatWuH3/3udzh37pxq+StXrkTv3r1NH4oTGBiIXbt2qZb/sIULF0Kn0yEyMlKVvDlz5kCn05ktrq6uqmRXyMnJwcsvvwxnZ2c4OjqiT58+SE9PVyW7U6dOlfZfp9MhPDxclfzS0lK8+eab8Pb2hoODAzp37oy3334b5eXlquQDQEFBASIjI+Hl5QUHBwcMHDgQaWlpquVT7bSqD4C2NULr+gBYV41Quz4ArBGsEdZfI9h41ENycjIiIyMxe/ZsZGRk4KmnnsKIESOQnZ2teHZhYSF8fX2xfPlyxbOqsn//foSHh+Po0aNISUlBaWkpQkJCUFhYqEq+u7s73nnnHRw7dgzHjh3D008/jTFjxuD06dOq5D8oLS0Nq1evRu/evVXN7dGjB3Jzc03LqVOnVMv++eefERQUBL1ej127duHMmTNYsmSJap8KnZaWZrbvFR8s9/zzz6uSv2jRIqxatQrLly/H2bNn8c9//hOLFy/GBx98oEo+AEybNg0pKSlYv349Tp06hZCQEAwfPhw5OTmqzYGqp2V9ALStEVrXB8B6aoRW9QFgjWCNsPIaofX9fBujgIAACQsLMxvz8fGR6OhoVecBQLZu3apq5sOuXbsmAMzu1a+2Rx99VD7++GNVMwsKCqRLly6SkpIigwcPloiICFVyY2NjxdfXV5Wsqrz++uvy5JNPapb/sIiICHnsscekvLxclbzQ0FCZMmWK2di4cePk5ZdfViX/7t27YmtrKzt27DAb9/X1ldmzZ6syB6qZtdQHEe1rhDXUBxH1a4RW9UGENeJhrBH3WVON4BkPCxUXFyM9PR0hISFm4yEhITh8+LBGs9LO7du3AQBt2rRRPbusrAybNm1CYWEhAgMDVc0ODw9HaGgohg8frmouAGRlZcHNzQ3e3t548cUXceHCBdWyv/jiC/j7++P5559Hu3bt0LdvX3z00Ueq5T+ouLgYGzZswJQpU6DT6VTJfPLJJ/HNN9/ghx9+AACcOHEChw4dwsiRI1XJLy0tRVlZGezt7c3GHRwc+EneVoD1wZyW9QHQrkZoWR8A1ogKrBH/y6pqhNadT2OTk5MjACQ1NdVsPC4uTrp27arqXKDxq1nl5eUyevRo1V/dOHnypLRs2VJsbW2lVatW8tVXX6man5SUJD169JBffvlFRETVV7R27twpn3/+uZw8edL0alr79u3l+vXrquTb2dmJnZ2dxMTEyPHjx2XVqlVib28vn376qSr5D0pOThZbW1vJyclRLbO8vFyio6NFp9NJixYtRKfTyYIFC1TLFxEJDAyUwYMHS05OjpSWlsr69etFp9Op/veHKrOm+iCibY3Qqj6IaFsjtKwPIqwRD2KNsM4awcbDQhWF5fDhw2bj8+fPl27duqk6F60bjxkzZoiXl5dcuXJF1dyioiLJysqStLQ0iY6OFhcXFzl9+rQq2dnZ2dKuXTvJzMw0jaldWB50584dad++vSxZskSVPL1eL4GBgWZjf/7zn2XAgAGq5D8oJCRERo0apWpmUlKSuLu7S1JSkpw8eVLWrVsnbdq0kbVr16o2hx9//FEGDRokAMTW1lb69+8vL730knTv3l21OVDVrKk+iGhbI7SqDyLa1Qhrqw8irBGsEdZXI9h4WKioqEhsbW1ly5YtZuN/+ctfZNCgQarORcuiMnPmTHF3d5cLFy5okv+gYcOGyfTp01XJ2rp1q+mXuWIBIDqdTmxtbaW0tFSVeTxo+PDhla4pV4qnp6dMnTrVbCwhIUHc3NxUya9w6dIlsbGxkW3btqma6+7uLsuXLzcbmzdvnib/VN65c0euXr0qIiIvvPCCjBw5UvU5kDlrqg8i2tUIa6oPIurVCGusDyKsEWpijagd3+NhIYPBAD8/P9OdEiqkpKRg4MCBGs1KPSKCmTNnYsuWLfj222/h7e2t9ZQgIigqKlIla9iwYTh16hQyMzNNi7+/P1566SVkZmbC1tZWlXlUKCoqwtmzZ9GhQwdV8oKCgirdHvOHH36Al5eXKvkVPvnkE7Rr1w6hoaGq5t69exc2NuZ/Nm1tbVW9VWKFli1bokOHDvj555+xZ88ejBkzRvU5kDnWB+urD4B6NcLa6gPAGsEaYYU1Qtu+p3HatGmT6PV6WbNmjZw5c0YiIyOlZcuWcunSJcWzCwoKJCMjQzIyMgSALF26VDIyMuTy5cuKZ4uIvPbaa9KqVSvZt2+f5Obmmpa7d++qkh8TEyMHDhyQixcvysmTJ+WNN94QGxsb2bt3ryr5VVHzVPrf/vY32bdvn1y4cEGOHj0qo0aNEicnJ1WOPRGR77//Xlq0aCFxcXGSlZUliYmJ4ujoKBs2bFAlX0SkrKxMPD095fXXX1cts8LkyZOlY8eOsmPHDrl48aJs2bJFXFxcZNasWarNYffu3bJr1y65cOGC7N27V3x9fSUgIECKi4tVmwNVT8v6IKJtjdC6PohYX41Q+1Ir1gjWCGuvEWw86mnFihXi5eUlBoNB+vXrp9rtAr/77jsBUGmZPHmyKvlVZQOQTz75RJX8KVOmmJ73tm3byrBhwzRtOkTULSzjx4+XDh06iF6vFzc3Nxk3bpxq72+p8OWXX0rPnj3Fzs5OfHx8ZPXq1arm79mzRwDIuXPnVM0VEcnPz5eIiAjx9PQUe3t76dy5s8yePVuKiopUm0NycrJ07txZDAaDuLq6Snh4uNy6dUu1fKqdVvVBRNsaoXV9ELG+GqF248EawRph7TVCJyKi1tkVIiIiIiJqnvgeDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbDyIiIiIiUhwbD6J62rhxI+Lj4zWdQ3FxMf7xj3/A29sbBoMBXl5eiImJwS+//KLpvIiImhNrqAc7duzApEmT0KtXL+j1euh0umrXLSkpwdy5c9GpUyfY2dnBx8cHH3zwgYqzpeaKjQdRPVlDofnDH/6AxYsXY/r06di5cyemTZuGpUuXYvz48ZrOi4ioObGGerB161YcPXoUjz/+OHx9fWtcd8aMGVi4cCHCw8OxZ88ejB07FhEREViwYIFKs6XmqoXWEyCi+jl69Ci2bNmCJUuWICoqCgAwfPhwtGjRAm+88QZSUlIQHBys8SyJiEgNH330EWxs7r+ePHPmTKSnp1e53unTp7FmzRrExcXhf/7nfwAAQ4YMwY0bNzB//nyEhYWhTZs2qs2bmhee8SCqwk8//YTp06fDw8MDdnZ2aNu2LYKCgvD1118DuP9H+quvvsLly5eh0+lMS4Xi4mLMnz8fPj4+pu1feeUV/PTTT2Y5nTp1wqhRo7B161b07t0b9vb26Ny5M5YtW1brHFNTUwEAI0eONBsfNWoUAGDz5s2/6jkgIqLGUQ8AmJqO2mzbtg0igldeecVs/JVXXsEvv/yC3bt31+lxiOqDZzyIqjBx4kQcP34ccXFx6Nq1K27duoXjx4/jxo0bAICEhARMnz4d58+fx9atW822LS8vx5gxY3Dw4EHMmjULAwcOxOXLlxEbG4shQ4bg2LFjcHBwMK2fmZmJyMhIzJkzB66urkhMTERERASKi4vx97//vdo5FhcXAwDs7OzMxiu+PnnyZIM8F0REzVljqAeW+Ne//oW2bdvC1dXVbLx3796m7xMpRoiokkceeUQiIyNrXCc0NFS8vLwqjSclJQkA2bx5s9l4WlqaAJCEhATTmJeXl+h0OsnMzDRbNzg4WIxGoxQWFlabv23bNgEg69evNxtfs2aNAJCuXbvWOH8iIqpdY6gHDwsPD5fq/sULDg6Wbt26Vfk9g8Eg06dPr3MOkaV4qRVRFQICArB27VrMnz8fR48eRUlJSZ233bFjB1q3bo3Ro0ejtLTUtPTp0weurq7Yt2+f2fo9evSo9EbACRMmID8/H8ePH682Z8SIEfjNb36D119/HSkpKbh16xZ2796NN954A7a2tnU+7U5ERNVrDPXAUjXd8aqm7xH9WvzPhKgKycnJmDx5Mj7++GMEBgaiTZs2mDRpEvLy8mrd9r///S9u3boFg8EAvV5vtuTl5eH69etm6z98uvvBsYpT+VUxGAzYtWsXPD09ERISgkcffRTPPfcc3njjDTz66KPo2LGjhXtNREQPawz1wBLOzs5VPlZhYSGKi4v5xnJSFN/jQVQFFxcXxMfHIz4+HtnZ2fjiiy8QHR2Na9eu1frGOxcXFzg7O1e7npOTk9nXVRWvijFnZ+cas37zm9/gyJEjyMnJwc2bN/HYY4/h9u3biIiIwKBBg2rcloiIatdY6kFd9erVC5s2bUJeXp5Zo3Pq1CkAQM+ePRskh6gqbDyIauHp6YmZM2fim2++Md1JCrj/Ju6qPqhv1KhR2LRpE8rKyvDEE0/U+vinT5/GiRMnzE6vb9y4EU5OTujXr1+d5tixY0fTGY4333wTLVu2xNSpU+u0LRER1U1jqAe1GTNmDN588018+umneP31103ja9euhYODA3772982SA5RVdh4ED3k9u3bGDp0KCZMmAAfHx84OTkhLS0Nu3fvxrhx40zr9erVC1u2bMHKlSvh5+cHGxsb+Pv748UXX0RiYiJGjhyJiIgIBAQEQK/X4z//+Q++++47jBkzBmPHjjU9jpubG5599lnMmTMHHTp0wIYNG5CSkoJFixbB0dGxxrn+85//hKurKzw9PfHf//4X//f//l9s27YN69ev56VWRES/UmOqB5cvX0ZaWhoA4Pz58wCAzz//HMD9W/X6+/sDuP8+kqlTpyI2Nha2trbo378/9u7di9WrV2P+/Pm81IqUpfW724mszb179yQsLEx69+4tRqNRHBwcpFu3bhIbG2t2V5GbN2/Kc889J61btxadTmd2B5GSkhJ59913xdfXV+zt7eWRRx4RHx8f+dOf/iRZWVmm9by8vCQ0NFQ+//xz6dGjhxgMBunUqZMsXbq0TnOdO3euPPbYY2JnZyetW7eW3/72t3LgwIGGezKIiJqxxlQPPvnkEwFQ5TJ58mSzdYuLiyU2NlY8PT3FYDBI165dZdmyZb/uySKqA52IiHZtD1Hz1qlTJ/Ts2RM7duzQeipERKQh1gNqDnhXKyIiIiIiUhwbDyIiIiIiUhwvtSIiIiIiIsXxjAcRERERESmOjQcRERERESmOjQcRERERESmuyXyAYHl5Oa5evQonJyfodDqtp0NE1KSICAoKCuDm5gYbm8b1mhXrAxGRsupaI5pM43H16lV4eHhoPQ0ioibtypUrcHd313oaFmF9ICJSR201osk0Hk5OTgDu77DRaFQ8r6SkBHv37kVISAj0er3iecy3rnxrmAPzma9mfn5+Pjw8PEx/axsTtesD0PyOD+Yzn/nNO7+uNaLJNB4Vp8+NRqNqjYejoyOMRqNmBxXztcu3hjkwn/la5DfGS5XUrg9A8z0+mM985jfv/NpqROO6UJeIiIiIiBolNh5ERERERKQ4Nh5ERERERKQ4Nh5ERERERKQ4Nh5ERERERKQ4Nh5ERERERKQ4Nh5ERERERKQ4Nh5ERERERKQ4Nh5ERERERKS4JvPJ5URERERK6Ls+qx5bPY45my5ZtEXGxC71yKHmwPJj0DqPP57xICIiIiIixdWr8UhISIC3tzfs7e3h5+eHgwcPVrvuli1bEBwcjLZt28JoNCIwMBB79uwxW2ft2rXQ6XSVlnv37tVnekREpBHWByIiqo7Fl1olJycjMjISCQkJCAoKwocffogRI0bgzJkz8PT0rLT+gQMHEBwcjAULFqB169b45JNPMHr0aPx//9//h759+5rWMxqNOHfunNm29vb29dglaqyaymlEapx4KcWvx/pAREQ1sbjxWLp0KaZOnYpp06YBAOLj47Fnzx6sXLkSCxcurLR+fHy82dcLFizA9u3b8eWXX5oVFp1OB1dXV0unQ0REVoL1gYiIamJR41FcXIz09HRER0ebjYeEhODw4cN1eozy8nIUFBSgTZs2ZuN37tyBl5cXysrK0KdPH8ybN8+s8DysqKgIRUVFpq/z8/MBACUlJSgpKanrLtVbRYYaWcxvOA05X62fA+Y372NQ7f2vLYf1wZzWxyfz+fehIR+P+Y0rv75+zXzruq1Fjcf169dRVlaG9u3bm423b98eeXl5dXqMJUuWoLCwEC+88IJpzMfHB2vXrkWvXr2Qn5+P999/H0FBQThx4gS6dKn6soSFCxdi7ty5lcb37t0LR0dHC/bq10lJSVEtq+nnP96Aj1W1nTt3NvhjNq2fQXPOV/74Axr+GFTr+b97926N32d9qFrT+f1o7vn8+8B8rfOt+3+k2mpEBZ2ISF0f9OrVq+jYsSMOHz6MwMBA03hcXBzWr1+Pf//73zVun5SUhGnTpmH79u0YPnx4teuVl5ejX79+GDRoEJYtW1blOlW9ouXh4YHr16/DaDTWdZfqraSkBCkpKQgODoZer1c8rznkB1h4rXx9fP9ipwZ7rKb4M2jO+Wocf0DDHYNqP//5+flwcXHB7du3q/wby/pgrqn9fjT3fP59YL7W+db+P1JtNaKCRWc8XFxcYGtrW+nVq2vXrlV6lethycnJmDp1Kj777LMaiwoA2NjYoH///sjKqv7NnnZ2drCzs6s0rtfrVT3I1M5j/q+jxFy1fg6Y37yPQbX2v7YM1oeqaX18Mp9/H5rz89/c8y31a+Za120tup2uwWCAn59fpVNHKSkpGDhwYLXbJSUl4Y9//CM2btyI0NDQWnNEBJmZmejQoYMl0yMiIo2wPhARUW0svqtVVFQUJk6cCH9/fwQGBmL16tXIzs5GWFgYACAmJgY5OTlYt24dgPtFZdKkSXj//fcxYMAA06thDg4OaNWqFQBg7ty5GDBgALp06YL8/HwsW7YMmZmZWLFiRUPtJxERKYz1gYiIamJx4zF+/HjcuHEDb7/9NnJzc9GzZ0/s3LkTXl5eAIDc3FxkZ2eb1v/www9RWlqK8PBwhIeHm8YnT56MtWvXAgBu3bqF6dOnIy8vD61atULfvn1x4MABBAQE/MrdIyIitbA+EBFRTSxuPABgxowZmDFjRpXfqygWFfbt21fr47333nt477336jMVIiKyIqwPRERUHYve40FERERERFQfbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxbDyIiIiIiEhxLbSeAJG16Ls+qx5bPY45my7Vee2MiV3qkUHNgRrHH8BjkIiItMMzHkREREREpDie8SAiIiKrxjOCpCUefw2HZzyIiIiIiEhxPONhJdhNk9b4HhciIiJSEs94EBERERGR4th4EBERERGR4nipFRERUS14OSxpiccfNRX1ajwSEhKwePFi5ObmokePHoiPj8dTTz1V7fr79+9HVFQUTp8+DTc3N8yaNQthYWFm62zevBlvvfUWzp8/j8ceewxxcXEYO3ZsfaZH9WT5Hzb+UaOGw8LaNLA+KIO/H6QlHn/UUCxuPJKTkxEZGYmEhAQEBQXhww8/xIgRI3DmzBl4enpWWv/ixYsYOXIkXn31VWzYsAGpqamYMWMG2rZti9///vcAgCNHjmD8+PGYN28exo4di61bt+KFF17AoUOH8MQTT/z6vSQiIsWxPjRd/MeTtMTjr+mw+D0eS5cuxdSpUzFt2jR0794d8fHx8PDwwMqVK6tcf9WqVfD09ER8fDy6d++OadOmYcqUKXj33XdN68THxyM4OBgxMTHw8fFBTEwMhg0bhvj4+HrvGBERqYv1gYiIamLRGY/i4mKkp6cjOjrabDwkJASHDx+ucpsjR44gJCTEbOyZZ57BmjVrUFJSAr1ejyNHjuCvf/1rpXVqKixFRUUoKioyfX379m0AwM2bN1FSUmLJbgEAhm7OtngbwBNvffIvi7b47veVX/UDgLJf7tQj33I3btyo9ntqzIH51eercQxWd/wB2u+/1r8DzT2/NgUFBQAAEany+025PgDa/3yYz3zmN998teZQ3/oA1F4jTMQCOTk5AkBSU1PNxuPi4qRr165VbtOlSxeJi4szG0tNTRUAcvXqVRER0ev1kpiYaLZOYmKiGAyGaucSGxsrALhw4cKFi4rLlStXWB+4cOHChUuVS3U1okK93lyu0+nMvhaRSmO1rf/wuKWPGRMTg6ioKNPX5eXluHnzJpydnWvcrqHk5+fDw8MDV65cgdFoVDyP+daVbw1zYD7z1cwXERQUFMDNza3G9Vgf7mtuxwfzmc/85p1f1xphUePh4uICW1tb5OXlmY1fu3YN7du3r3IbV1fXKtdv0aIFnJ2da1ynuscEADs7O9jZ2ZmNtW7duq670mCMRqNm//gyX/t8a5gD85mvVn6rVq2q/R7rQ9Wa0/HBfOYzv3nn11QjKlj05nKDwQA/Pz+kpKSYjaekpGDgwIFVbhMYGFhp/b1798Lf3x96vb7Gdap7TCIisi6sD0REVBuLL7WKiorCxIkT4e/vj8DAQKxevRrZ2dmm+67HxMQgJycH69atAwCEhYVh+fLliIqKwquvvoojR45gzZo1SEpKMj1mREQEBg0ahEWLFmHMmDHYvn07vv76axw6dKiBdpOIiJTG+kBERDWq8R0g1VixYoV4eXmJwWCQfv36yf79+03fmzx5sgwePNhs/X379knfvn3FYDBIp06dZOXKlZUe87PPPpNu3bqJXq8XHx8f2bx5c32mppp79+5JbGys3Lt3j/nNMN8a5sB85mv9O1AV1of7tP75MJ/5zGe+tdUHERGdSG33vSIiIiIiIvp1LP4AQSIiIiIiIkux8SAiIiIiIsWx8SAiIiIiIsWx8SAiIiIiIsWx8ainhIQEeHt7w97eHn5+fjh48KAquQcOHMDo0aPh5uYGnU6Hbdu2qZJbYeHChejfvz+cnJzQrl07/O53v8O5c+dUy1+5ciV69+5t+lCcwMBA7Nq1S7X8hy1cuBA6nQ6RkZGq5M2ZMwc6nc5scXV1VSW7Qk5ODl5++WU4OzvD0dERffr0QXp6uirZnTp1qrT/Op0O4eHhquSXlpbizTffhLe3NxwcHNC5c2e8/fbbKC8vVyUfAAoKChAZGQkvLy84ODhg4MCBSEtLUy2faqdVfQC0rRFa1wfAumqE2vUBYI1gjbD+GsHGox6Sk5MRGRmJ2bNnIyMjA0899RRGjBiB7OxsxbMLCwvh6+uL5cuXK55Vlf379yM8PBxHjx5FSkoKSktLERISgsLCQlXy3d3d8c477+DYsWM4duwYnn76aYwZMwanT59WJf9BaWlpWL16NXr37q1qbo8ePZCbm2taTp06pVr2zz//jKCgIOj1euzatQtnzpzBkiVLVPtU6LS0NLN9r/hgueeff16V/EWLFmHVqlVYvnw5zp49i3/+859YvHgxPvjgA1XyAWDatGlISUnB+vXrcerUKYSEhGD48OHIyclRbQ5UPS3rA6BtjdC6PgDWUyO0qg8AawRrhJXXCK3v59sYBQQESFhYmNmYj4+PREdHqzoPALJ161ZVMx927do1AWB2r361Pfroo/Lxxx+rmllQUCBdunSRlJQUGTx4sERERKiSGxsbK76+vqpkVeX111+XJ598UrP8h0VERMhjjz0m5eXlquSFhobKlClTzMbGjRsnL7/8sir5d+/eFVtbW9mxY4fZuK+vr8yePVuVOVDNrKU+iGhfI6yhPoioXyO0qg8irBEPY424z5pqBM94WKi4uBjp6ekICQkxGw8JCcHhw4c1mpV2bt++DQBo06aN6tllZWXYtGkTCgsLERgYqGp2eHg4QkNDMXz4cFVzASArKwtubm7w9vbGiy++iAsXLqiW/cUXX8Df3x/PP/882rVrh759++Kjjz5SLf9BxcXF2LBhA6ZMmQKdTqdK5pNPPolvvvkGP/zwAwDgxIkTOHToEEaOHKlKfmlpKcrKymBvb2827uDgwE/ytgKsD+a0rA+AdjVCy/oAsEZUYI34X1ZVI7TufBqbnJwcASCpqalm43FxcdK1a1dV5wKNX80qLy+X0aNHq/7qxsmTJ6Vly5Zia2srrVq1kq+++krV/KSkJOnRo4f88ssvIiKqvqK1c+dO+fzzz+XkyZOmV9Pat28v169fVyXfzs5O7OzsJCYmRo4fPy6rVq0Se3t7+fTTT1XJf1BycrLY2tpKTk6Oapnl5eUSHR0tOp1OWrRoITqdThYsWKBavohIYGCgDB48WHJycqS0tFTWr18vOp1O9b8/VJk11QcRbWuEVvVBRNsaoWV9EGGNeBBrhHXWCDYeFqooLIcPHzYbnz9/vnTr1k3VuWjdeMyYMUO8vLzkypUrquYWFRVJVlaWpKWlSXR0tLi4uMjp06dVyc7OzpZ27dpJZmamaUztwvKgO3fuSPv27WXJkiWq5On1egkMDDQb+/Of/ywDBgxQJf9BISEhMmrUKFUzk5KSxN3dXZKSkuTkyZOybt06adOmjaxdu1a1Ofz4448yaNAgASC2trbSv39/eemll6R79+6qzYGqZk31QUTbGqFVfRDRrkZYW30QYY1gjbC+GsHGw0JFRUVia2srW7ZsMRv/y1/+IoMGDVJ1LloWlZkzZ4q7u7tcuHBBk/wHDRs2TKZPn65K1tatW02/zBULANHpdGJrayulpaWqzONBw4cPr3RNuVI8PT1l6tSpZmMJCQni5uamSn6FS5cuiY2NjWzbtk3VXHd3d1m+fLnZ2Lx58zT5p/LOnTty9epVERF54YUXZOTIkarPgcxZU30Q0a5GWFN9EFGvRlhjfRBhjVATa0Tt+B4PCxkMBvj5+ZnulFAhJSUFAwcO1GhW6hERzJw5E1u2bMG3334Lb29vracEEUFRUZEqWcOGDcOpU6eQmZlpWvz9/fHSSy8hMzMTtra2qsyjQlFREc6ePYsOHTqokhcUFFTp9pg//PADvLy8VMmv8Mknn6Bdu3YIDQ1VNffu3buwsTH/s2lra6vqrRIrtGzZEh06dMDPP/+MPXv2YMyYMarPgcyxPlhffQDUqxHWVh8A1gjWCCusEdr2PY3Tpk2bRK/Xy5o1a+TMmTMSGRkpLVu2lEuXLimeXVBQIBkZGZKRkSEAZOnSpZKRkSGXL19WPFtE5LXXXpNWrVrJvn37JDc317TcvXtXlfyYmBg5cOCAXLx4UU6ePClvvPGG2NjYyN69e1XJr4qap9L/9re/yb59++TChQty9OhRGTVqlDg5Oaly7ImIfP/999KiRQuJi4uTrKwsSUxMFEdHR9mwYYMq+SIiZWVl4unpKa+//rpqmRUmT54sHTt2lB07dsjFixdly5Yt4uLiIrNmzVJtDrt375Zdu3bJhQsXZO/eveLr6ysBAQFSXFys2hyoelrWBxFta4TW9UHE+mqE2pdasUawRlh7jWDjUU8rVqwQLy8vMRgM0q9fP9VuF/jdd98JgErL5MmTVcmvKhuAfPLJJ6rkT5kyxfS8t23bVoYNG6Zp0yGibmEZP368dOjQQfR6vbi5ucm4ceNUe39LhS+//FJ69uwpdnZ24uPjI6tXr1Y1f8+ePQJAzp07p2quiEh+fr5ERESIp6en2NvbS+fOnWX27NlSVFSk2hySk5Olc+fOYjAYxNXVVcLDw+XWrVuq5VPttKoPItrWCK3rg4j11Qi1Gw/WCNYIa68ROhERtc6uEBERERFR88T3eBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeLYeBARERERkeL+f+hk1REZHh+PAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "with figsize(y=5.5):\n", " measurements = [1, 0, 1, 0, 0, 1, 1, 1, 0, 0]\n", " for i, m in enumerate(measurements):\n", " likelihood = lh_hallway(hallway, z=m, z_prob=.75)\n", " posterior = update(likelihood, prior)\n", " prior = predict(posterior, 1, kernel)\n", " plt.subplot(5, 2, i+1)\n", " book_plots.bar_plot(posterior, ylim=(0, .4), title=f'step {i+1}')\n", " plt.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We quickly filtered out the bad sensor reading and converged on the most likely positions for our dog." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Drawbacks and Limitations\n", "\n", "Do not be mislead by the simplicity of the examples I chose. This is a robust and complete filter, and you may use the code in real world solutions. If you need a multimodal, discrete filter, this filter works.\n", "\n", "With that said, this filter it is not used often because it has several limitations. Getting around those limitations is the motivation behind the chapters in the rest of this book.\n", "\n", "The first problem is scaling. Our dog tracking problem used only one variable, $pos$, to denote the dog's position. Most interesting problems will want to track several things in a large space. Realistically, at a minimum we would want to track our dog's $(x,y)$ coordinate, and probably his velocity $(\\dot{x},\\dot{y})$ as well. We have not covered the multidimensional case, but instead of an array we use a multidimensional grid to store the probabilities at each discrete location. Each `update()` and `predict()` step requires updating all values in the grid, so a simple four variable problem would require $O(n^4)$ running time *per time step*. Realistic filters can have 10 or more variables to track, leading to exorbitant computation requirements.\n", "\n", "The second problem is that the filter is discrete, but we live in a continuous world. The histogram requires that you model the output of your filter as a set of discrete points. A 100 meter hallway requires 10,000 positions to model the hallway to 1cm accuracy. So each update and predict operation would entail performing calculations for 10,000 different probabilities. It gets exponentially worse as we add dimensions. A 100x100 m$^2$ courtyard requires 100,000,000 bins to get 1cm accuracy.\n", "\n", "A third problem is that the filter is multimodal. In the last example we ended up with strong beliefs that the dog was in position 4 or 9. This is not always a problem. Particle filters, which we will study later, are multimodal and are often used because of this property. But imagine if the GPS in your car reported to you that it is 40% sure that you are on D street, and 30% sure you are on Willow Avenue. \n", "\n", "A forth problem is that it requires a measurement of the change in state. We need a motion sensor to detect how much the dog moves. There are ways to work around this problem, but it would complicate the exposition of this chapter, so, given the aforementioned problems, I will not discuss it further.\n", "\n", "With that said, if I had a small problem that this technique could handle I would choose to use it; it is trivial to implement, debug, and understand, all virtues." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tracking and Control\n", "\n", "We have been passively tracking an autonomously moving object. But consider this very similar problem. I am automating a warehouse and want to use robots to collect all of the items for a customer's order. Perhaps the easiest way to do this is to have the robots travel on a train track. I want to be able to send the robot a destination and have it go there. But train tracks and robot motors are imperfect. Wheel slippage and imperfect motors means that the robot is unlikely to travel to exactly the position you command. There is more than one robot, and we need to know where they all are so we do not cause them to crash.\n", "\n", "So we add sensors. Perhaps we mount magnets on the track every few feet, and use a Hall sensor to count how many magnets are passed. If we count 10 magnets then the robot should be at the 10th magnet. Of course it is possible to either miss a magnet or to count it twice, so we have to accommodate some degree of error. We can use the code from the previous section to track our robot since magnet counting is very similar to doorway sensing.\n", "\n", "But we are not done. We've learned to never throw information away. If you have information you should use it to improve your estimate. What information are we leaving out? We know what control inputs we are feeding to the wheels of the robot at each moment in time. For example, let's say that once a second we send a movement command to the robot - move left 1 unit, move right 1 unit, or stand still. If I send the command 'move left 1 unit' I expect that in one second from now the robot will be 1 unit to the left of where it is now. This is a simplification because I am not taking acceleration into account, but I am not trying to teach control theory. Wheels and motors are imperfect. The robot might end up 0.9 units away, or maybe 1.2 units. \n", "\n", "Now the entire solution is clear. We assumed that the dog kept moving in whatever direction he was previously moving. That is a dubious assumption for my dog! Robots are far more predictable. Instead of making a dubious prediction based on assumption of behavior we will feed in the command that we sent to the robot! In other words, when we call `predict()` we will pass in the commanded movement that we gave the robot along with a kernel that describes the likelihood of that movement." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simulating the Train Behavior\n", "\n", "We need to simulate an imperfect train. When we command it to move it will sometimes make a small mistake, and its sensor will sometimes return the incorrect value." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "class Train(object):\n", "\n", " def __init__(self, track_len, kernel=[1.], sensor_accuracy=.9):\n", " self.track_len = track_len\n", " self.pos = 0\n", " self.kernel = kernel\n", " self.sensor_accuracy = sensor_accuracy\n", "\n", " def move(self, distance=1):\n", " \"\"\" move in the specified direction\n", " with some small chance of error\"\"\"\n", "\n", " self.pos += distance\n", " # insert random movement error according to kernel\n", " r = random.random()\n", " s = 0\n", " offset = -(len(self.kernel) - 1) / 2\n", " for k in self.kernel:\n", " s += k\n", " if r <= s:\n", " break\n", " offset += 1\n", " self.pos = int((self.pos + offset) % self.track_len)\n", " return self.pos\n", "\n", " def sense(self):\n", " pos = self.pos\n", " # insert random sensor error\n", " if random.random() > self.sensor_accuracy:\n", " if random.random() > 0.5:\n", " pos += 1\n", " else:\n", " pos -= 1\n", " return pos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With that we are ready to write the filter. We will put it in a function so that we can run it with different assumptions. I will assume that the robot always starts at the beginning of the track. The track is implemented as being 10 units long, but think of it as a track of length, say 10,000, with the magnet pattern repeated every 10 units. A length of 10 makes it easier to plot and inspect." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "def train_filter(iterations, kernel, sensor_accuracy, \n", " move_distance, do_print=True):\n", " track = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", " prior = np.array([.9] + [0.01]*9)\n", " posterior = prior[:]\n", " normalize(prior)\n", " \n", " robot = Train(len(track), kernel, sensor_accuracy)\n", " for i in range(iterations):\n", " # move the robot and\n", " robot.move(distance=move_distance)\n", "\n", " # peform prediction\n", " prior = predict(posterior, move_distance, kernel) \n", "\n", " # and update the filter\n", " m = robot.sense()\n", " likelihood = lh_hallway(track, m, sensor_accuracy)\n", " posterior = update(likelihood, prior)\n", " index = np.argmax(posterior)\n", "\n", " if do_print:\n", " print(f'time {i}: pos {robot.pos}, sensed {m}, at position {track[robot.pos]}')\n", " conf = posterior[index] * 100\n", " print(f' estimated position is {index} with confidence {conf:.4f}%:') \n", "\n", " book_plots.bar_plot(posterior)\n", " if do_print:\n", " print()\n", " print('final position is', robot.pos)\n", " index = np.argmax(posterior)\n", " conf = posterior[index]*100\n", " print(f'Estimated position is {index} with confidence {conf:.4f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Read the code and make sure you understand it. Now let's do a run with no sensor or movement error. If the code is correct it should be able to locate the robot with no error. The output is a bit tedious to read, but if you are at all unsure of how the update/predict cycle works make sure you read through it carefully to solidify your understanding." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "time 0: pos 4, sensed 4, at position 4\n", " estimated position is 4 with confidence 99.9900%:\n", "time 1: pos 8, sensed 8, at position 8\n", " estimated position is 8 with confidence 100.0000%:\n", "time 2: pos 2, sensed 2, at position 2\n", " estimated position is 2 with confidence 100.0000%:\n", "time 3: pos 6, sensed 6, at position 6\n", " estimated position is 6 with confidence 100.0000%:\n", "\n", "final position is 6\n", "Estimated position is 6 with confidence 100.0000\n" ] }, { "data": { "image/png": "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+AFz586NhoaGruP9+/fHm2++GQMHDjzoeT7I2traYujQofHaa6/FgAEDsi4nE3qgBxF6UOz7j9CDCD0o9v1H6EFEcfQgl8tFe3t7DBky5JBz8wrtgwYNitLS0h531VtbW3vcTT/glFNO6XV+nz59YuDAgb2uKS8vj/Ly8m5jH/7wh/Mp9QNrwIABx+yFebj0QA8i9KDY9x+hBxF6UOz7j9CDiGO/B4e6w35AXh9E7du3b1RXV0dTU1O38aamphg1alSva2pra3vMX7NmTdTU1ByzzycBAMDRlPfbYxoaGuKuu+6KlStXxtatW2P27NnR3Nwc9fX1EfHOoy2TJk3qml9fXx+vvvpqNDQ0xNatW2PlypWxYsWKuP7664/eLgAA4BiW9zPtEyZMiB07dsTChQujpaUlRo4cGY2NjTF8+PCIiGhpaen2zvaqqqpobGyM2bNnx+233x5DhgyJ73//+/HlL3/56O3iGFBeXh7f/OY3ezwWVEz0QA8i9KDY9x+hBxF6UOz7j9CDCD3430pyh/OOGQAAIDN5Px4DAAAUltAOAACJE9oBACBxQjsAACROaE/E0qVLo6qqKioqKqK6ujrWr1+fdUkFs27duhg/fnwMGTIkSkpK4rHHHsu6pIJatGhRfOYzn4kTTjghTj755PjiF78YL7zwQtZlFdSyZcvivPPO6/oFGrW1tfHTn/4067Iys2jRoigpKYlZs2ZlXUpBzZ8/P0pKSrp9nXLKKVmXVVCvv/56fO1rX4uBAwdG//7945Of/GRs2rQp67IK5vTTT+9xDZSUlMSMGTOyLq1g9u7dG3/9138dVVVV0a9fvzjjjDNi4cKFsX///qxLK5j29vaYNWtWDB8+PPr16xejRo2KZ555JuuyMie0J2D16tUxa9asmDdvXmzevDlGjx4dY8eO7fbqzGPZrl274vzzz4/bbrst61IysXbt2pgxY0b88pe/jKampti7d2/U1dXFrl27si6tYE477bT427/929i4cWNs3LgxLr744rjiiiviueeey7q0gnvmmWdi+fLlcd5552VdSibOPffcaGlp6fp69tlnsy6pYH7/+9/HBRdcEGVlZfHTn/40nn/++fjud79bNL8RPOKd6/9/fv8P/HLGr3zlKxlXVjjf/va344477ojbbrsttm7dGt/5znfi7/7u7+If/uEfsi6tYKZNmxZNTU1x7733xrPPPht1dXVx6aWXxuuvv551adnKkbnPfvazufr6+m5j55xzTm7OnDkZVZSdiMg9+uijWZeRqdbW1lxE5NauXZt1KZn6oz/6o9xdd92VdRkF1d7enjvrrLNyTU1Nuc9//vO56667LuuSCuqb3/xm7vzzz8+6jMzceOONuQsvvDDrMpJy3XXX5c4888zc/v37sy6lYC6//PLclClTuo196Utfyn3ta1/LqKLC2r17d660tDT3T//0T93Gzz///Ny8efMyqioN7rRnbM+ePbFp06aoq6vrNl5XVxcbNmzIqCqytHPnzoiIOOmkkzKuJBv79u2LBx98MHbt2hW1tbVZl1NQM2bMiMsvvzwuvfTSrEvJzEsvvRRDhgyJqqqq+OpXvxovv/xy1iUVzOOPPx41NTXxla98JU4++eT41Kc+Ff/4j/+YdVmZ2bNnT9x3330xZcqUKCkpybqcgrnwwgvjX/7lX+LFF1+MiIjf/OY38eSTT8a4ceMyrqww9u7dG/v27YuKiopu4/369Ysnn3wyo6rSkPdvROXo2r59e+zbty8qKyu7jVdWVsa2bdsyqoqs5HK5aGhoiAsvvDBGjhyZdTkF9eyzz0ZtbW384Q9/iA996EPx6KOPxsc//vGsyyqYBx98MDZt2hQbN27MupTMfO5zn4t77rknPvaxj8Xvfve7uPnmm2PUqFHx3HPPxcCBA7Mu73338ssvx7Jly6KhoSFuuumm+NWvfhUzZ86M8vLymDRpUtblFdxjjz0Wb731Vnz961/PupSCuvHGG2Pnzp1xzjnnRGlpaezbty9uueWW+PM///OsSyuIE044IWpra+Nb3/pWjBgxIiorK+OBBx6If/u3f4uzzjor6/IyJbQn4n/fRcjlckV1Z4F3XHPNNfHv//7vRXk34eyzz44tW7bEW2+9FQ8//HBMnjw51q5dWxTB/bXXXovrrrsu1qxZ0+PuUjEZO3Zs1//+xCc+EbW1tXHmmWfGD37wg2hoaMiwssLYv39/1NTUxK233hoREZ/61Kfiueeei2XLlhVlaF+xYkWMHTs2hgwZknUpBbV69eq477774v77749zzz03tmzZErNmzYohQ4bE5MmTsy6vIO69996YMmVKnHrqqVFaWhqf/vSnY+LEifHrX/8669IyJbRnbNCgQVFaWtrjrnpra2uPu+8c26699tp4/PHHY926dXHaaadlXU7B9e3bNz760Y9GRERNTU0888wz8b3vfS/uvPPOjCt7/23atClaW1ujurq6a2zfvn2xbt26uO2226KjoyNKS0szrDAbxx9/fHziE5+Il156KetSCmLw4ME9/pE6YsSIePjhhzOqKDuvvvpq/PM//3M88sgjWZdScDfccEPMmTMnvvrVr0bEO/+AffXVV2PRokVFE9rPPPPMWLt2bezatSva2tpi8ODBMWHChKiqqsq6tEx5pj1jffv2jerq6q5PyB/Q1NQUo0aNyqgqCimXy8U111wTjzzySPzrv/5r0f9H6YBcLhcdHR1Zl1EQl1xySTz77LOxZcuWrq+ampr4i7/4i9iyZUtRBvaIiI6Ojti6dWsMHjw461IK4oILLujxutcXX3wxhg8fnlFF2bn77rvj5JNPjssvvzzrUgpu9+7dcdxx3eNZaWlpUb3y8YDjjz8+Bg8eHL///e/jiSeeiCuuuCLrkjLlTnsCGhoa4qqrroqampqora2N5cuXR3Nzc9TX12ddWkG8/fbb8dvf/rbr+JVXXoktW7bESSedFMOGDcuwssKYMWNG3H///fHjH/84TjjhhK6fupx44onRr1+/jKsrjJtuuinGjh0bQ4cOjfb29njwwQfjF7/4RfzsZz/LurSCOOGEE3p8huH444+PgQMHFtVnG66//voYP358DBs2LFpbW+Pmm2+Otra2orm7OHv27Bg1alTceuutceWVV8avfvWrWL58eSxfvjzr0gpq//79cffdd8fkyZOjT5/iiynjx4+PW265JYYNGxbnnntubN68ORYvXhxTpkzJurSCeeKJJyKXy8XZZ58dv/3tb+OGG26Is88+O66++uqsS8tWpu+uocvtt9+eGz58eK5v3765T3/600X1ur+f//znuYjo8TV58uSsSyuI3vYeEbm7774769IKZsqUKV3X/0c+8pHcJZdckluzZk3WZWWqGF/5OGHChNzgwYNzZWVluSFDhuS+9KUv5Z577rmsyyqon/zkJ7mRI0fmysvLc+ecc05u+fLlWZdUcE888UQuInIvvPBC1qVkoq2tLXfdddflhg0blquoqMidccYZuXnz5uU6OjqyLq1gVq9enTvjjDNyffv2zZ1yyim5GTNm5N56662sy8pcSS6Xy2XzzwUAAOBweKYdAAASJ7QDAEDihHYAAEic0A4AAIkT2gEAIHFCOwAAJE5oBwCAxAntAACQOKEdAAASJ7QDAEDihHYAAEic0A4AAIn7v3Z09/OoLORTAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import random\n", "\n", "random.seed(3)\n", "np.set_printoptions(precision=2, suppress=True, linewidth=60)\n", "train_filter(4, kernel=[1.], sensor_accuracy=.999,\n", " move_distance=4, do_print=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that the code was able to perfectly track the robot so we should feel reasonably confident that the code is working. Now let's see how it fairs with some errors. " ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "time 0: pos 4, sensed 4, at position 4\n", " estimated position is 4 with confidence 96.0390%:\n", "time 1: pos 8, sensed 9, at position 8\n", " estimated position is 9 with confidence 52.1180%:\n", "time 2: pos 3, sensed 3, at position 3\n", " estimated position is 3 with confidence 88.3993%:\n", "time 3: pos 7, sensed 8, at position 7\n", " estimated position is 8 with confidence 49.3174%:\n", "\n", "final position is 7\n", "Estimated position is 8 with confidence 49.3174\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAu0AAAFlCAYAAABftdZPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAi80lEQVR4nO3df5SWZZ0/8PfIj0FMbIUcQQFHMyUpq6FaUE6r6bTosdrapHUTEzgnDqTibBbIngIz2WrzUKtQrKhlqZzSyvZQMrtbaFqbErQe5ZitJq0NcaAClG/DAM/3D7/Md2cHlQdhnkue1+ucOYf7muvi/lyfmYfznpv7uaehUqlUAgAAFOuwWhcAAAC8OKEdAAAKJ7QDAEDhhHYAACic0A4AAIUT2gEAoHBCOwAAFE5oBwCAwgntAABQOKEdAAAKV3Vov++++3LBBRdkxIgRaWhoyHe+852XXLNq1aq0tLRk0KBBOfHEE/PlL395f2oFAIC6VHVof+6553L66afnhhtu2Kf5Tz31VM4777xMnDgxa9asydVXX53LL788d911V9XFAgBAPWqoVCqV/V7c0JBvf/vbee973/uCcz7xiU/knnvuybp167rHZsyYkV/84hf5yU9+sr+nBgCAutH/YJ/gJz/5SVpbW3uMvetd78qyZcvS1dWVAQMG9FrT2dmZzs7O7uPdu3fn97//fYYOHZqGhoaDXTIAABx0lUol27Zty4gRI3LYYS9+A8xBD+0bNmxIU1NTj7Gmpqbs3LkzmzZtyvDhw3utWbhwYRYsWHCwSwMAgJr7zW9+k+OPP/5F5xz00J6k19XxPXfkvNBV87lz56atra37eMuWLRk1alSeeuqpHHnkkQev0Brq6urKD3/4w5x11ll7/d+HeqAHepDoQb3vP9GDRA/qff+JHiT10YNt27alubl5n/LtQQ/txx57bDZs2NBjbOPGjenfv3+GDh261zWNjY1pbGzsNX700UdnyJAhB6XOWuvq6srgwYMzdOjQQ/Yb86XogR4kelDv+0/0INGDet9/ogdJffRgz7725fbvg/6c9vHjx6e9vb3H2MqVKzNu3LhD9gsAAAAHUtWh/dlnn83atWuzdu3aJM8/0nHt2rVZv359kudvbZkyZUr3/BkzZuTpp59OW1tb1q1bl5tvvjnLli3Lxz72sQOzAwAAOMRVfXvMww8/nLPOOqv7eM+955dcckluvfXWdHR0dAf4JGlubs6KFSty5ZVX5sYbb8yIESPypS99Ke9///sPQPkAAHDoqzq0/8Vf/EVe7NHut956a6+xd7zjHfn5z39e7akAAID0wT3tAADAyyO0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAo3H6F9sWLF6e5uTmDBg1KS0tL7r///hed/41vfCOnn356Bg8enOHDh+fSSy/N5s2b96tgAACoN1WH9uXLl2f27NmZN29e1qxZk4kTJ2bSpElZv379Xuf/+Mc/zpQpUzJt2rQ8+uij+eY3v5mHHnoo06dPf9nFAwBAPag6tF9//fWZNm1apk+fnjFjxmTRokUZOXJklixZstf5P/3pT3PCCSfk8ssvT3Nzc84888x85CMfycMPP/yyiwcAgHrQv5rJO3bsyOrVqzNnzpwe462trXnwwQf3umbChAmZN29eVqxYkUmTJmXjxo351re+lfPPP/8Fz9PZ2ZnOzs7u461btyZJurq60tXVVU3Jrxh79nWo7m9f6IEeJHpQ7/tP9CDRg3rff6IHSX30oJq9NVQqlcq+Tv7tb3+b4447Lg888EAmTJjQPX7dddflq1/9ah5//PG9rvvWt76VSy+9NH/605+yc+fOvPvd7863vvWtDBgwYK/z58+fnwULFvQav/322zN48OB9LRcAAIq1ffv2XHTRRdmyZUuGDBnyonOrutK+R0NDQ4/jSqXSa2yPxx57LJdffnk++clP5l3velc6Ojpy1VVXZcaMGVm2bNle18ydOzdtbW3dx1u3bs3IkSPT2tr6kht6perq6kp7e3vOPffcF/xh5lCnB3qQ6EG97z/Rg0QP6n3/iR4k9dGDPXeT7IuqQvuwYcPSr1+/bNiwocf4xo0b09TUtNc1CxcuzBlnnJGrrroqSfLGN74xRxxxRCZOnJhrr702w4cP77WmsbExjY2NvcYHDBhwyH7R9qiHPb4UPdCDRA/qff+JHiR6UO/7T/QgObR7UM2+qnoj6sCBA9PS0pL29vYe4+3t7T1ul/mftm/fnsMO63mafv36JXn+Cj0AAPDiqn56TFtbW2666abcfPPNWbduXa688sqsX78+M2bMSPL8rS1Tpkzpnn/BBRfk7rvvzpIlS/Lkk0/mgQceyOWXX563ve1tGTFixIHbCQAAHKKqvqd98uTJ2bx5c6655pp0dHRk7NixWbFiRUaPHp0k6ejo6PHM9g9/+MPZtm1bbrjhhvzd3/1dXv3qV+fss8/OZz/72QO3CwAAOITt1xtRZ86cmZkzZ+71c7feemuvscsuuyyXXXbZ/pwKAADqXtW3xwAAAH1LaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMLtV2hfvHhxmpubM2jQoLS0tOT+++9/0fmdnZ2ZN29eRo8encbGxpx00km5+eab96tgAACoN/2rXbB8+fLMnj07ixcvzhlnnJGvfOUrmTRpUh577LGMGjVqr2suvPDC/O53v8uyZcvy2te+Nhs3bszOnTtfdvEAAFAPqg7t119/faZNm5bp06cnSRYtWpR77703S5YsycKFC3vN/8EPfpBVq1blySefzNFHH50kOeGEE15e1QAAUEeqCu07duzI6tWrM2fOnB7jra2tefDBB/e65p577sm4cePyuc99LrfddluOOOKIvPvd786nP/3pHH744Xtd09nZmc7Ozu7jrVu3Jkm6urrS1dVVTcmv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Cie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBw+xXaFy9enObm5gwaNCgtLS25//77X3Du3XffnXPPPTevec1rMmTIkIwfPz733nvvfhcMAAD1purQvnz58syePTvz5s3LmjVrMnHixEyaNCnr16/f6/z77rsv5557blasWJHVq1fnrLPOygUXXJA1a9a87OIBAKAeVB3ar7/++kybNi3Tp0/PmDFjsmjRoowcOTJLlizZ6/xFixbl4x//eN761rfm5JNPznXXXZeTTz453/ve91528QAAUA+qCu07duzI6tWr09ra2mO8tbU1Dz744D79Hbt37862bdty9NFHV3NqAACoW/2rmbxp06bs2rUrTU1NPcabmpqyYcOGffo7vvCFL+S5557LhRde+IJzOjs709nZ2X28devWJElXV1e6urqqKfkVY8++DtX97Qs90INED+p9/4keJHrQl/S43B7Uw+ugmr1VFdr3aGho6HFcqVR6je3NHXfckfnz5+e73/1ujjnmmBect3DhwixYsKDX+MqVKzN48ODqC34FaW9vr3UJNacHepDoQb3vP9GDpNQevL7WBRxQK1as2I9VetCXynwdHBjbt2/f57lVhfZhw4alX79+va6qb9y4sdfV9/9t+fLlmTZtWr75zW/mnHPOedG5c+fOTVtbW/fx1q1bM3LkyLS2tmbIkCHVlPyK0dXVlfb29px77rkZMGBArcupCT3Qg0QP6n3/iR4kZfdg/p2/rnUJB9R5551X9Ro96Bslvw4OlD13k+yLqkL7wIED09LSkvb29vzVX/1V93h7e3ve8573vOC6O+64I1OnTs0dd9yR888//yXP09jYmMbGxl7jAwYMOGS/aHvUwx5fih7oQaIH9b7/RA8SPegL+lt+Dw7l10E1+6r69pi2trZcfPHFGTduXMaPH5+lS5dm/fr1mTFjRpLnr5I/88wz+drXvpbk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uqq+cePGXlffObRddtllueeee3Lffffl+OOPr3U5fW7gwIF57WtfmyQZN25cHnrooXzxi1/MV77ylRpXdvCtXr06GzduTEtLS/fYrl27ct999+WGG25IZ2dn+vXrV8MKa+OII47IG97whjzxxBO1LqVPDB8+vNcPqWPGjMldd91Vo4pq5+mnn86//uu/5u677651KX3uqquuypw5c/LBD34wyfM/wD799NNZuHBh3YT2k046KatWrcpzzz2XrVu3Zvjw4Zk8eXKam5trXVpNuae9xgYOHJiWlpbud8jv0d7engkTJtSoKvpSpVLJRz/60dx9993593//97r/R2mPSqWSzs7OWpfRJ975znfmkUceydq1a7s/xo0bl7/927/N2rVr6zKwJ0lnZ2fWrVuX4cOH17qUPnHGGWf0etzrL3/5y4wePbpGFdXOLbfckmOOOSbnn39+rUvpc9u3b89hh/WMZ/369aurRz7uccQRR2T48OH5wx/+kHvvvTfvec97al1STbnSXoC2trZcfPHFGTduXMaPH5+lS5dm/fr1mTFjRq1L6xPPPvtsfvWrX3UfP/XUU1m7dm2OPvrojBo1qoaV9Y1Zs2bl9ttvz3e/+90ceeSR3f/rctRRR+Xwww+vcXV94+qrr86kSZMycuTIbNu2LXfeeWd+9KMf5Qc/+EGtS+sTRx55ZK/3MBxxxBEZOnRoXb234WMf+1guuOCCjBo1Khs3bsy1116brVu31s3VxSuvvDITJkzIddddlwsvvDA/+9nPsnTp0ixdurTWpfWp3bt355Zbbskll1yS/v3rL6ZccMEF+cxnPpNRo0bltNNOy5o1a3L99ddn6tSptS6tz9x7772pVCo55ZRT8qtf/SpXXXVVTjnllFx66aW1Lq22avrsGrrdeOONldGjR1cGDhxYectb3lJXj/v74Q9/WEnS6+OSSy6pdWl9Ym97T1K55ZZbal1an5k6dWr39/9rXvOayjvf+c7KypUra11WTdXjIx8nT55cGT58eGXAgAGVESNGVN73vvdVHn300VqX1ae+973vVcaOHVtpbGysnHrqqZWlS5fWuqQ+d++991aSVB5//PFal1ITW7durVxxxRWVUaNGVQYNGlQ58cQTK/Pmzat0dnbWurQ+s3z58sqJJ55YGThwYOXYY4+tzJo1q/LHP/6x1mXVXEOlUqnU5scFAABgX7inHQAACie0AwBA4YR2AAAonNAOAACFE9oBAKBwQjsAABROaAcAgMIJ7QAAUDihHQAACie0AwBA4YR2AAAonNAOAACF+7/aav+LsxGWiQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "random.seed(5)\n", "train_filter(4, kernel=[.1, .8, .1], sensor_accuracy=.9,\n", " move_distance=4, do_print=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There was a sensing error at time 1, but we are still quite confident in our position. \n", "\n", "Now let's run a very long simulation and see how the filter responds to errors." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAp8AAAHnCAYAAAD+cTY5AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAABSKElEQVR4nO3dfVyUZd738e+IMIgbuqIiKCK2mpabbVgbmKWpdIuZbe1ml21qyhYXpimV+dCV6PqwtZu3tYpWPmWWspm2PWA5966pqb1WDcpN1tx8oBRjxRKSwgGO+w9vuJsYdWaYOYXh83695o85OM/je8yDP38z58w5NmOMEQAAAGCBZpd6AQAAAGg6aD4BAABgGZpPAAAAWIbmEwAAAJah+QQAAIBlaD4BAABgGZpPAAAAWIbmEwAAAJah+QQAAIBlaD4hSVq1apVsNpuOHDlSO/bqq69q4cKFl2xNnqzDZrMpKyvL0vVIUllZmaZMmaKUlBS1a9fO43UYY3TTTTfJZrPpoYceqvP3EydO6KGHHlLXrl3VokULxcfHa9y4cSosLAzArQDgT9RR7wSqjhYVFWnMmDFq3769wsPDdfXVV2v58uUBuAXwFc0nJElDhw7Vrl27FBMTUzvWGIrmrl27lJaWZu2CJJWUlOiFF15QRUWF7rjjDo/3W7x4sf7973+7/VtFRYVuuukm5eTk6NFHH9WmTZs0ffp0vfPOO0pOTlZZWZmfVg8gEKij3glEHT19+rRuvPFG/e1vf9PTTz+tv/71r7r22muVlpamBQsW+GnlqK/ml3oBaBjatWundu3aWZL13XffqUWLFn6Z64YbbvDLPN6Kj4/X119/LZvNppMnT2rZsmUX3efIkSOaNm2aVq9erTvvvLPO37dv366DBw9q2bJlGjdunCSpf//+ioyM1MiRI/V//s//0a9+9Su/3xYA/kEd9U4g6uiSJUt06NAh7dmzR4mJiZKkW2+9VUVFRXryySc1duxYtW7d2t83BV7inU9Iqnu4qH///nrnnXd09OhR2Wy22kuNs2fPas6cOerRo4fsdrvatWun+++/X//5z39c5u3SpYtuu+02bdiwQb/4xS8UHh6uWbNmSTr36vWmm25S+/bt1bJlS/385z/X008/LafTWbv/xdbh7jDNP//5Tw0fPlw//elPFR4ermuuuUYvvfSSyzbvv/++bDab1q5dqxkzZig2NlaRkZEaNGiQDhw4cNH768fr8MQDDzygwYMHn7eBDA0NlSS1atXKZbymUIaHh3uVB8Ba1NFLX0d37Nih6Ojo2sazxm233aYzZ87o3Xff9SoPgcE7n3ArOztbDzzwgD7//HNt3LjR5W/V1dUaPny4tm/frilTpig5OVlHjx7VzJkz1b9/f+3Zs8flFflHH32kgoICPfHEE0pISFDLli0lSZ9//rlGjhyphIQEhYWF6eOPP9bcuXP1r3/9SytWrLjoOtw5cOCAkpOT1b59ez333HOKiorSmjVrNGbMGH311VeaMmWKy/bTp09X3759tWzZMpWWlurxxx/XsGHDVFBQoJCQkPrejbWWLVumf/zjH9q/f/95t+nbt68SExOVlZWl+Ph49ezZU5999pmmT5+ua6+9VoMGDfLbegAEHnXU+jp69uxZ2e32OuM1Y5988onuuecev60JPjKAMWblypVGkjl8+HDt2NChQ018fHydbdeuXWskmddff91lfPfu3UaSyc7Orh2Lj483ISEh5sCBAxfMr6qqMk6n06xevdqEhISYU6dOXXQdxhgjycycObP2+j333GPsdrspLCx02W7IkCEmIiLCfPPNN8YYY7Zs2WIkmdTUVJft/vKXvxhJZteuXRdc7w/95z//qbOOH/ryyy9Nq1atzPPPP++y7vHjx9fZtrS01AwbNsxIqr3079/flJSUeLweAJcGdfScS1lHJ02aZJo1a2aOHj3qMn7fffcZSeaBBx7weE0IHA67w2tvv/22WrdurWHDhqmysrL2cs0116hDhw56//33Xba/+uqr1b179zrz5OXl6fbbb1dUVJRCQkIUGhqqUaNGqaqqSp999plPa/v73/+ugQMHKi4uzmV8zJgxKi8v165du1zGb7/99jprlaSjR4/6lO9Oenq6evfurd/97ncX3M7pdGrEiBHKz8/Xiy++qG3btumll17SsWPHNHjwYJ0+fdpvawJwaVFHveNpHX3ggQcUGhqqe++9V59++qlKSkq0ePFi5eTkSJKaNaPtaQg47A6vffXVV/rmm28UFhbm9u8nT550uf7Db37WKCwsVL9+/XTFFVfo2WefVZcuXRQeHq5//OMfGj9+vL777juf1lZSUuI2LzY2tvbvPxQVFeVyvebQjK/5P7Z+/Xq9++67+uCDD+o0j2fPntU333yjli1bKjQ0VMuXL9emTZu0e/du9enTR5LUr18/3Xjjjbr88su1cOFCzZw50y/rAnBpUUc9500d7dmzpzZu3KgHH3xQvXr1kiTFxcXpmWee0YQJE9SxY0e/rAn1Q/MJr7Vt21ZRUVHn/eD2ZZdd5nLd3QfK33jjDZ05c0YbNmxQfHx87Xh+fn691hYVFaWioqI648ePH5d0bu1W+uc//6nKykq33yZ98cUX9eKLL2rjxo264447lJ+fr5CQEF177bUu23Xt2lVRUVH65z//adWyAQQYddRz3tRRSRoyZIiOHj2qf//736qsrFT37t31l7/8RZJ00003Wbl0nAfNJ87Lbre7feV62223ad26daqqqtIvf/lLn+auKaQ//GC4MUYvvviix+twZ+DAgdq4caOOHz9e+ypdklavXq2IiAjLTykyZswY9e/fv874gAEDdMcdd+jhhx+ufXUeGxurqqoq7d692+V+/eyzz1RSUqJOnTpZtWwAfkIdrT9v6mgNm82mbt26STr37uizzz6ra665huazgaD5xHn9/Oc/14YNG7RkyRIlJiaqWbNm6tOnj+655x698sorSk1N1cMPP6zrr79eoaGh+vLLL7VlyxYNHz78ouejHDx4sMLCwvRf//VfmjJlir7//nstWbJEX3/9tcfrcGfmzJl6++23NWDAAD355JNq06aNXnnlFb3zzjt6+umn65zGqD42bdqkM2fO1J78ff/+/Vq/fr0kKTU1VREREerSpYu6dOnidv+OHTu6FNT7779f//t//2/dddddeuKJJ3TFFVfo0KFDmjdvnlq2bKn09HS/rR2ANaijF+bvOipJEyZMUP/+/RUVFaVDhw7pueee05dffqmtW7f6bd2op0v9jSc0DO6+pXnq1Cnz61//2rRu3drYbDbzw6eL0+k0f/rTn0zv3r1NeHi4+clPfmJ69OhhHnzwQXPw4MHa7eLj483QoUPdZr711lu1+3fs2NE89thjZtOmTUaS2bJli0frkJtvR+7bt88MGzbMtGrVyoSFhZnevXublStXumxT8y3N1157zWX88OHDRlKd7d2Jj493+Vb6Dy8/vB/d0Xm+7X7w4EFz3333mS5duhi73W46d+5sRowYYT799NOLrgfApUUdPedS19Hhw4ebmJgYExoaajp06GDGjBljjhw5ctG1wDo2Y4yxps0FAABAU8c5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OXPmmCuuuCIgmVY1nxkZGSY+Pt588cUXAZm/oqLCHDx40OzevdtMnTrVtG3b1nz66ad+zSgsLDTt27c3+fn5tWOBKpo/9O2335ro6GjzzDPP+H3u0NBQk5SU5DI2YcIEc8MNN/g9q0ZKSoq57bbbAjL32rVrTadOnczatWvNJ598YlavXm3atGljVq1a5fesf//73+amm24ykkxISIi57rrrzL333mt69uzp9yx47lLUUWOsqaXU0foJVC2ljvquIdXRJtt8VlRUmJCQELNhwwaX8YkTJ5qbbropIJlWFMyHHnrIdOrUyRw6dCigOT80cOBA88ADD/h1zo0bN9b+A6m5SDI2m82EhISYyspKv+b90KBBg+p8hs0fOnfubMaNG+cylp2dbWJjY/2eZYwxR44cMc2aNTNvvPFGQObv1KmTWbRokcvY73//+4A2Hd9++605fvy4McaYu+++26SmpgYsCxd3KeqoMYGvpdRR/whELaWO1l9DqKNN9jOfYWFhSkxMrP0GWw2Hw6Hk5ORLtCrfGWP00EMPacOGDfr73/+uhIQEr/ZftWqVbDabjhw5Ujv26quvauHChR5lV1RUeLniCxs4cKD27dun/Px8zZ07V4888oj69Omje++9V/n5+QoJCZEk2Ww2ZWVl+S23oqJCBQUFiomJueB2ZWVlmjJlilJSUtSuXbsLrmPMmDGy2WwqLCzU8uXLa0/Z0aNHD3322WeKj4932f7Pf/6zevToIbvdroSEBM2aNUtOp9Pr27Jy5Uq1b99eQ4cO9XpfT5SXl6tZM9cSEhISEpBThNRo2bKlYmJi9PXXX+u9997T8OHDA5aFi6OOuqKO/n+e1NJA1dGFCxfqzjvvVEJCgmw2m/r37+/z7aCOBojl7W4Dsm7dOhMaGmqWL19u9u/fbyZNmmRatmxpjhw54reMsrIyk5eXZ/Ly8owks2DBApOXl2eOHj3qtwxjjPnv//5v06pVK/P++++boqKi2kt5eblH+xcXF5tdu3aZ77//vnZs6NChJj4+3mW7adOmmW3btpnDhw+bTz75xEyfPt00a9bMbN682Z83x0XNOtwdLtq1a1e9Dos98sgj5v333zeHDh0yH374obntttvMZZdddtHnwOHDh02rVq3MTTfdZNLS0owkM3PmTLfbjh492rRo0cIsX77chISEmAcffND85S9/MfPmzTMRERFmzZo1tdvOmTPH2Gw2M23aNLNlyxbz9NNPm7CwMPO73/3Oq9tVVVVlOnfubB5//HGv9vPG6NGjTceOHc3bb79tDh8+bDZs2GDatm1rpkyZ4vesd99912zatMkcOnTIbN682fTu3dtcf/315uzZs37PgnesqKPGWFNLqaO+86WWBqqOXnHFFebaa681Y8eONe3atTM333yzT7eJOho4Tbr5NMaYxYsXm/j4eBMWFmauvfZav59SY8uWLUZSncvo0aP9muMuQ5JZuXKlz3O6K5pjx46tvb/atWtnBg4c6HXB9LSQ/3gdgfis0ogRI0xMTIwJDQ01sbGx5s477/Toc1fV1dW1p9z4z3/+c9Gi2bJlS2OMMW+99Zbp1auXsdvtpkePHuaFF16o3e7kyZMmPDy8zqG3uXPnGpvN5tXnwd577z0jyRw4cMDjfbxVWlpqHn74YdO5c2cTHh5uunbtambMmGEqKir8npWTk2O6du1qwsLCTIcOHcz48ePNN9984/cc+CbQddQYa2opddR3vtTSQNRRY841jTWuuuoqn5tP6mjgNPnmE+esXLnSSDKHDx82xpz7ULq7IlyjoqKi9nMpYWFhpm3btmbMmDGmuLjYZd74+HgzdOhQ8/rrr5trrrnG2O322leRixYtMv369TPt2rUzERERplevXuapp55yeRV2sXW4K1b79u0zt99+u2ndurWx2+2md+/edT68XfMf2auvvmqmT59uYmJizGWXXWYGDhxo/vWvf3l133lTNC9kzZo1RpLZtWuXy/jx48eNJDN37lyv1gXAWtTRS19Hf6w+zScCp7l/Dt4j2GRnZ+uBBx7Q559/ro0bN7r8rbq6WsOHD9f27ds1ZcoUJScn6+jRo5o5c6b69++vPXv2qEWLFrXbf/TRRyooKKj9CbGWLVtKkj7//HONHDlSCQkJCgsL08cff6y5c+fqX//6l1asWHHRdbhz4MABJScnq3379nruuecUFRWlNWvWaMyYMfrqq680ZcoUl+2nT5+uvn37atmyZSotLdXjjz+uYcOGqaCgoPbzUP7w3XffqUOHDvrPf/6jmJgY3XHHHZo9e7bL+QP/+c9/SpJ+/vOfu+wbExOjtm3b1v4dQONAHbW+jqKRuNTdLxqGH79iN8b94SJjzp0aQpJ5/fXXXcZ3795tJJns7Ozasfj4eBMSEnLRwxZVVVXG6XSa1atXm5CQEHPq1KmLrsOYuq/Y77nnHmO3201hYaHLdkOGDDERERG1hxhqXrH/+Ft+f/nLX9y++3ghF3vFvmDBArNgwQKzefNms3nzZjNjxgwTERFhevToYcrKymq3+93vfmfsdrvbObp3725SUlI8XhMA61FHz7mUdfTHeOezYWqy33aH795++221bt1aw4YNU2VlZe3lmmuuUYcOHfT++++7bH/11Vere/fudebJy8vT7bffrqioKIWEhCg0NFSjRo1SVVVV7a89eOvvf/+7Bg4cqLi4OJfxMWPGqLy8XLt27XIZv/322+usVZKOHj3qU747kydP1uTJkzV48GANHjxYc+bM0erVq/Wvf/2rzi9zXOjXM/z9yxoALh3qqHe8qaNo+DjsDq999dVX+uabbxQWFub27ydPnnS57u5UG4WFherXr5+uuOIKPfvss+rSpYvCw8P1j3/8Q+PHj9d3333n09pKSkrc5sXGxtb+/YeioqJcrtvtdknyOd9Tv/rVr9SyZUt9+OGHLmv5/vvvVV5eroiICJftT506pcTExICuCYB1qKP1566OonGg+YTX2rZtq6ioKL377rtu/37ZZZe5XHf3jt0bb7yhM2fOaMOGDS7nZ8vPz6/X2qKiolRUVFRn/Pjx45LOrb2hMMa4nN+t5rOe+/bt0y9/+cva8RMnTujkyZPq1auX5WsEEBjUUf/4cR1F40DzifOy2+1uX7nedtttWrdunaqqqlyaJG/UFNKaV8jSuSLi7vDJ+dbhzsCBA7Vx40YdP3689lW6JK1evVoRERG64YYbfFqvv61fv17l5eUu6/lf/+t/KTw8XKtWrXK5X2tOXH3HHXdcgpUCqA/qaOC4q6NoHGg+cV4///nPtWHDBi1ZskSJiYlq1qyZ+vTpo3vuuUevvPKKUlNT9fDDD+v6669XaGiovvzyS23ZskXDhw/Xr371qwvOPXjwYIWFhem//uu/NGXKFH3//fdasmSJvv76a4/X4c7MmTP19ttva8CAAXryySfVpk0bvfLKK3rnnXf09NNPq1WrVn65byRp06ZNOnPmjMrKyiRJ+/fv1/r16yVJqampioiI0NGjRzVy5Ejdc889+tnPfiabzaatW7dq4cKFuuqqq5SWllY7X5s2bfTEE0/of/7nf9SmTRulpKRo9+7dysrKUlpamq688kq/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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "with figsize(y=5.5):\n", " for i in range (4):\n", " random.seed(3)\n", " plt.subplot(221+i)\n", " train_filter(148+i, kernel=[.1, .8, .1], \n", " sensor_accuracy=.8,\n", " move_distance=4, do_print=False)\n", " plt.title (f'iteration {148 + i}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that there was a problem on iteration 149 as the confidence degrades. But within a few iterations the filter is able to correct itself and regain confidence in the estimated position." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Bayes Theorem and the Total Probability Theorem" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We developed the math in this chapter merely by reasoning about the information we have at each moment. In the process we discovered [*Bayes' Theorem*](https://en.wikipedia.org/wiki/Bayes%27_theorem) and the [*Total Probability Theorem*](https://en.wikipedia.org/wiki/Law_of_total_probability).\n", "\n", "Bayes theorem tells us how to compute the probability of an event given previous information. \n", "\n", "We implemented the `update()` function with this probability calculation:\n", "\n", "$$ \\mathtt{posterior} = \\frac{\\mathtt{likelihood}\\times \\mathtt{prior}}{\\mathtt{normalization\\, factor}}$$ \n", "\n", "We haven't developed the mathematics to discuss Bayes yet, but this is Bayes' theorem. Every filter in this book is an expression of Bayes' theorem. In the next chapter we will develop the mathematics, but in many ways that obscures the simple idea expressed in this equation:\n", "\n", "$$ updated\\,knowledge = \\big\\|likelihood\\,of\\,new\\,knowledge\\times prior\\, knowledge \\big\\|$$\n", "\n", "where $\\| \\cdot\\|$ expresses normalizing the term.\n", "\n", "We came to this with simple reasoning about a dog walking down a hallway. Yet, as we will see the same equation applies to a universe of filtering problems. We will use this equation in every subsequent chapter.\n", "\n", "Likewise, the `predict()` step computes the total probability of multiple possible events. This is known as the *Total Probability Theorem* in statistics, and we will also cover this in the next chapter after developing some supporting math.\n", "\n", "For now I need you to understand that Bayes' theorem is a formula to incorporate new information into existing information." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Summary\n", "\n", "The code is very short, but the result is impressive! We have implemented a form of a Bayesian filter. We have learned how to start with no information and derive information from noisy sensors. Even though the sensors in this chapter are very noisy (most sensors are more than 80% accurate, for example) we quickly converge on the most likely position for our dog. We have learned how the predict step always degrades our knowledge, but the addition of another measurement, even when it might have noise in it, improves our knowledge, allowing us to converge on the most likely result.\n", "\n", "This book is mostly about the Kalman filter. The math it uses is different, but the logic is exactly the same as used in this chapter. It uses Bayesian reasoning to form estimates from a combination of measurements and process models. \n", "\n", "**If you can understand this chapter you will be able to understand and implement Kalman filters.** I cannot stress this enough. If anything is murky, go back and reread this chapter and play with the code. The rest of this book will build on the algorithms that we use here. If you don't understand why this filter works you will have little success with the rest of the material. However, if you grasp the fundamental insight - multiplying probabilities when we measure, and shifting probabilities when we update leads to a converging solution - then after learning a bit of math you are ready to implement a Kalman filter." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n", "\n", " * [1] D. Fox, W. Burgard, and S. Thrun. \"Monte carlo localization: Efficient position estimation for mobile robots.\" In *Journal of Artifical Intelligence Research*, 1999.\n", " \n", " http://www.cs.cmu.edu/afs/cs/project/jair/pub/volume11/fox99a-html/jair-localize.html\n", "\n", "\n", " * [2] Dieter Fox, et. al. \"Bayesian Filters for Location Estimation\". In *IEEE Pervasive Computing*, September 2003.\n", " \n", " http://swarmlab.unimaas.nl/wp-content/uploads/2012/07/fox2003bayesian.pdf\n", " \n", " \n", " * [3] Sebastian Thrun. \"Artificial Intelligence for Robotics\".\n", " \n", " https://www.udacity.com/course/cs373\n", " \n", " \n", " * [4] Khan Acadamy. \"Introduction to the Convolution\"\n", " \n", " https://www.khanacademy.org/math/differential-equations/laplace-transform/convolution-integral/v/introduction-to-the-convolution\n", " \n", " \n", "* [5] Wikipedia. \"Convolution\"\n", "\n", " http://en.wikipedia.org/wiki/Convolution\n", "\n", "* [6] Wikipedia. \"Law of total probability\"\n", "\n", " http://en.wikipedia.org/wiki/Law_of_total_probability\n", " \n", "* [7] Wikipedia. \"Time Evolution\"\n", "\n", " https://en.wikipedia.org/wiki/Time_evolution\n", " \n", "* [8] We need to rethink how we teach statistics from the ground up\n", " \n", " http://www.statslife.org.uk/opinion/2405-we-need-to-rethink-how-we-teach-statistics-from-the-ground-up" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.7" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "1ea315f115ff43d8aedcd574bbeed410": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntSliderModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "IntSliderView", "continuous_update": true, "description": "step", "description_tooltip": null, "disabled": false, "layout": "IPY_MODEL_51963e73dba4487f95d2e6c2b9a9c71a", "max": 100, "min": 0, "orientation": "horizontal", "readout": true, "readout_format": "d", "step": 1, "style": "IPY_MODEL_bf7a2628623c422bbdc7983f76a57c75", "value": 1 } }, "24a3f8a7d3c44508a9d0ae15bb97df92": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "24f0f28eff1947719418be9532a5054c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "376e66cbf1e74103a1a93d5ec7611004": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_24f0f28eff1947719418be9532a5054c", "msg_id": "", "outputs": [] } }, "4825caa46e18450f9afcba67c27cbeba": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntSliderModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "IntSliderView", "continuous_update": true, "description": "time_step", "description_tooltip": null, "disabled": false, "layout": "IPY_MODEL_6409d65c66d5483ab1dff92c7199efb0", "max": 19, "min": 0, "orientation": "horizontal", "readout": true, "readout_format": "d", "step": 1, "style": "IPY_MODEL_c448c06a3e904b0d811dd099733429bc", "value": 0 } }, "48c69b49621547b9972c8eb7cddfa10e": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_4fbf3d96470d4f168fdd3af62ae85189", "msg_id": "", "outputs": [] } }, "4fbf3d96470d4f168fdd3af62ae85189": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "51963e73dba4487f95d2e6c2b9a9c71a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "557aede106aa460da09898120cf2c111": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6127afe680be4cc5bd3e14626d4493f0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "VBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_7f99b7560aa04802a5b1b03b5e4ad81e", "IPY_MODEL_48c69b49621547b9972c8eb7cddfa10e" ], "layout": "IPY_MODEL_557aede106aa460da09898120cf2c111" } }, "6409d65c66d5483ab1dff92c7199efb0": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7e810cc52ae044aba08c2672377d716c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7f99b7560aa04802a5b1b03b5e4ad81e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntSliderModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "IntSliderView", "continuous_update": true, "description": "step", "description_tooltip": null, "disabled": false, "layout": "IPY_MODEL_7e810cc52ae044aba08c2672377d716c", "max": 12, "min": 0, "orientation": "horizontal", "readout": true, "readout_format": "d", "step": 1, "style": "IPY_MODEL_d4f45abe59a24e19a6168202f72b914e", "value": 12 } }, "9260e86291ea4ceabb18583e1b480bd9": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "964107123dbf442593d2a43411c04268": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b51e90e175e14117b4c0727749c1047d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "bf7a2628623c422bbdc7983f76a57c75": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "SliderStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "", "handle_color": null } }, "c383bd000ae248f0adeec4825dc0923b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "SliderStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "", "handle_color": null } }, "c448c06a3e904b0d811dd099733429bc": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "SliderStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "", "handle_color": null } }, "d13d51f518a64cbfb548a3ac5fe0412d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "VBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_e99d98efa98146f7ae449672d8f4da71", "IPY_MODEL_e67fb12631604743a7b242a173e2250c" ], "layout": "IPY_MODEL_24a3f8a7d3c44508a9d0ae15bb97df92" } }, "d4f45abe59a24e19a6168202f72b914e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "SliderStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "", "handle_color": null } }, "e67fb12631604743a7b242a173e2250c": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_9260e86291ea4ceabb18583e1b480bd9", "msg_id": "", "outputs": [] } }, "e99d98efa98146f7ae449672d8f4da71": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntSliderModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "IntSliderView", "continuous_update": true, "description": "step", "description_tooltip": null, "disabled": false, "layout": "IPY_MODEL_fb2dce3f803243b3a6a4619bc0099cc2", "max": 100, "min": 0, "orientation": "horizontal", "readout": true, "readout_format": "d", "step": 1, "style": "IPY_MODEL_c383bd000ae248f0adeec4825dc0923b", "value": 1 } }, "ecba7b7412dc454d9c606867bb343235": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "VBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_4825caa46e18450f9afcba67c27cbeba", "IPY_MODEL_ecf2533746d74ee18336f04b86e21736" ], "layout": "IPY_MODEL_fa98c8f5d70f48af9968b14005fa2274" } }, "ecf2533746d74ee18336f04b86e21736": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_964107123dbf442593d2a43411c04268", "msg_id": "", "outputs": [] } }, "fa98c8f5d70f48af9968b14005fa2274": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "fb2dce3f803243b3a6a4619bc0099cc2": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "fd3a9bcbc55f432dad319c4248e1f8ef": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "VBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_1ea315f115ff43d8aedcd574bbeed410", "IPY_MODEL_376e66cbf1e74103a1a93d5ec7611004" ], "layout": "IPY_MODEL_b51e90e175e14117b4c0727749c1047d" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }