{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# How close is close enough?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is based on [Greg Wilson's post on testing](http://software-carpentry.org/blog/2014/10/why-we-dont-teach-testing.html), but avoids the big, difficult questions. Instead I focus on his comment about \"close enough\" in [the full phugoid model notebook](http://nbviewer.ipython.org/github/numerical-mooc/numerical-mooc/blob/master/lessons/01_phugoid/01_03_PhugoidFullModel.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See also [this page from NASA on grid convergence](http://www.grc.nasa.gov/WWW/wind/valid/tutorial/spatconv.html). Also [this paper by Liu](http://ocw.mit.edu/courses/mathematics/18-304-undergraduate-seminar-in-discrete-mathematics-spring-2006/projects/xtrpltn_liu_xpnd.pdf), which is rather mathematical, on Richardson extrapolation and its extensions." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Round off" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by reminding ourselves how round-off error comes in to numerical calculations. As an example, remember that $\\sin(2\\pi) = 0$, and in fact $\\sin(2 k \\pi)=0$ for any integer $k$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll use `numpy` for the calculations." ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib notebook\n", "import numpy\n", "from matplotlib import pyplot\n", "from numpy import pi, sin, arange" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sin(2 k pi) evaluates to 0 when k=0.\n", "sin(2 k pi) evaluates to -2.45e-16 when k=1.\n", "sin(2 k pi) evaluates to -4.9e-16 when k=2.\n", "sin(2 k pi) evaluates to -7.35e-16 when k=3.\n", "sin(2 k pi) evaluates to -9.8e-16 when k=4.\n", "sin(2 k pi) evaluates to -1.22e-15 when k=5.\n", "sin(2 k pi) evaluates to -1.47e-15 when k=6.\n", "sin(2 k pi) evaluates to -1.71e-15 when k=7.\n", "sin(2 k pi) evaluates to -1.96e-15 when k=8.\n", "sin(2 k pi) evaluates to -2.2e-15 when k=9.\n", "Adding these all up (result should be 0) we get -1.1021821192326179e-14.\n" ] } ], "source": [ "ks = arange(10)\n", "sins = sin(2.0*ks*pi)\n", "for k, s in zip(ks, sins):\n", " print(\"sin(2 k pi) evaluates to {:.3g} when k={}.\".format(s, k))\n", "print(\"Adding these all up (result should be 0) we get {}.\".format(sins.sum()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So we had ten different numerical calculations with errors between $0$ and $\\sim 2 \\times 10^{-15}$, which when combined lead to a total error $\\sim 10^{-14}$. This illustrates the standard result:\n", "\n", "Summing $N$ calculations with errors $\\delta_i$, where $\\delta_i \\le \\delta = \\max_i \\delta_i$, leads to a total error ${\\cal E}$ which is bounded by ${\\cal E} \\le N \\delta$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Going beyond sums" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll use a very simple initial value problem (as the calculations are faster):\n", "\n", "$$\n", "\\begin{equation}\n", " y' = -\\sin(x), \\qquad y(0) = 1\n", "\\end{equation}\n", "$$\n", "\n", "which has the solution $y = \\cos(x)$. We'll solve this using Euler's method, as in the original notebook:\n", "\n", "$$\n", "\\begin{equation}\n", " y_{n+1} = y_n - h \\sin(x_n), \\qquad y_0 = 1\n", "\\end{equation}\n", "$$\n", "\n", "where $h$ is the grid spacing and $x_n = n h$, with $n = 0, 1, \\dots$ the grid step." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def simple_euler(h, N):\n", " \"\"\"\n", " Solve the problem y' = -sin(x), y(0) = 1 using Euler's method.\n", " \n", " Parameters\n", " ----------\n", " \n", " h : float\n", " Grid spacing\n", " N : int\n", " Number of steps\n", " \n", " Returns\n", " -------\n", " \n", " Y : float\n", " y(Nh) as approximated by Euler's method\n", " \"\"\"\n", " \n", " # Initial data\n", " Y = 1.0\n", " x = 0.0\n", " for n in range(N):\n", " Y -= h*sin(x)\n", " x += h\n", " \n", " return Y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So, how good is this method? Check by comparing against the exact solution when $X=1$." ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [], "source": [ "X = 1.0\n", "N_all = numpy.array([2**i for i in range(3, 20)])\n", "h_all = X / N_all\n", "Y_exact = numpy.cos(X)\n", "Y_approx = numpy.zeros_like(h_all)\n", "Y_errors = numpy.zeros_like(h_all)\n", "for i, N in enumerate(N_all):\n", " h = h_all[i]\n", " Y_approx[i] = simple_euler(h, N)\n", " Y_errors[i] = numpy.abs(Y_approx[i] - Y_exact)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " fig.waiting = false;\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " this.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width);\n", " canvas.attr('height', height);\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Close figure', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": [ "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\n", "/j8XRzJ3qfdd2AAAAABJRU5ErkJggg==\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "simple_p = numpy.polyfit(numpy.log(h_all), numpy.log(Y_errors), 1)\n", "pyplot.loglog(h_all, Y_errors, 'kx', label='Data')\n", "pyplot.loglog(h_all, numpy.exp(simple_p[1])*h_all**(simple_p[0]), 'b-', label='Fit, slope={:.4f}'.format(simple_p[0]))\n", "pyplot.legend(loc='upper left')\n", "pyplot.xlabel(r'$h$')\n", "pyplot.ylabel('Error');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So, the best fit line matches the expected slope (1) to better than $0.3\\%$. Is this good enough?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, let's do a sanity check. Why do we believe that the slope shouldn't be *exactly* $1$? It's because of our assumption: that $\\text{Error} \\propto h + {\\cal O}(h^2)$, and that we could ignore the higher order terms. The assumption that the error takes this form is essentially saying that we've implemented the algorithm correctly (which is what we're trying to check!). The assumption that we can ignore the higher order terms is more reasonable when $h$ is small, like $10^{-5}$, but not when $h \\sim 10^{-1}$. So the slope should get closer to $1$ if we ignore the results for larger $h$. Let's do that calculation:" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The slope, when ignoring 2 entries, is 1.000313. (slope-1)=0.0003133\n", "The slope, when ignoring 3 entries, is 1.000176. (slope-1)=0.0001758\n", "The slope, when ignoring 4 entries, is 1.000099. (slope-1)=9.92e-05\n", "The slope, when ignoring 5 entries, is 1.000056. (slope-1)=5.638e-05\n", "The slope, when ignoring 6 entries, is 1.000032. (slope-1)=3.23e-05\n", "The slope, when ignoring 7 entries, is 1.000019. (slope-1)=1.867e-05\n", "The slope, when ignoring 8 entries, is 1.000011. (slope-1)=1.09e-05\n", "The slope, when ignoring 9 entries, is 1.000006. (slope-1)=6.439e-06\n", "The slope, when ignoring 10 entries, is 1.000004. (slope-1)=3.851e-06\n", "The slope, when ignoring 11 entries, is 1.000002. (slope-1)=2.336e-06\n", "The slope, when ignoring 12 entries, is 1.000001. (slope-1)=1.439e-06\n", "The slope, when ignoring 13 entries, is 1.000001. (slope-1)=9.026e-07\n", "The slope, when ignoring 14 entries, is 1.000001. (slope-1)=5.777e-07\n", "The slope, when ignoring 15 entries, is 1.000000. (slope-1)=3.79e-07\n" ] } ], "source": [ "for i in range(1, len(Y_errors)-2):\n", " partial_p = numpy.polyfit(numpy.log(h_all[i:]), numpy.log(Y_errors[i:]), 1)\n", " print(\"The slope, when ignoring {} entries, is {:.6f}. (slope-1)={:.4g}\".format(i+1, partial_p[0], partial_p[0]-1.0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's good news. We could just fit the final few entries to get closer to the expected slope, but we're still not answering how close is \"close enough\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One additional question that is quite important. What's the effect of changing how far we integrate, by changing $X$? Let's make $X$ smaller." ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false }, "outputs": [], "source": [ "X = 1.0e-5\n", "h_all = X / N_all\n", "Y_exact_short = numpy.cos(X)\n", "Y_approx_short = numpy.zeros_like(h_all)\n", "Y_errors_short = numpy.zeros_like(h_all)\n", "for i, N in enumerate(N_all):\n", " h = h_all[i]\n", " Y_approx_short[i] = simple_euler(h, N)\n", " Y_errors_short[i] = numpy.abs(Y_approx_short[i] - Y_exact_short)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " fig.waiting = false;\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " this.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width);\n", " canvas.attr('height', height);\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Close figure', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": [ "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\n", "AQAAAABJRU5ErkJggg==\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "floating_error_step = numpy.spacing(1.0e-3)\n", "floating_error = floating_error_step * N_all\n", "pyplot.loglog(h_all, Y_errors_short, 'kx', label='Data')\n", "pyplot.loglog(h_all, floating_error, 'b-', label='Floating point error contribution')\n", "pyplot.legend(loc='upper left')\n", "pyplot.xlabel(r'$h$')\n", "pyplot.ylabel('Error');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check the truncation error instead. First, redo the analysis to find out *exactly* what that should look like." ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import sympy\n", "sympy.init_printing()\n", "y = sympy.Function('y')\n", "f = sympy.Function('f')\n", "x, h, b= sympy.symbols('x, h, b')\n", "y_n_p_1 = y(x) + h * f(x, y(x))" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "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\n", "AwoAAAAASUVORK5CYII=\n" ], "text/latex": [ "$$\\frac{h^{2}}{2} \\left. \\frac{d^{2}}{d x^{2}} y{\\left (x \\right )} \\right|_{\\substack{ x=0 }} + \\frac{h^{3}}{6} \\left. \\frac{d^{3}}{d x^{3}} y{\\left (x \\right )} \\right|_{\\substack{ x=0 }} + \\frac{h^{4}}{24} \\left. \\frac{d^{4}}{d x^{4}} y{\\left (x \\right )} \\right|_{\\substack{ x=0 }} + \\frac{h^{5}}{120} \\left. \\frac{d^{5}}{d x^{5}} y{\\left (x \\right )} \\right|_{\\substack{ x=0 }} + \\mathcal{O}\\left(h^{6}\\right)$$" ], "text/plain": [ " ⎛ 2 ⎞│ ⎛ 3 ⎞│ ⎛ 4 ⎞│ ⎛ 5 ⎞│\n", " 2 ⎜ d ⎟│ 3 ⎜ d ⎟│ 4 ⎜ d ⎟│ 5 ⎜ d ⎟│\n", "h ⋅⎜───(y(x))⎟│ h ⋅⎜───(y(x))⎟│ h ⋅⎜───(y(x))⎟│ h ⋅⎜───(y(x))⎟│\n", " ⎜ 2 ⎟│ ⎜ 3 ⎟│ ⎜ 4 ⎟│ ⎜ 5 ⎟│\n", " ⎝dx ⎠│x=0 ⎝dx ⎠│x=0 ⎝dx ⎠│x=0 ⎝dx ⎠│\n", "────────────────── + ────────────────── + ────────────────── + ───────────────\n", " 2 6 24 120 \n", "\n", " \n", " \n", " \n", " \n", "x=0 ⎛ 6⎞\n", "─── + O⎝h ⎠\n", " " ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "truncation_error = sympy.series(y(h),h)-y_n_p_1.subs(x, 0)\n", "truncation_error = truncation_error.subs(f(0, y(0)), sympy.Subs(sympy.Derivative(y(x), x),(x,),(0,)))\n", "truncation_error" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So the truncation error should be the sum of each of these terms: for $h$ sufficiently small the higher order terms should have no effect at all. We can check, using that the derivatives of $\\cos(x)$ at $x=0$ are alternatively $1$ and $0$ in magnitude:" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [], "source": [ "h_truncation = numpy.array([2**(-i) for i in range(4,20)])\n", "Y_truncation_error = numpy.zeros_like(h_truncation)\n", "Y_expected_truncation_error = numpy.zeros_like(h_truncation)\n", "for i, h in enumerate(h_truncation):\n", " Y_truncation_error[i] = numpy.abs(simple_euler(h, 1) - numpy.cos(h))\n", " Y_expected_truncation_error[i] = h**2/2.0 - h**4/24.0 + h**6/720.0 - h**8/40320." ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " fig.waiting = false;\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " this.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width);\n", " canvas.attr('height', height);\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Close figure', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": [ "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\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig=pyplot.figure(figsize=(8,6))\n", "ax1=fig.add_subplot(111)\n", "ax1.loglog(h_all[1:], Y_errors[1:], 'bo', label='Data errors')\n", "ax1.set_xscale(\"log\", nonposx='clip')\n", "ax1.set_yscale(\"log\", nonposy='clip')\n", "ax1.errorbar(h_all[1:], numpy.abs(Y_exact - Y_richardson[1:]), yerr=Y_richardson_error[1:], \n", " lolims=True, marker='x', color='k', ls='None', label='Richardson extrapolation and error estimate')\n", "ax1.legend(loc='lower right')\n", "ax1.set_xlabel(r'$h$')\n", "ax1.set_ylabel('Error');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see that the error bar found from Richardson extrapolation pretty much matches up with the error in the original calculation, as expected. So, using the two best results (i.e., those with the highest resolution, or smallest $h$) we can say that" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "y(1) = 0.5403023058678328 ± 8.024897067970826e-07.\n" ] } ], "source": [ "print(\"y(1) = {} ± {}.\".format(Y_richardson[-1], Y_richardson_error[-1]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, this analysis is all based on the *assumption* that the error is exactly proportional to $h$. We know this isn't true; we're neglecting higher order terms. We see this because we measure a convergence rate that isn't exactly $1$. So we need a different model for the behaviour of our algorithm. We could add more terms to the error (as expected), but this leads to more parameters to fit, which is bad ([\"with four parameters I can fit an elephant\"](http://en.wikiquote.org/wiki/John_von_Neumann) and so on). Instead we keep a single error term, but write $y(X) = y^{(h)} + C h^s$ where $s$ is measured from the data (above we have $1.0006$). This leads to the Richardson extrapolation formulas\n", "\n", "$$\n", "\\begin{equation}\n", " y(X) = \\frac{2^s y^{(h)} - y^{(2h)}}{2^s - 1}, \\qquad C h = \\frac{y^{(2h)} - y^{(h)}}{2^s - 1}.\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Applying this assumption to the data, we get a new set of error bars:" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "y(1) = 0.5403023064917923 ± 8.018657471901381e-07.\n", "Difference between predicted exact values is 6.24e-10.\n" ] } ], "source": [ "Y_richardson_measured_s = numpy.zeros_like(Y_approx)\n", "Y_richardson_error_measured_s = numpy.zeros_like(Y_approx)\n", "for i in range(1, len(h_all)):\n", " Y_richardson_measured_s[i] = (2.0**(simple_p[0])*Y_approx[i] - Y_approx[i-1])/(2.0**(simple_p[0])-1.0)\n", " Y_richardson_error_measured_s[i] = abs(Y_approx[i-1] - Y_approx[i])/(2.0**(simple_p[0])-1.0)\n", "print(\"y(1) = {} ± {}.\".format(Y_richardson_measured_s[-1], Y_richardson_error_measured_s[-1]))\n", "print(\"Difference between predicted exact values is {:.4g}.\".format(abs(Y_richardson[-1]-Y_richardson_measured_s[-1])))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You have to look quite hard to see the difference. But the key point here is that the two exact values predicted by the different assumptions lie within each other's error bars." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's repeat this analysis using the data from the phugoid problem sheet. In this case we have a more complex system, a longer integration error (leading to a larger error), worse resolution (leading to a larger error), fewer data points, and no knowledge of the exact solution. However, we are still using Euler's method, so we expect the same behaviour for the error.\n", "\n", "I explicitly give the values of the errors here rather than the code, to save time. I modified the range of values considered to\n", "\n", "`dt_values = numpy.array([0.1*2**(-i) for i in range(8)])`\n", "\n", "to ensure that nice factor 2 between each resolution. I then computed the differences between each using the `get_diffgrid` function, and did the best fit line getting a slope of $1.21154575$ with the data below:" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Phugoid limit, standard assumption = -0.14430451 ± 0.28648019.\n", "Phugoid limit, measured slope = -0.07553820347702735 ± 0.21771388347702736.\n", "Difference between predicted limits is 0.06877.\n" ] } ], "source": [ "dt_values = numpy.array([ 0.1, 0.05, 0.025, 0.0125, 0.00625, 0.003125, 0.0015625])\n", "diffgrid = numpy.array([ 25.4562819, 10.52418949, 4.75647465, 2.20894037, 1.01024986, 0.42865587, 0.14217568])\n", "s = 1.21154575\n", "\n", "Y_richardson_phugoid = numpy.zeros_like(diffgrid)\n", "Y_richardson_phugoid_error = numpy.zeros_like(diffgrid)\n", "Y_richardson_phugoid_measured_s = numpy.zeros_like(diffgrid)\n", "Y_richardson_phugoid_error_measured_s = numpy.zeros_like(diffgrid)\n", "for i in range(1, len(diffgrid)):\n", " Y_richardson_phugoid[i] = (2.0*diffgrid[i] - diffgrid[i-1])\n", " Y_richardson_phugoid_measured_s[i] = (2.0**(s)*diffgrid[i] - diffgrid[i-1])/(2.0**(s)-1.0)\n", " Y_richardson_phugoid_error[i] = abs(diffgrid[i-1] - diffgrid[i])\n", " Y_richardson_phugoid_error_measured_s[i] = abs(diffgrid[i-1] - diffgrid[i])/(2.0**(s)-1.0)\n", "print(\"Phugoid limit, standard assumption = {} ± {}.\".format(Y_richardson_phugoid[-1], Y_richardson_phugoid_error[-1]))\n", "print(\"Phugoid limit, measured slope = {} ± {}.\".format(Y_richardson_phugoid_measured_s[-1], Y_richardson_phugoid_error_measured_s[-1]))\n", "print(\"Difference between predicted limits is {:.4g}.\".format(abs(Y_richardson_phugoid[-1]-Y_richardson_phugoid_measured_s[-1])))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see the errors are much larger, but that the difference between the limiting values is within the predicted error bars of either result. Therefore the assumption that the algorithm is behaving as the idealized Euler's method does is *close enough* that the predicted result lies within the predicted error bars." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So how close *is* close enough? We need \n", "\n", "$$\n", "\\begin{equation}\n", "\\left| \\frac{2^s y^{(h)} - y^{(2h)}}{2^s - 1} - \\left( 2 y^{(h)} - y^{(2h)} \\right) \\right| \\le \\left| \\frac{y^{(2h)} - y^{(h)}}{2^s - 1} \\right|.\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAAEoAAAAyBAMAAAAJj1DuAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUMhCrzbsidkTd\n", "mWY9FFLYAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACF0lEQVQ4Ec1VMUgbYRT+TO5MLhfFokhBoSGT\n", "tISeW5fiCdG1p4iTQxeHomBwdYggiFsPnQQtxam4GBfnrApqxi6BjiooKkqLtj3fu/+8eJczf1zE\n", "N/z/97/38b2X+y/f4Y1zicbx3rlAZ34ogvRN5I55G8v3o4v24VmR9FdtHlq2z0Cr7aYGXZba7dcF\n", "SNhYR/w/1MIDFhZDrFNgy8Bf4G0j1i6wXVJ/AyMNWFqZi9QRiRIjMRd3HN18B+zkTn5QNlXh2kQG\n", "aHORz1J2kfyuX+MgRfXkL1qW9y2gvUCoppXOQLlqLWOas2mD11gPdS0z8rU+UeGyrUOwWkpcwysL\n", "yjkDnzVAhT/aldrJWWatAl+NMIu1/mkbGyazuKNjMUsv89nXaqlAv42TBgdP/xo4tIPTL0HpQiKj\n", "z+VtZsUqwBniN/QkMnwWWsPOF6xnp4Cic0EEt49e/UnKCbPGYsSRNNSVPQZ0QyLW3M2by8t9oP2I\n", "Md22iMBte7kJE1hgnHTHQ+jN8VhqdjNHRECb59VnBzuKEq8P3+j731irRqPHtILsp7CcBnFOsk/R\n", "Ck5Rf3oOrainGukT1SVT7hPjiN2GbjvCJybpPyT3iV5gxpT6RNFiltwncGjJfQI6GW57gW/Ce/aL\n", "SNf7RPpzMz5RJRWZTwgTC7HqfAIfodlSn1AqSMl9Yi2bI8eT+UTRccjJX7pPNPfla+oregc/H9zN\n", "KHSIrgAAAABJRU5ErkJggg==\n" ], "text/latex": [ "$$\\left [ \\frac{\\log{\\left (3 \\right )}}{\\log{\\left (2 \\right )}}\\right ]$$" ], "text/plain": [ "⎡log(3)⎤\n", "⎢──────⎥\n", "⎣log(2)⎦" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "yh, y2h, s = sympy.symbols('y^h, y^{2h}, s')\n", "Eq1 = sympy.Eq((2**s*yh-y2h)/(2**s-1)-(2*yh-y2h) , (y2h-yh)/(2**s-1))\n", "sympy.solve(Eq1, s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There's another root to check:" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAUBAMAAABCNWFYAAAAG1BMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAB4Gco9AAAACHRSTlMAdt3NMolEZgN4ymIAAAAJcEhZcwAADsQAAA7EAZUrDhsA\n", "AAAXSURBVAgdYxAyKVZjCGMAIpoQQipCagCy4Q1mVUJFwQAAAABJRU5ErkJggg==\n" ], "text/latex": [ "$$\\left [ \\right ]$$" ], "text/plain": [ "[]" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Eq2 = sympy.Eq((2**s*yh-y2h)/(2**s-1)-(2*yh-y2h) , -(y2h-yh)/(2**s-1))\n", "sympy.solve(Eq2, s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So the threshold is $s = \\log(3)/\\log(2) \\simeq 1.585$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But there's also the other interval, for which we need\n", "\n", "$$\n", "\\begin{equation}\n", "\\left| \\frac{2^s y^{(h)} - y^{(2h)}}{2^s - 1} - \\left( 2 y^{(h)} - y^{(2h)} \\right) \\right| \\le \\left| y^{(2h)} - y^{(h)} \\right|.\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAUBAMAAABCNWFYAAAAG1BMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAB4Gco9AAAACHRSTlMAdt3NMolEZgN4ymIAAAAJcEhZcwAADsQAAA7EAZUrDhsA\n", "AAAXSURBVAgdYxAyKVZjCGMAIpoQQipCagCy4Q1mVUJFwQAAAABJRU5ErkJggg==\n" ], "text/latex": [ "$$\\left [ \\right ]$$" ], "text/plain": [ "[]" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Eq3 = sympy.Eq((2**s*yh-y2h)/(2**s-1)-(2*yh-y2h) , (y2h-yh))\n", "sympy.solve(Eq3, s)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAAH4AAAAyBAMAAABol3KsAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUMhDN3auZdmYi\n", "u0S/dLA5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACb0lEQVRIDc2XP2gUQRTGv9zt3iXn3qIkoI3m\n", "uEI4Qd2UCuIKJ6RzFSEWFsHiTOWdjaIGYiMhIOZKrxAkZUCS1n+waBGCFoKNTXDtLJMQFRWzvrdz\n", "e56b2+xkh6CvmHlz8347b2dn5pvDsL+OtHbcX8Ng9eyO8Dci+gVXF6sjGNqWHr0S6TbewSgftdDv\n", "Bh1nEnj9QITPuVhG9if0cSkeHyL8U2DBwjfgSDp+Evjk6V+B86l4o8EY5Y+cx17S+3P+F+aPAZ8r\n", "z55QfKHJ1FgJGAg8CV6bRPGx+QV3CkQWF6l4dcsB9oyTJzN+vgRto7+BaY7PW1xmDtE7NNiTGP8c\n", "IesDewXf5zGFfQ60VXYk+NMe8MvY0Ac5nvm3wEdLnufxvxtzczbhQf6+w7wpm39fE+Zm1mNazN9B\n", "YMqVnb8VaEPIlcxrVZf5TBN4juwP+n4lbie9/6h/H8vlB0DdXyM0yNpsPfJo/djUTOQ5hq1o6a9v\n", "s0PrV9hSUEXGH3HC7kh9itov+TfaP8J67B99ZjbkT4Zh7XrMBt6zX3S5RMz+XYjj9fJ8xWaOzo/A\n", "2s+J5B/LC4jL7vNry/xJ8H+exN7Ox98FXr96k+yGTUdbMH+Ha7XrtdoEj+RvY6vU/1/kz4kK+8fz\n", "/3B4YlEkEl2/YYIJ66cTFvI99a+1Yifp3+X2k3rp3yVkNmP2T2f8jtND/+7R+auif/uBWVtB/+oO\n", "8yr6hylHRf9g0pVJRf/yd9X0r0WfJ73+iUuANL9F/3AChqugf1oTBRX9WypX6C6RXv/qvk/3t13R\n", "v862iTpS+heFutqS+tdF/O3G65/q/V3x/8NvxZH3UA+6zV0AAAAASUVORK5CYII=\n" ], "text/latex": [ "$$\\left [ -1 + \\frac{\\log{\\left (3 \\right )}}{\\log{\\left (2 \\right )}}\\right ]$$" ], "text/plain": [ "⎡ log(3)⎤\n", "⎢-1 + ──────⎥\n", "⎣ log(2)⎦" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Eq4 = sympy.Eq((2**s*yh-y2h)/(2**s-1)-(2*yh-y2h) , -(y2h-yh))\n", "sympy.solve(Eq4, s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This gives the lower bound of $\\simeq 0.585$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is very specific to Euler's method. What if we're using a better method with convergence rate $s_e$, so that the idealized behaviour of the algorithm is $y(X) = y^{(h)} + C h^{s_e}$? In that case, if we measure a convergence rate of $s_m$, then the results are close enough when\n", "\n", "$$\n", "\\begin{equation}\n", "\\left| \\frac{2^{s_e} y^{(h)} - y^{(2h)}}{2^{s_e} - 1} - \\frac{2^{s_m} y^{(h)} - y^{(2h)}}{2^{s_m} - 1} \\right| \\le \\left| \\frac{y^{(2h)} - y^{(h)}}{2^{s_e} - 1} \\right|\n", "\\end{equation}\n", "$$\n", "\n", "and\n", "\n", "$$\n", "\\begin{equation}\n", "\\left| \\frac{2^{s_e} y^{(h)} - y^{(2h)}}{2^{s_e} - 1} - \\frac{2^{s_m} y^{(h)} - y^{(2h)}}{2^{s_m} - 1} \\right| \\le \\left| \\frac{y^{(2h)} - y^{(h)}}{2^{s_m} - 1} \\right| .\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAAJkAAAA/BAMAAAABN3d6AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMARM1UEDKrie+7Inbd\n", "mWYDwv/QAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADw0lEQVRYCe2YTWgTQRTH//lsssmGguC1tSge\n", "PDRQDwqWBoXqQTAIFj0UI3gQFY14yEGC8RMPHgKi0JMLnpTW1lPRIuTgB1SxEaTiodKDKCoWqy1V\n", "UdZ5szubTXZ38tEc+w4zb9/Hb9/Mzm4eQZeud6MdclvXk+jq6+tsBwzr+gYYrSnUfll0xJMWci14\n", "+KQbbcI0etMOOdIyZNnhMDPDetPoTdvoSCuSxZXWMU8uwJOmiuo7ppJGKLxpeGKECNrQZjNFTOMp\n", "YOzdTeB1iFOYXUJ7bKQJWvCqwJhzHghmcL4TI1tTpsmdFrjM3ONGiKDhlpkipktAOIVIAUN6mmzh\n", "np6LPVuc+zY4u8S88XmKqexbDS3EYiIlhJcDWngCnxYo1r22GNFU7vOkJQqAf4nR4mk1nSiqFm0b\n", "aXbhtFiBm+wr3T11hh2d/NeHzKN2c3d8KbHwAP6zH+iK7j82c4I7KgOn+ajAqpWGphGdYOZXMWaP\n", "GqV3ZSkoqgVpMkyk2YXTQsvcZKstnkVoOVwCf3f8Ge5+xkflfWXfuME+cJqyyE022uEksKIWDFq8\n", "TG6VjyJXEwqw8yXJJjIYtJ/cZ6MNdAK/leUgOxvsCWRoNA8lqZ4iqe2fMjmZpkROC5Rxz5MiHMa+\n", "/eGXttoiZfgWA6xAknCRDcPAI34lGzit9pmOIHQF/qxvwwGNcukAKc9zsyW6kAqn0fFkImob0o9j\n", "LHcE6NV/lZmdbubXdb1EQTJRj/045XwXzIxoMnjnBekXZAiHzz/BTaI24d/OlM908VZYGpr3pXhY\n", "LW1vGrhBnoPc3ejw0QispQVzU3kGZA812SiJ4p4awbU0CxHsttT6SiJrxHjS0F8fYkXcNTVvmjjH\n", "VopEeVOXJkn2dHnX5pkicQgaO/arFXYXQZPcsAnXGs11s+4b1i+uTjJK9s3R6ChFKHMjaYQ1L5yE\n", "5mh0/BoG0bEI71dYQnM0Ot+Ao8A14FwLtTlo08B14HQae9pAU0rsVyNFNH+nB67OSu2NTqzMGTOp\n", "mhbARpbTqhudecrzrQCJbtJcRE6ranTi/NsezwCBkguJTHJaVaMT4bs1x5JC31uiVTU6nMY3r0Ua\n", "1WY1Onyl/VA0+Eot1VbV6ETn2RrLiGmtPYWaRqejDIzm8qz1VLPN1+ZodNj6enX9L2t30s3TRIbV\n", "6LA3y5BRodTOshNixlqNDnvrDWnprTdzrUYnqhmW1r5IJs1qdNjXkougmn7b1MBKK9Gr+ZJXKA1r\n", "TdVWl7pGq7tFrgG0b239V2pX+/6V6tP+A/XNQ3RzkyOMAAAAAElFTkSuQmCC\n" ], "text/latex": [ "$$\\left [ \\frac{\\log{\\left (2^{s_{e} + 1} - 1 \\right )}}{\\log{\\left (2 \\right )}}\\right ]$$" ], "text/plain": [ "⎡ ⎛ sₑ + 1 ⎞⎤\n", "⎢log⎝2 - 1⎠⎥\n", "⎢────────────────⎥\n", "⎣ log(2) ⎦" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "yh, y2h, se, sm = sympy.symbols('y^h, y^{2h}, s_e, s_m')\n", "Eq5 = sympy.Eq((2**sm*yh-y2h)/(2**sm-1)-(2**se*yh-y2h)/(2**se-1) , (y2h-yh)/(2**sm-1))\n", "sympy.solve(Eq5, sm)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAAIkAAAA/BAMAAAAmmfaSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMARM1UEDKrie+7Inbd\n", "mWYDwv/QAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAD40lEQVRYCe2YTUhUURSAz+j8z5tpQKpdTla4\n", "KHBgNgmZD4JsITEISS3EKVpZkK2EYsSKokWQUAQG0YO2mi4CCze2NdBZBOFCcFcmiYJiRfE659z7\n", "3ryfueNMugm6i3vPPefc751773vnDAPNppmB3bSXppmF5lwuXQVyaLWKkU1NuU6kqL2KL3QYOF/Z\n", "3uNQR5WUUBoiRjgDfccgNbzsWCLEvus4JqRaTbkEoBmhnxGjC1ag5KPAKVQFCkKvphxFSjq+kVp7\n", "A62ndeHt7IkCw0KjpCSnyKFxk/rnoNPgbkzRdFZalN5Wtw9Msl1j1sTasseKU6YkxFYtSvCBx6/I\n", "c9F7TGLKlPg6TywKPPO43qN5SjzKYWrk4EjBFJhnm4oS4gM5CPsdBBK9lMWqlNQImkNHck/Zq9yV\n", "KSdZ+ZZ7ZyxdMzcBDhRX36ElmcEuappi3+zKnU2ZWLhGimadegclNAexqcAmzNMbGRslq7/ZFGnq\n", "z5PgoGiDENoKzwK92tBQoN7fvJTJNPk4KP1ZgO3kiKBoJTSajraO80hLy4m7LS0FFPeRCcdJXOSi\n", "dKYBfsS3gnzHu4rld3x6Ok/0MoWyQ7nZO4osfiRtv0G9Y0fREgQ2GjEgauFRMYrsIGUcbMotuEJa\n", "zx2NQeg+NAwGDl8wyJoYoR4bZQchcW9T5kQYX1hrxdJrDsDE0GWANvN7CS1446JRdpAiDTblPfD1\n", "eN5d6RnLBl99IPmOVFjZQU5tCkCnjrrjrLdikU7QjsIKTT5ZGtCmbBEgaNgTelhQhOyldOcBnpDj\n", "RdtbkR0itPFUgd28lODQTBFBeElZtlfKDsLwjQaNfcs3LdfYQzAjRX92YENgMICEz8LJG4tcikOH\n", "ECtkBzb05Np1iI8KJzVFvn8VsgOvfEyfUVLfiSLstfXqWGpb747FkQPqFRG0t7HUE7/f95+M5bXY\n", "x1f/dlCj2JGv+ONbGl8ay0PYqIRRUHzFv8GAsxDZAPvzcsEUFF/xxy/4KsBDgNuu5XJSK2UO4BHA\n", "jTyc2wUlPosZWSdKQ7oCpkoszuKfKPHaBR2SQnKj1BR38V+mZYFtTH0ZkjxNTXEVfy1L67QCVoRZ\n", "kjxNTXEV/yifxhIuDq17CDRVU1zFnyl8OHVSKBa7+POOOiBuQGC2rliizuIfW8a9lCBh1He6nuJP\n", "JWx8qIg/s5KDtcfiK/64jzbT/IU/bPK1UyxPu/jjFyDauCU4R9UdSR+7+HM9JWVdX6OkdGP8XPxj\n", "htDUlxkkxS7+mKW4WTRpl8MOOyo7/03GLK+uSao5lqq0/5TKx0Pnsif/Vpyp/m9F5ac7tU25nPEH\n", "mzNHZ8UJAgUAAAAASUVORK5CYII=\n" ], "text/latex": [ "$$\\left [ \\frac{\\log{\\left (\\frac{2^{s_{e}}}{2} + \\frac{1}{2} \\right )}}{\\log{\\left (2 \\right )}}\\right ]$$" ], "text/plain": [ "⎡ ⎛ sₑ ⎞⎤\n", "⎢ ⎜2 1⎟⎥\n", "⎢log⎜─── + ─⎟⎥\n", "⎢ ⎝ 2 2⎠⎥\n", "⎢────────────⎥\n", "⎣ log(2) ⎦" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Eq6 = sympy.Eq((2**sm*yh-y2h)/(2**sm-1)-(2**se*yh-y2h)/(2**se-1) , -(y2h-yh)/(2**se-1))\n", "sympy.solve(Eq6, sm)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So we can see how the bound changes with increased accuracy of the ideal algorithm:" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " fig.waiting = false;\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " this.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width);\n", " canvas.attr('height', height);\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Close figure', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": [ "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\n", "SUVORK5CYII=\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "r1 = r1.subs(v, 30.0)\n", "r2 = r2.subs(v, 30.0)\n", "sympy.plot(r1); " ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " fig.waiting = false;\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " this.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width);\n", " canvas.attr('height', height);\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Close figure', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": [ "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\n", "qgTCzkz4uZgAAAAASUVORK5CYII=\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "pyplot.loglog(h, D, 'bo', label = 'Difference')\n", "pyplot.loglog(h, h, 'r-', label = 'D = h model')\n", "pyplot.xlabel('h')\n", "pyplot.ylabel('Difference')\n", "pyplot.legend(loc='lower right');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So, despite being *completely inconsistent, and unstable*, the algorithm appears to behave correctly over **12** orders of magnitude: from $h \\sim 10^{-4}$ to $h \\sim 10^{8}$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In reality, the behaviour at the top end (large $h$) is not a concern. What's more important is how it behaves for small $h$. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's also noticeable that in the convergence check for the phugoid model, the behaviour was only checked over 2 orders of magnitude. So, should we be concerned?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the original phugoid model notebook the differences were computed over a fairly narrow range of $h$. If we modify that range, we can check the data in more detail." ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "collapsed": false }, "outputs": [], "source": [ "h_values = numpy.array([0.1*2**(-i) for i in range(-3,18)])\n", "differences = numpy.array([3.70456578e+04, 5.11556903e+02, 2.68347318e+02,\n", " 1.40645139e+02, 7.00473279e+01, 3.51807674e+01,\n", " 1.76241342e+01, 1.15159153e+00, 5.69993649e-01,\n", " 2.83511479e-01, 1.41334800e-01, 7.05107406e-02,\n", " 3.51645549e-02, 1.75078941e-02, 8.68366865e-03,\n", " 4.27258022e-03, 2.06729609e-03, 9.64716814e-04,\n", " 4.13441038e-04, 1.37809468e-04, 0.00000000e+00])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the final value is from the reference solution, so of course there's no information there." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we plot this on a loglog scale to see if it's roughly correct." ] }, { "cell_type": "code", "execution_count": 80, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " fig.waiting = false;\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " this.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width);\n", " canvas.attr('height', height);\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Close figure', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": [ "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\n", "JsGkqzmPsbpTZ8eP2+0dgHlXxd9OgkdNRgIGz9oA0CkEjw4HD4lnbQDoJlZbqZs5D4lnbQDoHnIe\n", "SVdHHuQ8AHQZ01bdDR6bJR0ZDRQpgGygZDqAthE8Oho8AKDLyHkAAFpB8AAAZKOqLgDMCarqJuQ8\n", "ACAfOQ8AQCsIHgCAbAQPAEA2ggcAIBvBAwCQjeABAMjGPg8AmBPs80jY5wEA+djnAQBoBcEDAJBt\n", "7oKH7c3jT/WzvTI9gwMAUMDcBQ9JRyTdNQwgI0/5O9JqrwCgR+YyYT4SMHZp8JxxHg8LYG7wJMES\n", "N8D2GkknJK2NiJMVdgsAOm3mV1vZfpHtb1edj0gjj+2S1kraPp4DAQAsrdPBQ9KHJO2v8oQjU1Y7\n", "0ohjh0ZyIPMsbSBCRbif1eJ+dkvtwcP2fbafsn1srH2T7cdsP2H79kU+9zpJj0h6uuIubdBIjiN9\n", "35Ha593GtjswYza23YEZs7HtDuC8JkYe90vaNNpge4WkPan9CklbbV9u+ybbn7D9cknXSvotSe+Q\n", "dIvtSnaSR8TB8eR4RJyNiIOTPrPc/3hyPjftvUu9vthrRdra+E+uzDWbuJ857fNyP6v+3Vysvejv\n", "cN36eD/b+t2sPXhExGFJPxxrvlrS8Yg4GRE/l7RP0paI2BsRt0XEkxHx4Yi4TdIXJd0T7Wb2Nzbw\n", "uWnvXer1xV4r0jbtmnUoc82cz05776TXc9rH26Zdsw5lrln0s9Pet9Trk14bb1/sfdOuW4cy1yz6\n", "2WnvW+r1xV4r0jbtmtkaWW2VVjYdiIgr0/FbJF0fEbek43dJWh8RH8g8b3+XigFAi8qutmqrqm4l\n", "f/QpiggA7WhrtdUZSatHjldLOt1SXwAAmdoKHt+RdJntNbYvlHSjpIda6gsAIFMTS3UfkHRU0jrb\n", "p2xvi4hzkm6VdEiD5bj7I+LRuvsCAKhGr8uTAADa0fUd5gCADprJ4OGBu2zvtv1Hbfen72xvtH3Y\n", "9qdsX9t2f/qurppt88j2K9Lv5Zdsv6ft/vSd7S2277G9L1X5mGgmg4ekP5S0StLPxCquKvxC0v9I\n", "ukjczypUXrNtXkXEYxHxfklvl3R92/3pu4j4+4h4r6T3abCQaaJOB4/l1sWStE7SkYj4M0nvb6Sz\n", "PVDifh6OiN+T9OeS7myksx3XwZptvVbid1O23yjpoAaVKqBy9zP5sAYlpCbqdPDQ8utinZY0rF/1\n", "iyY73HHLup8jpWHOajD6QMdqts2A5d5PRcSBiHiDpHc33ekOW9b9TFP+H5X0jxHx3aUu0NYO80Ii\n", "4nAqbTLq2bpYkmR7WBfrbkl7U9uXJX3S9jWSFprqb9eVuJ9v0mBKYKWkTzbV3y5b7r3U4D862X63\n", "pKdbrtnWGSV+N6+VdIOkiyV9o6n+dl2J+/lBSddJusT2pRHxmUnX6HTwmGCVpFMjx6clrR99Q0T8\n", "RNLNTXaqx4rcz69I+kqTneqpqfdyKCI+10iP+q3I7+Y3JX2zyU71WJH7uVvS7iIn6/q01WL4T61a\n", "3M/qcC+rxf2sVqX3s4/Bg7pY1eJ+Vod7WS3uZ7UqvZ99DB7UxaoW97M63MtqcT+rVen97HTwoC5W\n", "tbif1eFeVov7Wa0m7ie1rQAA2To98gAAdBPBAwCQjeABAMhG8AAAZCN4AACyETwAANkIHgCAbAQP\n", "oGJpB++x6e8E+ovgAQDIRvAA6rEiPQv6X2wfsn1x2x0CqkTwAOpxmaQ9EfFKDZ7A+OaW+wNUiuAB\n", "1ONERHwv/fywpDUt9gWoHMEDqMdPR35+Rv18aicwEcEDAJCN4AHUY/xZBzz7ADOF53kAALIx8gAA\n", "ZCN4AACyETwAANkIHgCAbAQPAEA2ggcAIBvBAwCQ7f8B5Mh4tdXb6EQAAAAASUVORK5CYII=\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "h_small = h_values[numpy.logical_and(h_values < 1e-2, h_values > 1e-6)]\n", "differences_small = differences[numpy.logical_and(h_values < 1e-2, h_values > 1e-6)]\n", "pyplot.loglog(h_small, differences_small, 'kx')\n", "pyplot.xlabel('h')\n", "pyplot.ylabel('Differences');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now do our standard thing: assume that this is perfectly modelled by $D(h) = a h^s$ and use linear regression (of $\\log(D)$ against $\\log(h)$) to find the parameters $a$ and $s$. First we'll do this using the entire dataset." ] }, { "cell_type": "code", "execution_count": 82, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The measured value of s is 1.052\n" ] } ], "source": [ "p_all = numpy.polyfit(numpy.log(h_small), numpy.log(differences_small), 1)\n", "print(\"The measured value of s is {:.3f}\".format(p_all[0]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So this is off by about 5%. Let's plot the line of best fit and see where the difference lies." ] }, { "cell_type": "code", "execution_count": 83, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " fig.waiting = false;\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " this.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width);\n", " canvas.attr('height', height);\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('