Reformat, and changes to work with IPython 6.0
After a new Anaconda install I was getting a lot of minor errors in the notebooks. I've fixed all of those. Along the ways I altered the format of the PDF output to exclude the In[] Out[] tags so the code is indented less. I also altered the font size of the notebooks to better match fonts in other pages on chrome. FilterPy was updated to 1.1.0, and this check in requires that release at the minimum.
This commit is contained in:
parent
5ab83047d9
commit
850c7fc0dd
328
00-Preface.ipynb
328
00-Preface.ipynb
@ -24,283 +24,8 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Lora');\n",
|
||||
"\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Open+Sans');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Vollkorn');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Karla');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Poppins');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arimo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Roboto');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Lato');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Domine');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Chivo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Cardo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arvo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Crimson+Text');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Ubuntu');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Fontin');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Raleway');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Merriweather');\n",
|
||||
"\n",
|
||||
"\n",
|
||||
".CodeMirror pre {\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
"}\n",
|
||||
" div.cell{\n",
|
||||
" //width: 950px;\n",
|
||||
" margin-left: 0% !important;\n",
|
||||
" margin-right: auto;\n",
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Lora';\n",
|
||||
" //font-family: 'Open Sans';\n",
|
||||
" //font-family: 'Karla',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Roboto',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Lato',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Domine',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Chivo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Cardo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Arvo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Poppins',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Ubuntu',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Fontin',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Raleway',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Merriweather',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Crimson Text', verdana,arial,sans-serif;\n",
|
||||
" //font-family: verdana,arial,sans-serif;\n",
|
||||
" //font-family: arial,sans-serif;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 130%;\n",
|
||||
" text-align: justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" div.text_cell code {\n",
|
||||
" background: transparent;\n",
|
||||
" color: #000000;\n",
|
||||
" font-weight: 400;\n",
|
||||
" font-size: 12pt;\n",
|
||||
" //font-style: bold;\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
" }\n",
|
||||
" h1 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
"\t}\n",
|
||||
"\n",
|
||||
" div.input_area {\n",
|
||||
" background: #F6F6F9;\n",
|
||||
" border: 1px solid #586e75;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .text_cell_render h1 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 30pt;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#c76c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 1em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" text-align: left;\n",
|
||||
" }\n",
|
||||
" h2 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" text-align: left;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h2 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 16pt;\n",
|
||||
" font-style: italic;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#c76c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 1.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" text-align: left;\n",
|
||||
" }\n",
|
||||
" h3 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h3 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 14pt;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#d77c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 2em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" text-align: left;\n",
|
||||
" }\n",
|
||||
" h4 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h4 {\n",
|
||||
" font-weight: 100;\n",
|
||||
" font-size: 14pt;\n",
|
||||
" color:#d77c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" h5 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .text_cell_render h5 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-style: normal;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" font-size: 16pt;\n",
|
||||
" margin-bottom: 0em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_text.output_pyout {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_stream.output_stdout.output_text {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" }\n",
|
||||
" div.output_wrapper{\n",
|
||||
" margin-top:0.2em;\n",
|
||||
" margin-bottom:0.2em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
" code{\n",
|
||||
" font-size: 6pt;\n",
|
||||
"\n",
|
||||
" }\n",
|
||||
" .rendered_html code{\n",
|
||||
" background-color: transparent;\n",
|
||||
" }\n",
|
||||
" ul{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" }\n",
|
||||
" ul li li{\n",
|
||||
" padding-left: 0.2em;\n",
|
||||
" margin-bottom: 0.2em;\n",
|
||||
" margin-top: 0.2em;\n",
|
||||
" }\n",
|
||||
" ol{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ol li{\n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.2em;\n",
|
||||
" }\n",
|
||||
" a:link{\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:visited{\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:hover{\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:focus{\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:active{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" .rendered_html :link {\n",
|
||||
" text-decoration: underline;\n",
|
||||
" }\n",
|
||||
" .rendered_html :hover {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :visited {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :focus {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :active {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .warning{\n",
|
||||
" color: rgb( 240, 20, 20 )\n",
|
||||
" }\n",
|
||||
" hr {\n",
|
||||
" color: #f3f3f3;\n",
|
||||
" background-color: #f3f3f3;\n",
|
||||
" height: 1px;\n",
|
||||
" }\n",
|
||||
" blockquote{\n",
|
||||
" display:block;\n",
|
||||
" background: #fcfcfc;\n",
|
||||
" border-left: 5px solid #c76c0c;\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" width:680px;\n",
|
||||
" padding: 10px 10px 10px 10px;\n",
|
||||
" text-align:justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" blockquote p {\n",
|
||||
" margin-bottom: 0;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 100%;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<script>\n",
|
||||
" MathJax.Hub.Config({\n",
|
||||
" TeX: {\n",
|
||||
" extensions: [\"AMSmath.js\"],\n",
|
||||
" equationNumbers: { autoNumber: \"AMS\", useLabelIds: true}\n",
|
||||
" },\n",
|
||||
" tex2jax: {\n",
|
||||
" inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
|
||||
" displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
|
||||
" },\n",
|
||||
" displayAlign: 'center', // Change this to 'center' to center equations.\n",
|
||||
" \"HTML-CSS\": {\n",
|
||||
" scale:95,\n",
|
||||
" availableFonts: [],\n",
|
||||
" preferredFont:null,\n",
|
||||
" webFont: \"TeX\",\n",
|
||||
" styles: {'.MathJax_Display': {\"margin\": 4}}\n",
|
||||
" }\n",
|
||||
" });\n",
|
||||
"</script>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#format the book\n",
|
||||
"from book_format import load_style\n",
|
||||
@ -425,28 +150,22 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Downloading the book"
|
||||
"## Downloading and Running the Book"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This book is interactive and I recommend using it in that form. If you install IPython on your computer and then clone this book you will be able to run all of the code in the book inside your browser. You can perform experiments, see how filters react to different data, see how different filters react to the same data, and so on. I find this sort of immediate feedback vital. You do not have to wonder \"what happens if\". Try it and see!\n",
|
||||
"However, this book is intended to be interactive and I recommend using it in that form. It's a little more effort to set up, but worth it. If you install IPython and some supporting libraries on your computer and then clone this book you will be able to run all of the code in the book yourself. You can perform experiments, see how filters react to different data, see how different filters react to the same data, and so on. I find this sort of immediate feedback both vital and invigorating. You do not have to wonder \"what happens if\". Try it and see!\n",
|
||||
"\n",
|
||||
"The GitHub pages for this project are at\n",
|
||||
"Instructions for installation can be found in the Installation appendix, found [here](http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/Appendix-A-Installation.ipynb).\n",
|
||||
"\n",
|
||||
" https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python \n",
|
||||
"\n",
|
||||
"You can clone it to your hard drive with the command \n",
|
||||
"\n",
|
||||
"`git clone --depth=1 https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python.git`\n",
|
||||
" \n",
|
||||
"This will create a directory named `Kalman-and-Bayesian-Filters-in-Python`. The `depth` parameter just gets you the latest version. Unless you need to see my entire commit history this is a lot faster and saves space. Navigate to the directory, and run Jupyter Notebook with the command\n",
|
||||
"Once the software is installed you can navigate to the installation directory and run Juptyer notebook with the command line instruction\n",
|
||||
"\n",
|
||||
" jupyter notebook\n",
|
||||
"\n",
|
||||
"This will open a browser window showing the contents of the base directory. The book is organized into chapters. Each chapter is named *xx*-*name*.ipynb, where *xx* is the chapter number. .ipynb is the Notebook file extension.\n",
|
||||
"This will open a browser window showing the contents of the base directory. The book is organized into chapters. Each chapter is named *xx*-*name*.ipynb, where *xx* is the chapter number. .ipynb is the Notebook file extension. To read Chapter 2, click on the link for chapter 2. This will cause the browser to open that subdirectory. In each subdirectory there will be one or more IPython Notebooks (all notebooks have a .ipynb file extension). The chapter contents are in the notebook with the same name as the chapter name. There are sometimes supporting notebooks for doing things like generating animations that are displayed in the chapter. These are not intended to be read by the end user, but of course if you are curious as to how an animation is made go ahead and take a look.\n",
|
||||
"\n",
|
||||
"Admittedly this is a cumbersome interface to a book. I am following in the footsteps of several other projects that are re-purposing Jupyter Notebook to generate entire books. I feel the slight annoyances have a huge payoff - instead of having to download a separate code base and run it in an IDE while you try to read a book, all of the code and text is in one place. If you want to alter the code, you may do so and immediately see the effects of your change. If you find a bug, you can make a fix, and push it back to my repository so that everyone in the world benefits. And, of course, you will never encounter a problem I face all the time with traditional books - the book and the code are out of sync with each other, and you are left scratching your head as to which source to trust."
|
||||
]
|
||||
@ -455,34 +174,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Installation and Software Requirements"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Installation of the required software is described in detail in the Installation appendix, which you can read online here:\n",
|
||||
"\n",
|
||||
"http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/Appendix_A_Installation.ipynb\n",
|
||||
"\n",
|
||||
"You will need IPython 3.0 or greater, Python 2.7+ or Python 3.4+, NumPy, SciPy, SymPy, and Matplotlib. You will also need my open source library FilterPy.\n",
|
||||
"\n",
|
||||
"The easiest way to get all of those except for FilterPy is by installing a free Scientific Python distribution, such as the Anaconda distribution https://store.continuum.io/cshop/anaconda/ (the link says \"shop\", but it is free). I am not naming them out of favoritism, I am merely documenting my environment. Should you have trouble running any of the code, perhaps knowing this will help you.\n",
|
||||
"\n",
|
||||
"Once you have Python installed install FilterPy by typing\n",
|
||||
"\n",
|
||||
"```bash\n",
|
||||
"pip install filterpy\n",
|
||||
"```\n",
|
||||
"at the command line."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## My Libraries and Modules"
|
||||
"## Companion Software"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -591,9 +283,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.1"
|
||||
"version": "3.6.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -9,9 +9,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "raw",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\\appendix"
|
||||
]
|
||||
@ -20,15 +18,13 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Installation, Python, NumPy, and FilterPy"
|
||||
"# Installation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -37,24 +33,6 @@
|
||||
"@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Lora');\n",
|
||||
"\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Open+Sans');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Vollkorn');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Karla');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Poppins');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arimo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Roboto');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Lato');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Domine');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Chivo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Cardo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arvo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Crimson+Text');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Ubuntu');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Fontin');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Raleway');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Merriweather');\n",
|
||||
"\n",
|
||||
"\n",
|
||||
".CodeMirror pre {\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
"}\n",
|
||||
@ -65,24 +43,8 @@
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Lora';\n",
|
||||
" //font-family: 'Open Sans';\n",
|
||||
" //font-family: 'Karla',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Roboto',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Lato',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Domine',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Chivo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Cardo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Arvo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Poppins',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Ubuntu',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Fontin',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Raleway',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Merriweather',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Crimson Text', verdana,arial,sans-serif;\n",
|
||||
" //font-family: verdana,arial,sans-serif;\n",
|
||||
" //font-family: arial,sans-serif;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 130%;\n",
|
||||
" font-size: 100%;\n",
|
||||
" text-align: justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
@ -90,8 +52,7 @@
|
||||
" background: transparent;\n",
|
||||
" color: #000000;\n",
|
||||
" font-weight: 400;\n",
|
||||
" font-size: 12pt;\n",
|
||||
" //font-style: bold;\n",
|
||||
" font-size: 11pt;\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
" }\n",
|
||||
" h1 {\n",
|
||||
@ -172,13 +133,13 @@
|
||||
" }\n",
|
||||
" div.output_subarea.output_text.output_pyout {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_stream.output_stdout.output_text {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_wrapper{\n",
|
||||
" margin-top:0.2em;\n",
|
||||
@ -335,11 +296,23 @@
|
||||
"source": [
|
||||
"This book requires IPython, Jupyter, NumPy, SciPy, SymPy, and Matplotlib. The SciPy stack of NumPy, SciPy, and Matplotlib depends on third party Fortran and C code, and is not trivial to install from source code. The SciPy website strongly urges using a pre-built installation, and I concur with this advice.\n",
|
||||
"\n",
|
||||
"I use the Anaconda distribution from Continuum Analytics. This is an excellent distribution that combines all of the packages listed above, plus many others. Installation is very straightforward, and it can be done alongside other Python installations you might already have on your machine. It is free to use. You may download it from here: http://continuum.io/downloads I strongly recommend using the latest Python 3 version that they provide.\n",
|
||||
"Jupyter notebook is the software that allows you to run Python inside of the browser - the book is a collection of Jupyter notebooks. IPython provides the infrastructure for Jupyter and data visualization. NumPy and Scipy are packages which provide the linear algebra implementation that the filters use. Sympy performs symbolic math - I use it to find derivatives of algebraic equations. Finally, Matplotlib provides plotting capability. \n",
|
||||
"\n",
|
||||
"There are other choices for installing the SciPy stack. You can find instructions here: http://scipy.org/install.html\n",
|
||||
"I use the Anaconda distribution from Continuum Analytics. This is an excellent distribution that combines all of the packages listed above, plus many others. IPython recommends this package to install Ipython. Installation is very straightforward, and it can be done alongside other Python installations you might already have on your machine. It is free to use. You may download it from here: http://continuum.io/downloads I strongly recommend using the latest Python 3 version that they provide. For now I support Python 2.7, but perhaps not much longer. \n",
|
||||
"\n",
|
||||
"Many Linux distributions come with these packages preinstalled. However, they are often somewhat dated and they will need to be updated as the book depends on recent versions of all. Updating a specific Linux installation is beyond the scope of this book. An advantage of the Anaconda distribution is that it does not modify your local Python installation, so you can install it and not break your linux distribution. "
|
||||
"There are other choices for installing the SciPy stack. You can find instructions here: http://scipy.org/install.html It can be very cumbersome, and I do not support it or provide any instructions on how to do it.\n",
|
||||
"\n",
|
||||
"Many Linux distributions come with these packages pre-installed. However, they are often somewhat dated and they will need to be updated as the book depends on recent versions of all. Updating a specific Linux installation is beyond the scope of this book. An advantage of the Anaconda distribution is that it does not modify your local Python installation, so you can install it and not break your linux distribution. Some people have been tripped up by this. They install Anaconda, but the installed Python remains the default version and then the book's software doesn't run correctly.\n",
|
||||
"\n",
|
||||
"I do not run regression tests on old versions of these libraries. In fact, I know the code will not run on older versions (say, from 2014-2015). I do not want to spend my life doing tech support for a book, thus I put the burden on you to install a recent version of Python and the SciPy stack. \n",
|
||||
"\n",
|
||||
"You will need Python 2.7 or later installed. Almost all of my work is done in Python 3.6, but I periodically test on 2.7. I do not promise any specific check in will work in 2.7 however. I use Python's `from __future__ import ...` statement to help with compatibility. For example, all prints need to use parenthesis. If you try to add, say, `print x` into the book your script will fail; you must write `print(x)` as in Python 3.X.\n",
|
||||
"\n",
|
||||
"Please submit a bug report at the book's [github repository](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python) if you have installed the latest Anaconda and something does not work - I will continue to ensure the book will run with the latest Anaconda release. I'm rather indifferent if the book will not run on an older installation. I'm sorry, but I just don't have time to provide support for everyone's different setups. Packages like `jupyter notebook` are evolving rapidly, and I cannot keep up with all the changes *and* remain backwards compatible as well. \n",
|
||||
"\n",
|
||||
"If you need older versions of the software for other projects, note that Anaconda allows you to install multiple versions side-by-side. Documentation for this is here:\n",
|
||||
"\n",
|
||||
"https://conda.io/docs/user-guide/tasks/manage-python.html\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -353,9 +326,7 @@
|
||||
" pip install filterpy\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"FilterPy is written by me, and the latest development version is always available at https://github.com/rlabbe/filterpy.\n",
|
||||
" \n",
|
||||
" "
|
||||
"FilterPy is written by me, and the latest development version is always available at https://github.com/rlabbe/filterpy."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -371,8 +342,10 @@
|
||||
"source": [
|
||||
"The book is stored in a github repository. From the command line type the following:\n",
|
||||
"\n",
|
||||
" git clone https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python.git\n",
|
||||
" \n",
|
||||
" git clone --depth=1 https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python.git\n",
|
||||
"\n",
|
||||
"This will create a directory named Kalman-and-Bayesian-Filters-in-Python. The `depth` parameter just gets you the latest version. Unless you need to see my entire commit history this is a lot faster and saves space.\n",
|
||||
"\n",
|
||||
"If you do not have git installed, browse to https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python where you can download the book via your browser.\n",
|
||||
"\n",
|
||||
"Now, from the command prompt change to the directory that was just created, and then run Jupyter notebook:\n",
|
||||
@ -387,6 +360,28 @@
|
||||
"http://jupyter-notebook-beginner-guide.readthedocs.org/en/latest/execute.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Companion Software"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Code that is specific to the book is stored with the book in the subdirectory *./kf_book*. This code is in a state of flux; I do not wish to document it here yet. I do mention in the book when I use code from this directory, so it should not be a mystery.\n",
|
||||
"\n",
|
||||
"In the *kf_book* subdirectory there are Python files with a name like *xxx*_internal.py. I use these to store functions that are useful for a specific chapter. This allows me to hide away Python code that is not particularly interesting to read - I may be generating a plot or chart, and I want you to focus on the contents of the chart, not the mechanics of how I generate that chart with Python. If you are curious as to the mechanics of that, just go and browse the source.\n",
|
||||
"\n",
|
||||
"Some chapters introduce functions that are useful for the rest of the book. Those functions are initially defined within the Notebook itself, but the code is also stored in a Python file that is imported if needed in later chapters. I do document when I do this where the function is first defined, but this is still a work in progress. I try to avoid this because then I always face the issue of code in the directory becoming out of sync with the code in the book. However, IPython Notebook does not give us a way to refer to code cells in other notebooks, so this is the only mechanism I know of to share functionality across notebooks.\n",
|
||||
"\n",
|
||||
"There is an undocumented directory called **experiments**. This is where I write and test code prior to putting it in the book. There is some interesting stuff in there, and feel free to look at it. As the book evolves I plan to create examples and projects, and a lot of this material will end up there. Small experiments will eventually just be deleted. If you are just interested in reading the book you can safely ignore this directory. \n",
|
||||
"\n",
|
||||
"The subdirectory *./kf_book* contains a css file containing the style guide for the book. The default look and feel of IPython Notebook is rather plain. Work is being done on this. I have followed the examples set by books such as [Probabilistic Programming and Bayesian Methods for Hackers](http://nbviewer.ipython.org/github/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/blob/master/Chapter1_Introduction/Chapter1.ipynb). I have also been very influenced by Professor Lorena Barba's fantastic work, [available here](https://github.com/barbagroup/CFDPython). I owe all of my look and feel to the work of these projects. \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@ -404,9 +399,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@ -446,9 +439,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -482,9 +473,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -516,9 +505,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -549,9 +536,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -582,9 +567,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
@ -611,9 +594,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -648,9 +629,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -697,9 +676,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -739,6 +716,24 @@
|
||||
"\n",
|
||||
"sympy.integrate(F_k*Q*F_k.T,(dt, 0, dt))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Various Links"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"https://ipython.org/\n",
|
||||
"\n",
|
||||
"https://jupyter.org/\n",
|
||||
"\n",
|
||||
"https://www.scipy.org/"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
@ -758,9 +753,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.1"
|
||||
"version": "3.6.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
|
@ -10,9 +10,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -21,52 +19,18 @@
|
||||
"@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Lora');\n",
|
||||
"\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Open+Sans');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Vollkorn');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Karla');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Poppins');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arimo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Roboto');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Lato');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Domine');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Chivo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Cardo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arvo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Crimson+Text');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Ubuntu');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Fontin');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Raleway');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Merriweather');\n",
|
||||
"\n",
|
||||
"\n",
|
||||
".CodeMirror pre {\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
"}\n",
|
||||
" div.cell{\n",
|
||||
" width: 850px;\n",
|
||||
" //width: 950px;\n",
|
||||
" margin-left: 0% !important;\n",
|
||||
" margin-right: auto;\n",
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Lora';\n",
|
||||
" //font-family: 'Open Sans';\n",
|
||||
" //font-family: 'Karla',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Roboto',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Lato',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Domine',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Chivo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Cardo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Arvo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Poppins',verdana,arial,sans-serif; \n",
|
||||
" //font-family: 'Ubuntu',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Fontin',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Raleway',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Merriweather',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Crimson Text', verdana,arial,sans-serif;\n",
|
||||
" //font-family: verdana,arial,sans-serif;\n",
|
||||
" //font-family: arial,sans-serif;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 130%;\n",
|
||||
" font-size: 100%;\n",
|
||||
" text-align: justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
@ -74,17 +38,16 @@
|
||||
" background: transparent;\n",
|
||||
" color: #000000;\n",
|
||||
" font-weight: 400;\n",
|
||||
" font-size: 12pt;\n",
|
||||
" //font-style: bold;\n",
|
||||
" font-size: 11pt;\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
" }\n",
|
||||
" h1 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
"\t}\n",
|
||||
"\t\n",
|
||||
"\n",
|
||||
" div.input_area {\n",
|
||||
" background: #F6F6F9;\n",
|
||||
" border: 1px solid #586e75; \n",
|
||||
" border: 1px solid #586e75;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .text_cell_render h1 {\n",
|
||||
@ -97,7 +60,7 @@
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" text-align: left;\n",
|
||||
" } \n",
|
||||
" }\n",
|
||||
" h2 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" text-align: left;\n",
|
||||
@ -113,7 +76,7 @@
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" text-align: left;\n",
|
||||
" } \n",
|
||||
" }\n",
|
||||
" h3 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
@ -156,13 +119,13 @@
|
||||
" }\n",
|
||||
" div.output_subarea.output_text.output_pyout {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_stream.output_stdout.output_text {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_wrapper{\n",
|
||||
" margin-top:0.2em;\n",
|
||||
@ -180,42 +143,38 @@
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" }\n",
|
||||
" ul li li{\n",
|
||||
" padding-left: 0.2em; \n",
|
||||
" margin-bottom: 0.2em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" padding-left: 0.2em;\n",
|
||||
" margin-bottom: 0.2em;\n",
|
||||
" margin-top: 0.2em;\n",
|
||||
" }\n",
|
||||
" ol{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ol li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.2em;\n",
|
||||
" }\n",
|
||||
" a:link{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:visited{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:hover{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:focus{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:active{\n",
|
||||
@ -223,10 +182,10 @@
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" .rendered_html :link {\n",
|
||||
" text-decoration: underline; \n",
|
||||
" text-decoration: underline;\n",
|
||||
" }\n",
|
||||
" .rendered_html :hover {\n",
|
||||
" text-decoration: none; \n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :visited {\n",
|
||||
" text-decoration: none;\n",
|
||||
@ -239,7 +198,7 @@
|
||||
" }\n",
|
||||
" .warning{\n",
|
||||
" color: rgb( 240, 20, 20 )\n",
|
||||
" } \n",
|
||||
" }\n",
|
||||
" hr {\n",
|
||||
" color: #f3f3f3;\n",
|
||||
" background-color: #f3f3f3;\n",
|
||||
@ -353,8 +312,8 @@
|
||||
"$$\n",
|
||||
"\\begin{aligned}\n",
|
||||
"\\underline{\\hat{x}}_k(-) &= \\Phi_{k-1} \\underline{\\hat{x}}_{k-1}(+) \\\\\n",
|
||||
"\\underline{\\hat{x}}_k(+) &= \\underline{\\hat{x}}_k(-) +K_k[Z_k - H_k\\underline{\\hat{x}}_k(-)] \\\\\n",
|
||||
"K_k &= P_k(-)H_k^\\mathsf{T}[H_kP_k(-)H_k^\\mathsf{T} + R_k]^{-1}\\\\\n",
|
||||
"\\underline{\\hat{x}}_k(+) &= \\underline{\\hat{x}}_k(-) +K_k[Z_k - H_k\\underline{\\hat{x}}_k(-)] \\\\\n",
|
||||
"K_k &= P_k(-)H_k^\\mathsf{T}[H_kP_k(-)H_k^\\mathsf{T} + R_k]^{-1} \\\\\n",
|
||||
"P_k(+) &= \\Phi_{k-1} P_{k-1}(+)\\Phi_{k-1}^\\mathsf{T} + Q_{k-1} \\\\\n",
|
||||
"P_k(-) &= (I-K_kH_k)P_k(-)\n",
|
||||
"\\end{aligned}$$\n",
|
||||
@ -400,9 +359,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.1"
|
||||
"version": "3.6.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -17,9 +17,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
@ -28,24 +26,6 @@
|
||||
"@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Lora');\n",
|
||||
"\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Open+Sans');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Vollkorn');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Karla');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Poppins');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arimo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Roboto');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Lato');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Domine');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Chivo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Cardo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Arvo');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Crimson+Text');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Ubuntu');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Fontin');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Raleway');\n",
|
||||
"//@import url('http://fonts.googleapis.com/css?family=Merriweather');\n",
|
||||
"\n",
|
||||
"\n",
|
||||
".CodeMirror pre {\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
"}\n",
|
||||
@ -56,24 +36,8 @@
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Lora';\n",
|
||||
" //font-family: 'Open Sans';\n",
|
||||
" //font-family: 'Karla',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Roboto',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Lato',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Domine',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Chivo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Cardo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Arvo',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Poppins',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Ubuntu',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Fontin',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Raleway',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Merriweather',verdana,arial,sans-serif;\n",
|
||||
" //font-family: 'Crimson Text', verdana,arial,sans-serif;\n",
|
||||
" //font-family: verdana,arial,sans-serif;\n",
|
||||
" //font-family: arial,sans-serif;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 130%;\n",
|
||||
" font-size: 100%;\n",
|
||||
" text-align: justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
@ -81,8 +45,7 @@
|
||||
" background: transparent;\n",
|
||||
" color: #000000;\n",
|
||||
" font-weight: 400;\n",
|
||||
" font-size: 12pt;\n",
|
||||
" //font-style: bold;\n",
|
||||
" font-size: 11pt;\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
" }\n",
|
||||
" h1 {\n",
|
||||
@ -163,13 +126,13 @@
|
||||
" }\n",
|
||||
" div.output_subarea.output_text.output_pyout {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_stream.output_stdout.output_text {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_wrapper{\n",
|
||||
" margin-top:0.2em;\n",
|
||||
@ -351,9 +314,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.1"
|
||||
"version": "3.6.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
|
@ -16,37 +16,42 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Vollkorn');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Arimo');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Fira_sans');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Lora');\n",
|
||||
"\n",
|
||||
".CodeMirror pre {\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
"}\n",
|
||||
" div.cell{\n",
|
||||
" width: 900px;\n",
|
||||
" //width: 950px;\n",
|
||||
" margin-left: 0% !important;\n",
|
||||
" margin-right: auto;\n",
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Lora';\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 100%;\n",
|
||||
" text-align: justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" div.text_cell code {\n",
|
||||
" background: transparent;\n",
|
||||
" color: #000000;\n",
|
||||
" font-weight: 600;\n",
|
||||
" font-weight: 400;\n",
|
||||
" font-size: 11pt;\n",
|
||||
" font-style: bold;\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
" }\n",
|
||||
" h1 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
"\t}\n",
|
||||
"\t\n",
|
||||
"\n",
|
||||
" div.input_area {\n",
|
||||
" background: #F6F6F9;\n",
|
||||
" border: 1px solid #586e75;\n",
|
||||
@ -62,7 +67,7 @@
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" text-align: left;\n",
|
||||
" } \n",
|
||||
" }\n",
|
||||
" h2 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" text-align: left;\n",
|
||||
@ -78,7 +83,7 @@
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" text-align: left;\n",
|
||||
" } \n",
|
||||
" }\n",
|
||||
" h3 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
@ -108,6 +113,7 @@
|
||||
" h5 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .text_cell_render h5 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-style: normal;\n",
|
||||
@ -118,22 +124,15 @@
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Fira sans', verdana,arial,sans-serif;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 115%;\n",
|
||||
" text-align:justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_text.output_pyout {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_stream.output_stdout.output_text {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" overflow-y: visible;\n",
|
||||
" max-height: 5000000px;\n",
|
||||
" }\n",
|
||||
" div.output_wrapper{\n",
|
||||
" margin-top:0.2em;\n",
|
||||
@ -141,7 +140,8 @@
|
||||
"}\n",
|
||||
"\n",
|
||||
" code{\n",
|
||||
" font-size: 70%;\n",
|
||||
" font-size: 6pt;\n",
|
||||
"\n",
|
||||
" }\n",
|
||||
" .rendered_html code{\n",
|
||||
" background-color: transparent;\n",
|
||||
@ -150,42 +150,38 @@
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" }\n",
|
||||
" ul li li{\n",
|
||||
" padding-left: 0.2em; \n",
|
||||
" margin-bottom: 0.2em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" padding-left: 0.2em;\n",
|
||||
" margin-bottom: 0.2em;\n",
|
||||
" margin-top: 0.2em;\n",
|
||||
" }\n",
|
||||
" ol{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ol li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" padding-left: 0.5em;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.2em;\n",
|
||||
" }\n",
|
||||
" a:link{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:visited{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:hover{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:focus{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:active{\n",
|
||||
@ -193,10 +189,10 @@
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" .rendered_html :link {\n",
|
||||
" text-decoration: underline; \n",
|
||||
" text-decoration: underline;\n",
|
||||
" }\n",
|
||||
" .rendered_html :hover {\n",
|
||||
" text-decoration: none; \n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :visited {\n",
|
||||
" text-decoration: none;\n",
|
||||
@ -209,7 +205,7 @@
|
||||
" }\n",
|
||||
" .warning{\n",
|
||||
" color: rgb( 240, 20, 20 )\n",
|
||||
" } \n",
|
||||
" }\n",
|
||||
" hr {\n",
|
||||
" color: #f3f3f3;\n",
|
||||
" background-color: #f3f3f3;\n",
|
||||
@ -234,7 +230,8 @@
|
||||
"<script>\n",
|
||||
" MathJax.Hub.Config({\n",
|
||||
" TeX: {\n",
|
||||
" extensions: [\"AMSmath.js\"]\n",
|
||||
" extensions: [\"AMSmath.js\"],\n",
|
||||
" equationNumbers: { autoNumber: \"AMS\", useLabelIds: true}\n",
|
||||
" },\n",
|
||||
" tex2jax: {\n",
|
||||
" inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
|
||||
@ -242,7 +239,7 @@
|
||||
" },\n",
|
||||
" displayAlign: 'center', // Change this to 'center' to center equations.\n",
|
||||
" \"HTML-CSS\": {\n",
|
||||
" scale:100,\n",
|
||||
" scale:95,\n",
|
||||
" availableFonts: [],\n",
|
||||
" preferredFont:null,\n",
|
||||
" webFont: \"TeX\",\n",
|
||||
@ -255,7 +252,7 @@
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -312,9 +309,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.0"
|
||||
"version": "3.6.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
|
75
README.md
75
README.md
@ -50,7 +50,7 @@ From my point of view none of this necessary. Certainly if you are designing a K
|
||||
|
||||
I wrote this book to address all of those needs. This is not the book for you if you program navigation computers for Boeing or design radars for Raytheon. Go get an advanced degree at Georgia Tech, UW, or the like, because you'll need it. This book is for the hobbiest, the curious, and the working engineer that needs to filter or smooth data.
|
||||
|
||||
This book is interactive. While you can read it online as static content, I urge you to use it as intended. It is written using Jupyter Notebook, which allows me to combine text, Python, and Python output in one place. Every plot, every piece of data in this book is generated from Python that is available to you right inside the notebook. Want to double the value of a parameter? Click on the Python cell, change the parameter's value, and click 'Run'. A new plot or printed output will appear in the book.
|
||||
This book is interactive. While you can read it online as static content, I urge you to use it as intended. It is written using Jupyter Notebook, which allows me to combine text, math, Python, and Python output in one place. Every plot, every piece of data in this book is generated from Python that is available to you right inside the notebook. Want to double the value of a parameter? Click on the Python cell, change the parameter's value, and click 'Run'. A new plot or printed output will appear in the book.
|
||||
|
||||
This book has exercises, but it also has the answers. I trust you. If you just need an answer, go ahead and read the answer. If you want to internalize this knowledge, try to implement the exercise before you read the answer.
|
||||
|
||||
@ -79,35 +79,22 @@ The website http://nbviewer.org provides an Jupyter Notebook server that renders
|
||||
GitHub is able to render the notebooks directly. The quickest way to view a notebook is to just click on them above. Note: I have found this to be buggy - sometimes it cannot open files that are readable by all the other methods here. Chapters names are prefaced with numbers to indicate their order 01_gh_filter.ipynb, and so on. Notebooks are rendered statically - you can read them, but not modify or run the code.
|
||||
|
||||
|
||||
Issues or Questions
|
||||
------
|
||||
|
||||
If you have comments, you can write an issue at GitHub so that everyone can read it along with my response. Please don't view it as a way to report bugs only. Alternatively I've created a gitter room for more informal discussion. [](https://gitter.im/rlabbe/Kalman-and-Bayesian-Filters-in-Python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
|
||||
The preface available from the link above has all the information in this README and more, so feel free to follow the link now.
|
||||
|
||||
PDF Version
|
||||
-----
|
||||
I used to keep a PDF version of the book in this repository. However, git does not do well with binary blobs like that, and the repository was getting too big. I deleted it and it's history from git. I am now providing it
|
||||
on my google drive [here](https://drive.google.com/open?id=0By_SW19c1BfhSVFzNHc0SjduNzg)
|
||||
|
||||
A PDF version of the book is available [here](https://drive.google.com/open?id=0By_SW19c1BfhSVFzNHc0SjduNzg)
|
||||
|
||||
|
||||
The PDF will usually lag behind what is in github as I don't update it for every minor check in.
|
||||
|
||||
|
||||
## Downloading the book
|
||||
## Downloading and Running the Book
|
||||
|
||||
However, this book is intended to be interactive and I recommend using it in that form. It's a little more effort to set up, but worth it. If you install IPython and some supporting libraries on your computer and then clone this book you will be able to run all of the code in the book yourself. You can perform experiments, see how filters react to different data, see how different filters react to the same data, and so on. I find this sort of immediate feedback both vital and invigorating. You do not have to wonder "what happens if". Try it and see!
|
||||
However, this book is intended to be interactive and I recommend using it in that form. It's a little more effort to set up, but worth it. If you install IPython and some supporting libraries on your computer and then clone this book you will be able to run all of the code in the book yourself. You can perform experiments, see how filters react to different data, see how different filters react to the same data, and so on. I find this sort of immediate feedback both vital and invigorating. You do not have to wonder "what happens if". Try it and see!
|
||||
|
||||
The github pages for this project are at https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python You can clone it to your hard drive with the command
|
||||
Instructions for installation can be found in the Installation appendix, found [here](http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/Appendix-A-Installation.ipynb).
|
||||
|
||||
git clone https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python.git
|
||||
|
||||
|
||||
|
||||
This will create a directory named Kalman-and-Bayesian-Filters-in-Python.
|
||||
|
||||
Follow the instructions in **Installation and Software Requirements** below to install all the supporting sofware require. Then, navigate to the directory, and run IPython notebook with the command
|
||||
Once the software is installed you can navigate to the installation directory and run Juptyer notebook with the command line instruction
|
||||
|
||||
jupyter notebook
|
||||
|
||||
@ -121,55 +108,25 @@ Companion Software
|
||||
|
||||
[](http://pypi.python.org/pypi/filterpy)
|
||||
|
||||
All of the filters used in this book as well as others not in this book are implemented in my Python library FilterPy, available [here](https://github.com/rlabbe/filterpy). You do not need to download or install this to read the book, but you will likely want to use this library to write your own filters. It includes Kalman filters, Fading Memory filters, H infinity filters, Extended and Unscented filters, least square filters, and many more. It also includes helper routines that simplify the designing the matrices used by some of the filters, and other code such as Kalman based smoothers.
|
||||
|
||||
The easiest way to install is to run pip from the command line:
|
||||
|
||||
$ pip install filterpy
|
||||
|
||||
|
||||
Installation and Software Requirements
|
||||
-----
|
||||
|
||||
**author's note**. *The book is still being written, and so I am not focusing on issues like supporting multiple versions of Python. I am staying more or less on the bleeding edge of Python 3 for the time being. If you follow my suggestion of installing Anaconda the versioning problems will be taken care of for you, and you will not alter or affect any existing installation of Python on your machine. I am aware that telling somebody to install a specific packaging system is not a long term solution, but I can either focus on endless regression testing for every minor code change, or work on delivering the book, and then doing one sweep through it to maximize compatibility. I opt for the latter. In the meantime I welcome bug reports if the book does not work on your platform.*
|
||||
|
||||
If you want to run the notebook on your computer, which is what I recommend, then you will have to have IPython installed. I do not cover how to do that in this book; requirements change based on what other Python installations you may have, whether you use a third party package like Anaconda Python, what operating system you are using, and so on.
|
||||
|
||||
To use all features you will have to have IPython 3.0 or later installed, which is released and stable as of April 2014. Most of the book does not require that recent of a version, but I do make use of the interactive plotting widgets introduced in this release. A few cells will not run if you have an older version installed. This is merely a minor annoyance. If you have IPython 4.0 or later installed then you will need to install the notebook separately. As of version 4.0 the notebook was split into a standalone project called Jupyter. If your distribution does not include Jupyter issuing *pip install jupyter* from the command line should install it. As of August 2015 the instructions and documentation for Jupyter is sparse; if you have customized your IPython environment you may have some searching to do to set up your environment for 4.0. I am not prepared to support your 4.0 install as I am focusing on writing the book, though of course if you encounter a bug either I or the Jupyter team would love to hear about it (depending on whose code has the bug, of course!)
|
||||
|
||||
You will need Python 2.7 or later installed. Almost all of my work is done in Python 3.4, but I periodically test on 2.7. I do not promise any specific check in will work in 2.7 however. I do use Python's "from \_\_future\_\_ import ..." statement to help with compatibility. For example, all prints need to use parenthesis. If you try to add, say, "print 3.14" into the book your script will fail; you must write "print (3.4)" as in Python 3.X.
|
||||
|
||||
You will need a recent version of NumPy, SciPy, SymPy, and Matplotlib installed. I don't really know what the minimal version might be. I have numpy 1.71, SciPy 0.13.0, and Matplotlib 1.4.0 installed on my machines.
|
||||
|
||||
Personally, I use the Anaconda Python distribution in all of my work, [available here](https://store.continuum.io/cshop/anaconda/). I am not selecting them out of favoritism, I am merely documenting my environment. Should you have trouble running any of the code, perhaps knowing this will help you. Especially if you are in Windows, installing the entire stack above can be difficult if you do not use a distribution like Anaconda.
|
||||
|
||||
Finally, you will need to install FilterPy, described in the next section.
|
||||
|
||||
Installation of all of these packages is described in the Installation appendix, which you can read online [here](http://nbviewer.ipython.org/github/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/Appendix_A_Installation.ipynb).
|
||||
|
||||
|
||||
Provided Libraries and Modules
|
||||
-----
|
||||
|
||||
I am writing an open source Bayesian filtering Python library called **FilterPy**. I have made the project available on PyPi, the Python Package Index. To install from PyPi, at the command line issue the command
|
||||
I wrote an open source Bayesian filtering Python library called **FilterPy**. I have made the project available on PyPi, the Python Package Index. To install from PyPi, at the command line issue the command
|
||||
|
||||
pip install filterpy
|
||||
|
||||
If you do not have pip, you may follow the instructions here: https://pip.pypa.io/en/latest/installing.html.
|
||||
|
||||
I recommend using pip for the install, as I try hard (sometimes I fail) to make good, safe releases to it. Whereas on github (where the project resides) I'll check in any tiny change at any time; there is no guarantee that the latest on github is a version you really want to have.
|
||||
All of the filters used in this book as well as others not in this book are implemented in my Python library FilterPy, available [here](https://github.com/rlabbe/filterpy). You do not need to download or install this to read the book, but you will likely want to use this library to write your own filters. It includes Kalman filters, Fading Memory filters, H infinity filters, Extended and Unscented filters, least square filters, and many more. It also includes helper routines that simplify the designing the matrices used by some of the filters, and other code such as Kalman based smoothers.
|
||||
|
||||
FilterPy is hosted github at (https://github.com/rlabbe/filterpy). If you want the bleading edge release you will want to grab a copy from github, and follow your Python installation's instructions for adding it to the Python search path. However, it is quite possible that it will not be compatible with the notebooks in this project. I try to make sure the notebooks are in sync with the PyPi hosted version.
|
||||
|
||||
Code that is specific to the book is stored with the book in the subdirectory ./*kf_book*. This code is in a state of flux; I do not wish to document it here yet. I do mention in the book when I use code from this directory, so it should not be a mystery.
|
||||
FilterPy is hosted github at (https://github.com/rlabbe/filterpy). If you want the bleading edge release you will want to grab a copy from github, and follow your Python installation's instructions for adding it to the Python search path. This might expose you to some instability since you might not get a tested release, but as a benefit you will also get all of the test scripts used to test the library. You can examine these scripts to see many examples of writing and running filters while not in the Jupyter Notebook environment.
|
||||
|
||||
In the *kf_book* subdirectory there are Python files with a name like *xxx*_internal.py. I use these to store functions that are useful for a specific chapter. This allows me to hide away Python code that is not particularly interesting to read - I may be generating a plot or chart, and I want you to focus on the contents of the chart, not the mechanics of how I generate that chart with Python. If you are curious as to the mechanics of that, just go and browse the source.
|
||||
|
||||
Some chapters introduce functions that are useful for the rest of the book. Those functions are initially defined within the Notebook itself, but the code is also stored in a Python file that is imported if needed in later chapters. I do document when I do this where the function is first defined, but this is still a work in progress. I try to avoid this because then I always face the issue of code in the directory becoming out of sync with the code in the book. However, IPython Notebook does not give us a way to refer to code cells in other notebooks, so this is the only mechanism I know of to share functionality across notebooks.
|
||||
|
||||
There is an undocumented directory called **experiments**. This is where I write and test code prior to putting it in the book. There is some interesting stuff in there, and feel free to look at it. As the book evolves I plan to create examples and projects, and a lot of this material will end up there. Small experiments will eventually just be deleted. If you are just interested in reading the book you can safely ignore this directory.
|
||||
|
||||
The directory **kf_book** contains a css file containing the style guide for the book. The default look and feel of IPython Notebook is rather plain. Work is being done on this. I have followed the examples set by books such as [Probabilistic Programming and Bayesian Methods for Hackers](http://nbviewer.ipython.org/github/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/blob/master/Chapter1_Introduction/Chapter1.ipynb). I have also been very influenced by Professor Lorena Barba's fantastic work, [available here](https://github.com/barbagroup/CFDPython). I owe all of my look and feel to the work of these projects.
|
||||
Issues or Questions
|
||||
------
|
||||
|
||||
If you have comments, you can write an issue at GitHub so that everyone can read it along with my response. Please don't view it as a way to report bugs only. Alternatively I've created a gitter room for more informal discussion. [](https://gitter.im/rlabbe/Kalman-and-Bayesian-Filters-in-Python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
|
||||
License
|
||||
-----
|
||||
|
@ -35,6 +35,10 @@ if matplotlib.__version__ == '1.4.3':
|
||||
warnings.simplefilter(action="ignore", category=FutureWarning)
|
||||
|
||||
np.set_printoptions(precision=3)
|
||||
try:
|
||||
matplotlib.style.use('default')
|
||||
except:
|
||||
pass
|
||||
|
||||
def test_filterpy_version():
|
||||
|
||||
@ -42,7 +46,7 @@ def test_filterpy_version():
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
v = filterpy.__version__
|
||||
min_version = "0.1.2"
|
||||
min_version = "1.1.0"
|
||||
if LooseVersion(v) < LooseVersion(min_version):
|
||||
raise Exception("Minimum FilterPy version supported is {}.\n"
|
||||
"Please install a more recent version.\n"
|
||||
@ -56,7 +60,7 @@ def test_filterpy_version():
|
||||
test_filterpy_version()
|
||||
|
||||
pylab.rcParams['figure.max_open_warning'] = 50
|
||||
pylab.rcParams['figure.figsize'] = 9, 4
|
||||
pylab.rcParams['figure.figsize'] = 8, 3
|
||||
|
||||
|
||||
|
||||
@ -109,17 +113,12 @@ def load_style(directory = '.', name='kf_book/custom.css'):
|
||||
style = json.load(open(os.path.join(directory, "kf_book/538.json")))
|
||||
else:
|
||||
style = json.load(open(directory + "/kf_book/538.json"), object_hook=_decode_dict)
|
||||
|
||||
# matplotlib has deprecated the use of axes.color_cycle as of version
|
||||
if version[0] > 1 or (version[0] == 1 and version[1] >= 5):
|
||||
style["axes.prop_cycle"] = "cycler('color', ['#6d904f','#013afe', '#202020','#fc4f30','#e5ae38','#A60628','#30a2da','#008080','#7A68A6','#CF4457','#188487','#E24A33'])"
|
||||
style.pop("axes.color_cycle", None)
|
||||
plt.rcParams.update(style)
|
||||
except:
|
||||
pass
|
||||
set_figsize()
|
||||
reset_axis ()
|
||||
np.set_printoptions(suppress=True,precision=3, linewidth=70,
|
||||
np.set_printoptions(suppress=True, precision=3, linewidth=70,
|
||||
formatter={'float':lambda x:' {:.3}'.format(x)})
|
||||
|
||||
styles = open(os.path.join(directory, name), 'r').read()
|
||||
|
@ -1,27 +1,11 @@
|
||||
{
|
||||
"lines.linewidth": 2.0,
|
||||
"lines.linewidth": 1.5,
|
||||
"patch.linewidth": 0.5,
|
||||
"legend.fancybox": true,
|
||||
"axes.color_cycle": [
|
||||
"#6d904f",
|
||||
"#013afe",
|
||||
"#202020",
|
||||
"#fc4f30",
|
||||
"#e5ae38",
|
||||
"#A60628",
|
||||
"#30a2da",
|
||||
"#008080",
|
||||
"#7A68A6",
|
||||
"#CF4457",
|
||||
"#188487",
|
||||
"#E24A33"
|
||||
],
|
||||
"axes.facecolor": "#ffffff",
|
||||
"axes.labelsize": "large",
|
||||
"axes.axisbelow": true,
|
||||
"axes.grid": true,
|
||||
"patch.edgecolor": "#f0f0f0",
|
||||
"axes.titlesize": "x-large",
|
||||
"examples.directory": "",
|
||||
"figure.facecolor": "#ffffff",
|
||||
"grid.linestyle": "-",
|
||||
@ -33,8 +17,7 @@
|
||||
"ytick.major.size": 0,
|
||||
"ytick.minor.size": 0,
|
||||
"axes.linewidth": 3.0,
|
||||
"font.size":14.0,
|
||||
"lines.linewidth": 3,
|
||||
"font.size":12.0,
|
||||
"lines.solid_capstyle": "butt",
|
||||
"savefig.edgecolor": "#f0f0f0",
|
||||
"savefig.facecolor": "#f0f0f0",
|
||||
|
@ -22,7 +22,9 @@ import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
def plot_track_and_residuals(t, xs, z_xs, res):
|
||||
def plot_track_and_residuals(dt, xs, z_xs, res):
|
||||
assert np.isscalar(dt)
|
||||
t = np.arange(0, len(xs)*dt, dt)
|
||||
plt.subplot(121)
|
||||
if z_xs is not None:
|
||||
bp.plot_measurements(t, z_xs, label='z')
|
||||
@ -45,8 +47,7 @@ def plot_markov_chain():
|
||||
fig = plt.figure(figsize=(4,4), facecolor='w')
|
||||
ax = plt.axes((0, 0, 1, 1),
|
||||
xticks=[], yticks=[], frameon=False)
|
||||
#ax.set_xlim(0, 10)
|
||||
#ax.set_ylim(0, 10)
|
||||
|
||||
box_bg = '#DDDDDD'
|
||||
|
||||
kf1c = Circle((4,5), 0.5, fc=box_bg)
|
||||
@ -99,7 +100,6 @@ def plot_markov_chain():
|
||||
|
||||
plt.axis('equal')
|
||||
plt.show()
|
||||
bp.end_interactive(fig)
|
||||
|
||||
|
||||
def turning_target(N=600, turn_start=400):
|
||||
|
@ -33,25 +33,25 @@ except:
|
||||
pass
|
||||
|
||||
|
||||
def equal_axis():
|
||||
pylab.rcParams['figure.figsize'] = 10,10
|
||||
def equal_axis(sz=10):
|
||||
pylab.rcParams['figure.figsize'] = sz, sz
|
||||
plt.axis('equal')
|
||||
|
||||
|
||||
def reset_axis():
|
||||
pylab.rcParams['figure.figsize'] = 9, 3
|
||||
pylab.rcParams['figure.figsize'] = 8, 3
|
||||
|
||||
|
||||
def reset_figsize():
|
||||
pylab.rcParams['figure.figsize'] = 9, 4
|
||||
pylab.rcParams['figure.figsize'] = 8, 3
|
||||
|
||||
|
||||
def set_figsize(x=9, y=4):
|
||||
def set_figsize(x=8, y=3):
|
||||
pylab.rcParams['figure.figsize'] = x, y
|
||||
|
||||
|
||||
@contextmanager
|
||||
def figsize(x=9, y=4):
|
||||
def figsize(x=8, y=3):
|
||||
"""Temporarily set the figure size using 'with figsize(a,b):'"""
|
||||
|
||||
size = pylab.rcParams['figure.figsize']
|
||||
@ -100,18 +100,19 @@ def interactive_plot(close=True, fig=None):
|
||||
end_interactive(fig)
|
||||
|
||||
|
||||
def plot_errorbars(bars, xlims, ylims=(0, 2)):
|
||||
def plot_errorbars(bars, xlims, ylims=(-1, 1)):
|
||||
|
||||
i = 0.0
|
||||
for bar in bars:
|
||||
plt.errorbar([bar[0]], [i], xerr=[bar[1]], fmt='o', label=bar[2] , capthick=2, capsize=10)
|
||||
i += 0.2
|
||||
with figsize(y=2):
|
||||
i = 0.0
|
||||
for bar in bars:
|
||||
plt.errorbar([bar[0]], [i], xerr=[bar[1]], fmt='o', label=bar[2] , capthick=2, capsize=10)
|
||||
i += 0.2
|
||||
|
||||
plt.ylim(*ylims)
|
||||
plt.xlim(xlims[0], xlims[1])
|
||||
show_legend()
|
||||
plt.gca().axes.yaxis.set_ticks([])
|
||||
plt.show()
|
||||
plt.ylim(*ylims)
|
||||
plt.xlim(xlims[0], xlims[1])
|
||||
show_legend()
|
||||
plt.gca().axes.yaxis.set_ticks([])
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_errorbar1():
|
||||
@ -237,12 +238,13 @@ def plot_estimate_chart_2():
|
||||
plt.scatter ([1], [164.2], c='b',s=128)
|
||||
plt.scatter ([1], [159], c='r', s=128)
|
||||
plt.text (1.0, 158.8, "prediction ($x_t)$", ha='center',va='top',fontsize=18,color='red')
|
||||
plt.text (1.0, 164.4, "measurement ($z$)",ha='center',va='bottom',fontsize=18,color='blue')
|
||||
plt.text (0, 157.8, "estimate ($\hat{x}_{t-1}$)", ha='center', va='top',fontsize=18)
|
||||
plt.text (1.0, 164.4, "measurement ($z_t$)",ha='center',va='bottom',fontsize=18,color='blue')
|
||||
plt.text (0.0, 159.8, "estimate ($\hat{x}_{t-1}$)", ha='left', va='top',fontsize=18)
|
||||
plt.xlabel('day')
|
||||
plt.ylabel('weight (lbs)')
|
||||
ax.xaxis.grid(True, which="major", linestyle='dotted')
|
||||
ax.yaxis.grid(True, which="major", linestyle='dotted')
|
||||
plt.ylim(157, 164.5)
|
||||
|
||||
|
||||
def plot_estimate_chart_3():
|
||||
@ -263,16 +265,16 @@ def plot_estimate_chart_3():
|
||||
plt.scatter ([1], [159], c='r', s=128)
|
||||
plt.text (1.0, 158.8, "prediction ($x_t)$", ha='center',va='top',fontsize=18,color='red')
|
||||
plt.text (1.0, 164.4, "measurement ($z$)",ha='center',va='bottom',fontsize=18,color='blue')
|
||||
plt.text (0, 157.8, "estimate ($\hat{x}_{t-1}$)", ha='center', va='top',fontsize=18)
|
||||
plt.text (0, 159.8, "estimate ($\hat{x}_{t-1}$)", ha='left', va='top',fontsize=18)
|
||||
plt.text (0.95, est_y, "new estimate ($\hat{x}_{t}$)", ha='right', va='center',fontsize=18)
|
||||
plt.xlabel('day')
|
||||
plt.ylabel('weight (lbs)')
|
||||
ax.xaxis.grid(True, which="major", linestyle='dotted')
|
||||
ax.yaxis.grid(True, which="major", linestyle='dotted')
|
||||
plt.ylim(157, 164.5)
|
||||
|
||||
|
||||
|
||||
def create_predict_update_chart(box_bg = '#CCCCCC',
|
||||
def predict_update_chart(box_bg = '#CCCCCC',
|
||||
arrow1 = '#88CCFF',
|
||||
arrow2 = '#88FF88'):
|
||||
plt.figure(figsize=(4,4), facecolor='w')
|
||||
@ -334,7 +336,7 @@ def create_predict_update_chart(box_bg = '#CCCCCC',
|
||||
plt.text (4, 3.7,'State Estimate ($\mathbf{\hat{x}_k}$)',
|
||||
ha='center', va='center', fontsize=14)
|
||||
plt.axis('equal')
|
||||
plt.xlim(2,10)
|
||||
plt.show()
|
||||
|
||||
|
||||
def show_residual_chart(show_eq=True, show_H=False):
|
||||
@ -417,7 +419,7 @@ def bar_plot(pos, x=None, ylim=(0,1), title=None, c='#30a2da',
|
||||
ax.bar(x, pos, color=c, **kwargs)
|
||||
if ylim:
|
||||
plt.ylim(ylim)
|
||||
plt.xticks(np.asarray(x)+0.4, x)
|
||||
plt.xticks(np.asarray(x), x)
|
||||
if title is not None:
|
||||
plt.title(title)
|
||||
|
||||
@ -490,11 +492,14 @@ def plot_kf_output(xs, filter_xs, zs, title=None, aspect_equal=True):
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_measurements(xs, ys=None, color='k', lw=2, label='Measurements',
|
||||
def plot_measurements(xs, ys=None, dt=None, color='k', lw=1, label='Measurements',
|
||||
lines=False, **kwargs):
|
||||
""" Helper function to give a consistant way to display
|
||||
measurements in the book.
|
||||
"""
|
||||
if ys is None and dt is not None:
|
||||
ys = xs
|
||||
xs = np.arange(0, len(ys)*dt, dt)
|
||||
|
||||
plt.autoscale(tight=True)
|
||||
if lines:
|
||||
@ -525,17 +530,23 @@ def plot_residual_limits(Ps, stds=1.):
|
||||
facecolor='#ffff00', alpha=0.3)
|
||||
|
||||
|
||||
def plot_track(xs, ys=None, label='Track', c='k', lw=2, **kwargs):
|
||||
def plot_track(xs, ys=None, dt=None, label='Track', c='k', lw=2, **kwargs):
|
||||
if ys is None and dt is not None:
|
||||
ys = xs
|
||||
xs = np.arange(0, len(ys)*dt, dt)
|
||||
if ys is not None:
|
||||
return plt.plot(xs, ys, color=c, lw=lw, ls=':', label=label, **kwargs)
|
||||
else:
|
||||
return plt.plot(xs, color=c, lw=lw, ls=':', label=label, **kwargs)
|
||||
|
||||
|
||||
def plot_filter(xs, ys=None, c='#013afe', label='Filter', var=None, **kwargs):
|
||||
def plot_filter(xs, ys=None, dt=None, c='C0', label='Filter', var=None, **kwargs):
|
||||
""" plot result of KF with color `c`, optionally displaying the variance
|
||||
of `xs`. Returns the list of lines generated by plt.plot()"""
|
||||
|
||||
if ys is None and dt is not None:
|
||||
ys = xs
|
||||
xs = np.arange(0, len(ys) * dt, dt)
|
||||
if ys is None:
|
||||
ys = xs
|
||||
xs = range(len(ys))
|
||||
@ -622,7 +633,7 @@ if __name__ == "__main__":
|
||||
plot_estimate_chart_1()
|
||||
plot_estimate_chart_2()
|
||||
plot_estimate_chart_3()
|
||||
create_predict_update_chart()
|
||||
predict_update_chart()
|
||||
show_residual_chart()
|
||||
show_residual_chart(True, True)
|
||||
plt.close('all')
|
||||
|
@ -2,24 +2,6 @@
|
||||
@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');
|
||||
@import url('http://fonts.googleapis.com/css?family=Lora');
|
||||
|
||||
//@import url('http://fonts.googleapis.com/css?family=Open+Sans');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Vollkorn');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Karla');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Poppins');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Arimo');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Roboto');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Lato');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Domine');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Chivo');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Cardo');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Arvo');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Crimson+Text');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Ubuntu');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Fontin');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Raleway');
|
||||
//@import url('http://fonts.googleapis.com/css?family=Merriweather');
|
||||
|
||||
|
||||
.CodeMirror pre {
|
||||
font-family: 'Source Code Pro', Consolas, monocco, monospace;
|
||||
}
|
||||
@ -30,24 +12,8 @@
|
||||
}
|
||||
div.text_cell_render{
|
||||
font-family: 'Lora';
|
||||
//font-family: 'Open Sans';
|
||||
//font-family: 'Karla',verdana,arial,sans-serif;
|
||||
//font-family: 'Roboto',verdana,arial,sans-serif;
|
||||
//font-family: 'Lato',verdana,arial,sans-serif;
|
||||
//font-family: 'Domine',verdana,arial,sans-serif;
|
||||
//font-family: 'Chivo',verdana,arial,sans-serif;
|
||||
//font-family: 'Cardo',verdana,arial,sans-serif;
|
||||
//font-family: 'Arvo',verdana,arial,sans-serif;
|
||||
//font-family: 'Poppins',verdana,arial,sans-serif;
|
||||
//font-family: 'Ubuntu',verdana,arial,sans-serif;
|
||||
//font-family: 'Fontin',verdana,arial,sans-serif;
|
||||
//font-family: 'Raleway',verdana,arial,sans-serif;
|
||||
//font-family: 'Merriweather',verdana,arial,sans-serif;
|
||||
//font-family: 'Crimson Text', verdana,arial,sans-serif;
|
||||
//font-family: verdana,arial,sans-serif;
|
||||
//font-family: arial,sans-serif;
|
||||
line-height: 125%;
|
||||
font-size: 130%;
|
||||
font-size: 100%;
|
||||
text-align: justify;
|
||||
text-justify:inter-word;
|
||||
}
|
||||
@ -55,8 +21,7 @@
|
||||
background: transparent;
|
||||
color: #000000;
|
||||
font-weight: 400;
|
||||
font-size: 12pt;
|
||||
//font-style: bold;
|
||||
font-size: 11pt;
|
||||
font-family: 'Source Code Pro', Consolas, monocco, monospace;
|
||||
}
|
||||
h1 {
|
||||
@ -137,13 +102,13 @@
|
||||
}
|
||||
div.output_subarea.output_text.output_pyout {
|
||||
overflow-x: auto;
|
||||
overflow-y: scroll;
|
||||
max-height: 50000px;
|
||||
overflow-y: visible;
|
||||
max-height: 5000000px;
|
||||
}
|
||||
div.output_subarea.output_stream.output_stdout.output_text {
|
||||
overflow-x: auto;
|
||||
overflow-y: scroll;
|
||||
max-height: 50000px;
|
||||
overflow-y: visible;
|
||||
max-height: 5000000px;
|
||||
}
|
||||
div.output_wrapper{
|
||||
margin-top:0.2em;
|
||||
|
@ -201,8 +201,7 @@ def show_radar_chart():
|
||||
plt.ylim([0.5,2.5])
|
||||
|
||||
plt.scatter ([1,2],[1,2])
|
||||
#plt.scatter ([2],[1],marker='o')
|
||||
ax = plt.axes()
|
||||
ax = plt.gca()
|
||||
|
||||
ax.annotate('', xy=(2,2), xytext=(1,1),
|
||||
arrowprops=dict(arrowstyle='->', ec='r',shrinkA=3, shrinkB=4))
|
||||
@ -239,7 +238,7 @@ def show_linearization():
|
||||
|
||||
plt.plot(xs, ys, label='$f(x)=x^2−2x$')
|
||||
plt.plot([1, 2], [y(1), y(2)], color='k', ls='--', label='linearization')
|
||||
plt.axes().axvline(1.5, lw=1, c='k')
|
||||
plt.gca().axvline(1.5, lw=1, c='k')
|
||||
plt.xlim(0, 2)
|
||||
plt.ylim([-1.5, 0.0])
|
||||
plt.title('Linearization of $f(x)$ at $x=1.5$')
|
||||
|
@ -34,6 +34,7 @@ def plot_height_std(x, lw=10):
|
||||
facecolor='yellow', alpha=0.4)
|
||||
plt.xlabel('student')
|
||||
plt.ylabel('height (m)')
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_correlated_data(X, Y, xlabel=None,
|
||||
@ -54,11 +55,11 @@ def plot_correlated_data(X, Y, xlabel=None,
|
||||
plt.gca().set_aspect('equal')
|
||||
plt.show()
|
||||
|
||||
def plot_gaussian (mu, variance,
|
||||
mu_line=False,
|
||||
xlim=None,
|
||||
xlabel=None,
|
||||
ylabel=None):
|
||||
def plot_gaussian(mu, variance,
|
||||
mu_line=False,
|
||||
xlim=None,
|
||||
xlabel=None,
|
||||
ylabel=None):
|
||||
|
||||
xs = np.arange(mu-variance*2,mu+variance*2,0.1)
|
||||
ys = [stats.gaussian (x, mu, variance)*100 for x in xs]
|
||||
@ -73,6 +74,7 @@ def plot_gaussian (mu, variance,
|
||||
plt.ylabel(ylabel)
|
||||
plt.show()
|
||||
|
||||
|
||||
def display_stddev_plot():
|
||||
xs = np.arange(10,30,0.1)
|
||||
var = 8;
|
||||
@ -94,7 +96,7 @@ def display_stddev_plot():
|
||||
plt.plot ([20,20],[0,y],'b')
|
||||
|
||||
x = 20+stddev
|
||||
ax = plt.axes()
|
||||
ax = plt.gca()
|
||||
ax.annotate('68%', xy=(20.3, 0.045))
|
||||
ax.annotate('', xy=(20-stddev,0.04), xytext=(x,0.04),
|
||||
arrowprops=dict(arrowstyle="<->",
|
||||
|
@ -26,22 +26,18 @@ import time
|
||||
|
||||
def plot_gh_results(weights, estimates, predictions, time_step=0):
|
||||
|
||||
plt.figure(figsize=(9,4))
|
||||
n = len(weights)
|
||||
if time_step > 0:
|
||||
rng = range(1, n+1)
|
||||
else:
|
||||
rng = range(n, n+1)
|
||||
|
||||
plt.xlim([-1, n+1])
|
||||
plt.ylim([156.0, 173])
|
||||
act, = book_plots.plot_track([0, n], [160, 160+n], c='k')
|
||||
plt.gcf().canvas.draw()
|
||||
|
||||
for i in rng:
|
||||
xs = list(range(i+1))
|
||||
|
||||
#plt.cla()
|
||||
|
||||
pred, = book_plots.plot_track(xs[1:], predictions[:i], c='r', marker='v')
|
||||
plt.xlim([-1, n+1])
|
||||
plt.ylim([156.0, 173])
|
||||
@ -62,6 +58,8 @@ def plot_gh_results(weights, estimates, predictions, time_step=0):
|
||||
|
||||
plt.legend([act, scale, est, pred], ['Actual Weight', 'Measurement', 'Estimates', 'Predictions'], loc=4)
|
||||
book_plots.set_labels(x='day', y='weight (lbs)')
|
||||
plt.xlim([-1, n+1])
|
||||
plt.ylim([156.0, 173])
|
||||
|
||||
|
||||
|
||||
|
@ -149,7 +149,7 @@ def show_position_prediction_chart():
|
||||
plt.yticks(np.arange(1,5,1))
|
||||
|
||||
plt.scatter ([4], [4], s=128, color='#8EBA42')
|
||||
ax = plt.axes()
|
||||
ax = plt.gca()
|
||||
ax.annotate('', xy=(4,4), xytext=(3,3),
|
||||
arrowprops=dict(arrowstyle='->',
|
||||
ec='g',
|
||||
|
@ -16,8 +16,7 @@ for more information.
|
||||
from __future__ import (absolute_import, division, print_function,
|
||||
unicode_literals)
|
||||
|
||||
from filterpy.kalman import MerweScaledSigmaPoints, unscented_transform
|
||||
from filterpy.stats import multivariate_gaussian
|
||||
import math
|
||||
from matplotlib import cm
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
@ -25,8 +24,11 @@ import numpy as np
|
||||
from numpy.random import normal, multivariate_normal
|
||||
import scipy.stats
|
||||
|
||||
def plot_nonlinear_func(data, f, gaussian, num_bins=300):
|
||||
from filterpy.kalman import MerweScaledSigmaPoints, unscented_transform
|
||||
from filterpy.stats import multivariate_gaussian
|
||||
|
||||
|
||||
def plot_nonlinear_func(data, f, gaussian, num_bins=300):
|
||||
# linearize at mean to simulate EKF
|
||||
#x = gaussian[0]
|
||||
|
||||
@ -44,11 +46,10 @@ def plot_nonlinear_func(data, f, gaussian, num_bins=300):
|
||||
in_lims = [x0-in_std*3, x0+in_std*3]
|
||||
out_lims = [y-std*3, y+std*3]
|
||||
|
||||
|
||||
#plot output
|
||||
h = np.histogram(ys, num_bins, density=False)
|
||||
plt.subplot(2,2,4)
|
||||
plt.plot(h[0], h[1][1:], lw=4, alpha=0.8)
|
||||
plt.plot(h[0], h[1][1:], lw=2, alpha=0.8)
|
||||
plt.ylim(out_lims[1], out_lims[0])
|
||||
plt.gca().xaxis.set_ticklabels([])
|
||||
plt.title('Output')
|
||||
@ -82,15 +83,13 @@ def plot_nonlinear_func(data, f, gaussian, num_bins=300):
|
||||
h = np.histogram(data, num_bins, density=True)
|
||||
|
||||
plt.subplot(2,2,1)
|
||||
plt.plot(h[1][1:], h[0], lw=4)
|
||||
plt.plot(h[1][1:], h[0], lw=2)
|
||||
plt.xlim(in_lims)
|
||||
plt.gca().yaxis.set_ticklabels([])
|
||||
plt.title('Input')
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
import math
|
||||
|
||||
def plot_ekf_vs_mc():
|
||||
|
||||
def fx(x):
|
||||
@ -205,7 +204,6 @@ def test_plot():
|
||||
plt.plot(h[1][1:], h[0], lw=4)
|
||||
|
||||
|
||||
|
||||
def plot_bivariate_colormap(xs, ys):
|
||||
xs = np.asarray(xs)
|
||||
ys = np.asarray(ys)
|
||||
@ -230,17 +228,17 @@ def plot_monte_carlo_mean(xs, ys, f, mean_fx, label, plot_colormap=True):
|
||||
computed_mean_x = np.average(fxs)
|
||||
computed_mean_y = np.average(fys)
|
||||
|
||||
plt.subplot(121)
|
||||
plt.gca().grid(b=False)
|
||||
ax = plt.subplot(121)
|
||||
ax.grid(b=False)
|
||||
|
||||
plot_bivariate_colormap(xs, ys)
|
||||
|
||||
plt.scatter(xs, ys, marker='.', alpha=0.02, color='k')
|
||||
plt.xlim(-20, 20)
|
||||
plt.ylim(-20, 20)
|
||||
ax.set_xlim(-20, 20)
|
||||
ax.set_ylim(-20, 20)
|
||||
|
||||
plt.subplot(122)
|
||||
plt.gca().grid(b=False)
|
||||
ax = plt.subplot(122)
|
||||
ax.grid(b=False)
|
||||
|
||||
plt.scatter(fxs, fys, marker='.', alpha=0.02, color='k')
|
||||
plt.scatter(mean_fx[0], mean_fx[1],
|
||||
@ -249,16 +247,15 @@ def plot_monte_carlo_mean(xs, ys, f, mean_fx, label, plot_colormap=True):
|
||||
marker='*',s=120, c='b', label='Computed Mean')
|
||||
|
||||
plot_bivariate_colormap(fxs, fys)
|
||||
plt.ylim([-10, 200])
|
||||
plt.xlim([-100, 100])
|
||||
ax.set_xlim([-100, 100])
|
||||
ax.set_ylim([-10, 200])
|
||||
plt.legend(loc='best', scatterpoints=1)
|
||||
print ('Difference in mean x={:.3f}, y={:.3f}'.format(
|
||||
computed_mean_x-mean_fx[0], computed_mean_y-mean_fx[1]))
|
||||
|
||||
|
||||
|
||||
def plot_cov_ellipse_colormap(cov=[[1,1],[1,1]]):
|
||||
side = np.linspace(-3,3,24)
|
||||
side = np.linspace(-3, 3, 200)
|
||||
X,Y = np.meshgrid(side,side)
|
||||
|
||||
pos = np.empty(X.shape + (2,))
|
||||
@ -271,7 +268,6 @@ def plot_cov_ellipse_colormap(cov=[[1,1],[1,1]]):
|
||||
plt.show()
|
||||
|
||||
|
||||
|
||||
def plot_gaussians(xs, ps, x_range, y_range, N):
|
||||
""" given a list of 2d states (x,y) and 2x2 covariance matrices, produce
|
||||
a surface plot showing all of the gaussians"""
|
||||
|
@ -111,12 +111,14 @@ def plot_random_pd():
|
||||
y2 = (0.1 * np.sin(norm(x, 0.2, 0.05)) + 0.25 * norm(x, 0.6, 0.05) +
|
||||
.5*norm(x, .5, .08) +
|
||||
np.sqrt(norm(x, 0.8, 0.06)) +0.1 * (1 - sigmoid(x, 0.45, 0.15)))
|
||||
with plt.xkcd():
|
||||
#plt.setp(plt.gca().get_xticklabels(), visible=False)
|
||||
#plt.setp(plt.gca().get_yticklabels(), visible=False)
|
||||
plt.axes(xticks=[], yticks=[], frameon=False)
|
||||
plt.plot(x, y2)
|
||||
plt.ylim([0, max(y2)+.1])
|
||||
|
||||
# hack because of bug `with plt.xkcd()` doesn't return context correctly
|
||||
saved_state = mpl.rcParams.copy()
|
||||
plt.xkcd()
|
||||
plt.axes(xticks=[], yticks=[], frameon=False)
|
||||
plt.plot(x, y2)
|
||||
plt.ylim([0, max(y2)+.1])
|
||||
mpl.rcParams.update(saved_state)
|
||||
|
||||
|
||||
def plot_monte_carlo_ukf():
|
||||
|
@ -367,7 +367,7 @@ def plot_scatter_moving_target():
|
||||
a = actual_angle + randn() * math.radians(1)
|
||||
xs.append(d*math.cos(a))
|
||||
ys.append(d*math.sin(a))
|
||||
plt.scatter(xs, ys)
|
||||
plt.scatter(xs, ys, c='C0')
|
||||
|
||||
plt.axis('equal')
|
||||
plt.plot([5.5, pos[0]], [6, pos[1]], c='g', linestyle='--')
|
||||
@ -419,7 +419,7 @@ def _plot_iscts(pos, sa, sb, N=4):
|
||||
|
||||
plt.scatter(xs, ys, c='r', marker='.', alpha=0.5)
|
||||
plt.scatter(xs_a, ys_a, c='k', edgecolor='k')
|
||||
plt.scatter(xs_b, ys_b, marker='v', edgecolor=None)
|
||||
plt.scatter(xs_b, ys_b, marker='v', edgecolor=None, c='C0')
|
||||
plt.gca().set_aspect('equal')
|
||||
|
||||
|
||||
@ -430,7 +430,7 @@ def plot_iscts_two_sensors():
|
||||
sb = [8., 2.]
|
||||
|
||||
plt.scatter(*sa, s=200, c='k', marker='v')
|
||||
plt.scatter(*sb, s=200, marker='s')
|
||||
plt.scatter(*sb, s=200, marker='s', c='C0')
|
||||
_plot_iscts(pos, sa, sb, N=4)
|
||||
plt.subplot(122)
|
||||
plot_iscts_two_sensors_changed_sensors()
|
||||
|
@ -1,7 +1,9 @@
|
||||
% Inherit from report
|
||||
%((* extends 'report.tplx' *))
|
||||
|
||||
((* set cell_style = 'style_ipython.tplx' *))
|
||||
|
||||
((= IPython input/output style =))
|
||||
|
||||
((*- extends 'base.tplx' -*))
|
||||
|
||||
|
||||
((* block docclass *))
|
||||
\documentclass{book}
|
||||
@ -23,5 +25,68 @@
|
||||
\normalem
|
||||
\setlength{\parindent}{0em}
|
||||
\setlength{\parskip}{0.5em}
|
||||
((( cell.source | citation2latex | strip_files_prefix | markdown2latex(extra_args=["--chapters"]) )))
|
||||
((* endblock markdowncell *))
|
||||
((( cell.source | citation2latex | strip_files_prefix | markdown2latex(extra_args=["--top-level-division=chapter"]) )))
|
||||
((* endblock markdowncell *))
|
||||
|
||||
|
||||
% Custom definitions
|
||||
((* block definitions *))
|
||||
((( super() )))
|
||||
|
||||
% Pygments definitions
|
||||
((( resources.latex.pygments_definitions )))
|
||||
|
||||
% Exact colors from NB
|
||||
\definecolor{incolor}{rgb}{0.0, 0.0, 0.5}
|
||||
\definecolor{outcolor}{rgb}{0.545, 0.0, 0.0}
|
||||
|
||||
((* endblock definitions *))
|
||||
|
||||
%===============================================================================
|
||||
% Input
|
||||
%===============================================================================
|
||||
|
||||
((* block input scoped *))
|
||||
%\noindent\rule[0.5ex]{\linewidth}{1pt}
|
||||
((*- if resources.global_content_filter.include_input_prompt *))
|
||||
((( add_prompt(cell.source | highlight_code(strip_verbatim=True, metadata=cell.metadata), cell, 'in :', 'incolor') )))
|
||||
((* endif *))
|
||||
((* endblock input *))
|
||||
|
||||
|
||||
%===============================================================================
|
||||
% Output
|
||||
%===============================================================================
|
||||
|
||||
((* block execute_result scoped *))
|
||||
%\noindent\rule[1.0ex]{\linewidth}{1pt}
|
||||
% Output:
|
||||
((*- for type in output.data | filter_data_type -*))
|
||||
((*- if resources.global_content_filter.include_output_prompt -*))
|
||||
((*- if type in ['text/plain'] *))
|
||||
((( add_prompt(output.data['text/plain'] | escape_latex, cell, 'out:', 'outcolor') )))
|
||||
((* else -*))
|
||||
\texttt{\color{outcolor}out:[{\color{outcolor}((( cell.execution_count )))}]:}((( super() )))
|
||||
((*- endif -*))
|
||||
((*- endif -*))
|
||||
((*- endfor -*))
|
||||
((* endblock execute_result *))
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% Support Macros
|
||||
%==============================================================================
|
||||
|
||||
% Name: draw_prompt
|
||||
% Purpose: Renders an output/input prompt
|
||||
((* macro add_prompt(text, cell, prompt, prompt_color) -*))
|
||||
((*- if cell.execution_count is defined -*))
|
||||
((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*))
|
||||
((*- else -*))
|
||||
((*- set execution_count = " " -*))
|
||||
((*- endif -*))
|
||||
((*- set indention = " " -*))
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
((( text )))
|
||||
\end{Verbatim}
|
||||
((*- endmacro *))
|
||||
|
Loading…
Reference in New Issue
Block a user