{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Symbolic solution of ODEs with sympy\n", "Intro to sympy variables in previous notebook." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import sympy as sym\n", "sym.init_printing() # for LaTeX formatted output\n", "\n", "import scipy as sp\n", "\n", "import matplotlib as mpl # As of July 2017 Bucknell computers use v. 2.x \n", "import matplotlib.pyplot as plt\n", "\n", "# Following is an Ipython magic command that puts figures in the notebook.\n", "# For figures in separate windows, comment out following line and uncomment\n", "# the next line\n", "# Must come before defaults are changed.\n", "%matplotlib notebook\n", "#%matplotlib\n", "\n", "# As of Aug. 2017 reverting to 1.x defaults.\n", "# In 2.x text.ustex requires dvipng, texlive-latex-extra, and texlive-fonts-recommended, \n", "# which don't seem to be universal\n", "# See https://stackoverflow.com/questions/38906356/error-running-matplotlib-in-latex-type1cm?\n", "mpl.style.use('classic')\n", " \n", "# M.L. modifications of matplotlib defaults using syntax of v.2.0 \n", "# More info at http://matplotlib.org/2.0.0/users/deflt_style_changes.html\n", "# Changes can also be put in matplotlibrc file, or effected using mpl.rcParams[]\n", "plt.rc('figure', figsize = (6, 4.5)) # Reduces overall size of figures\n", "plt.rc('axes', labelsize=16, titlesize=14)\n", "plt.rc('figure', autolayout = True) # Adjusts supblot parameters for new size" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "x = sym.symbols('x') \n", "f, g = sym.symbols('f g', cls=sym.Function)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAACUAAAAUBAMAAAD4luk4AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEJl2IquJVETdZu8y\nu83OyatpAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA/klEQVQYGVWQP04CURCHv5UFUdmVWBCNDQUH\n4M8FtoWGQmNjo6GiAhOtIfECFlhqiNBAywU4Ag09FzBZYyGFhb95uyE4ycz83vdm5u0OpNZK8zTJ\nZ/UIf5WybOTEzaBPmEjwNsa87Tl8mHLWsXgYK4zc2cKlhdwL+PLUwiEc376WyZQ1o3H9rMacJKdV\nCMZQYlZ9V81GrL2Eoz7c0ys+aryNGchPhlDkU4pCrNCVG4NvC46tJayXwq+xvPUu5PbGQyamlrzh\nbcX0AfmfIPZ1dXCn2i8xNXhXtfpcMlyqZCWx929NeArHxv7t4O3CEEHkUrKrScUddjvdXQrv7f4P\nZAkxRPkkmioAAAAASUVORK5CYII=\n", "text/latex": [ "$$f{\\left (x \\right )}$$" ], "text/plain": [ "f(x)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Define the differential equation as a sym.Eq()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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\nYII=\n", "text/latex": [ "$$f{\\left (x \\right )} - 2 \\frac{d}{d x} f{\\left (x \\right )} + \\frac{d^{2}}{d x^{2}} f{\\left (x \\right )} = \\sin{\\left (x \\right )}$$" ], "text/plain": [ " 2 \n", " d d \n", "f(x) - 2⋅──(f(x)) + ───(f(x)) = sin(x)\n", " dx 2 \n", " dx " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diffeq = sym.Eq(f(x).diff(x, x) - 2*f(x).diff(x) + f(x), sym.sin(x))\n", "diffeq" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Solve differential equation" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAASYAAAAqBAMAAADsX+smAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEJl2IquJVETdZu8y\nu83OyatpAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEdUlEQVRYCe1X3WscVRT/TfZj9mMyHdpaFGlZ\nsC3UD9wkNQ8V7VhErKGkpLVIK7iNUsxLs34h4kMWhIBUaMTUD0S7GBH0QQqK+CB2qX9A0mJfRHAR\niy3ouqm2DZJSz7kz987Mna0bggsL7nm493fP75x7fvdjZ2aBnuFVp9s2wRh7qus0ATt7mlZ0UXr7\ntKJt6t2nlW1Tb5/+J/uUrHoLzbnxBT8Wd93c83FApQe/ezIYCbTl9IWq5vKGWv21gy6wR0bul0D1\nyQWCxgOPH0yWlC8AOpFyFTeQqr+rBm2AVv/AVBn4ReZskkD1tkvw/irMu6rKFwCdMOqKq9lVhduB\naH1j6VYgV5BJ6aJEsv+IwMY3qbnXlS6YMkongKdVENbIhBcCX2uk1TebFJaV2TBO6Vmz5PjDoeZY\nwChNOgHcHkTNo+YN2mrS6qdnKG93MNHFAAqUJL7vGsMzASM1xQjArvhhyeYESh5uqylaP3foRAEY\npNx19z06XATGvWlUmyB6lHVjvfKpswsTxtD+1+jg0hQPbBjabOybHna8lJgmY+t4mWKehbVjrk4x\nWv01pAM/0C+rlHsrS/znNMTRBtvPDPurwCTHkFl10UFpksT4OQcb8GnxQ7qaHJOZxSN+KHcxTSNl\n60trFv3FjQCvV6s/WiPfO7Q+J71ousArNAxbtgycrAmPtYXz2eTZ+UTaTdVxGJPOi0RxzEjZuFsE\nek1MUwPmcrYEa/mYgyLFaPWnOO1r2ifYCwznuQlZvgKcdtjhePWQbjQufdto7CWXT2Rd6y+if+co\nq0nNobkdIoUdtOfvNxoXGN5gI964TIP5MnA1e307E1r9Cd8HiFNsqekkx5g1XxPjIntoA7kxa9lK\nconAnzwSmq4wCkzfpwxHTlWA68bRGwXCpClc/zwPae9IeI3b17mZeI/tBEM+O/Fk6qPqM+whk5ok\nAXOR1CwzleGYq4wC0zWpfbr8EHK8Gq3+F5xKd8x0diLh+Hc8mE7c8dESOQ630CQJZIt4LtHEgH/H\nvwISoTl0TWjQXPkCMkvEHKTAaH2DZfID4Hj5J/DbdiuPQ8a/bfNv4HnSG9snSdAEmWv9TX6T9pUo\n+UEYm6mTFtM0UsUz1jewS/Qf9HuKitbP0KaLA7tlaN2dVYK/8Thk4izWnh+rkC+mCT6RK8DYNzD4\nGcXYNWoSdzBUFtNkjA272HXkCUzPfVKhMLowofrpBc4Mnu382I7abDCMa/K5abwho3ZLEOqVpl33\n/BhyBzBS/yW7ygyt07fW72CfNE/5wHB94HXWry+flQ56lMdsve8x9mKyEmPJEan/wW1eCB+qsE0S\nqL7flTC57UpR4kifF08d4Qp9q0RCxCDlIC+XFWXD9ef8q7hHhihSOiC+6dSoHQhW0CIyP4OUeGDE\nuFb1+RfD9l9++3ozhlt78Waa/q1+eIaO4Kz4nXdk6lVPery06tSOJYr3VcdmX9XEfYVVpXU0iT8o\nu8zMAh7uMkn8N2N7l2lKvn1EfT53izSbPn1j73hd3D/FCBTUWA/lbgAAAABJRU5ErkJggg==\n", "text/latex": [ "$$f{\\left (x \\right )} = \\left(C_{1} + C_{2} x\\right) e^{x} + \\frac{1}{2} \\cos{\\left (x \\right )}$$" ], "text/plain": [ " x cos(x)\n", "f(x) = (C₁ + C₂⋅x)⋅ℯ + ──────\n", " 2 " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "soln = sym.dsolve(diffeq,f(x))\n", "soln" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Boundary conditions\n", "This isn't implemented yet in `dsolve` -- it's on the \"to do\" list
\n", "For now, solve for contants on your own. For example, if\n", "$$ f(0) = 1\\quad\\mbox{and}\\quad\\left.\\frac{df}{dx}\\right|_0 = 0, $$\n", "solve the following equations:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAALsAAAAyBAMAAAD2AbdJAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEImZRO/dMlQiu6vN\nZnZmcXX2AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADZElEQVRYCe2Yz2sTQRTH3+bHNmuaZFEsaMXG\nFs+N1F7aQ4MgHm1Be5BKq4deFBIQPAktlPrj1GChoAhVBAV7SSl6KbU5ieCh+Q8MiAe9pIr4q2qd\n92Y2O5OkuxPcgocOdObNm+989u3bmdlNAVjZn8E62HJ/2uFFRvOOGVybuGAL2NwuBA+wcInjrZ8e\nMc86MXho6oZiI+Swtrg//qlu3O0aK+st4zsHBW8oT6BUyeU1WNWW8ZAU+KkK0VLFBqjr+Ad8V4Yw\nXbuF59w9vPuwoPZoRVb2kvN/Jmdw/E1ZjkzDDj//tUayukd7dGm1fFdjPpMYH1fXrLSPVsUnLwLM\nsD+d8r4MsX6/21LwxhMbIPxDBw6H8SgfKvhoxVm2mEZdO55zkWE0fcsGiwRO+8lSD0nxNovN0DSr\n2jJo+pXwd1Rc85O1b5JiEmvrK9ZGAWssV3jTtF6cQPchZ8wsOpbaxn5jP0T5Dv0RYzeoNcZEt1nT\nW+Hensc2GgdLvNtQr2Owx7PoN79hzW75BW+96lyeRkOFeMlLBvFzAEeWSRKlN5gBcFOesY1lU/ag\nPU5B22ahzV1oxqtJVq7mIUVz+JTZCnScINMkyK06PFfV1zl0xPJm1vpSP6T2r6cB+ulW+YrPaOFp\nxYfxEnTLKlLqhVhyIExZtz4zM8TuWkmOpJVM2ijHmMOsSN5Gs5cCp4UJc2yfY544Xl05XSVlLq64\nGRYJ9JB7p5UT4YuxmkWVMbB6ElsRvbLuTTwEpHJgaSXLugmWS1Z2Wvf7NmmYHwpkskpNzvzAUxy4\n44wq7Sk4o/R5x+p7RkkB8XkmPneEclaeYRShN8scadnp2G2vbz9ybKnthBBfUMqJKQTzuZeSNG5D\ndJglriL5ama0yZZgg8sA50nTDF+bTEZ0AuJsYSVUr3dvFGCdsuOPZ6c04lsq7LTWxTOu6b11ml45\nZ6PbP3omOptGaUslgltUE69sAL2riI2gE304o4eUVX28o4N/J8/Ts5MiIg18LAP39KCuagasAvY0\n8Ox9/cGdqGWxz4GkJt663D04oQV1RQvdPfyFKqL3+OnWzt5sreI3trfpqwPEWRYtuZcO0ppKEy3u\nvpCDpEM1Tzjn13mgbHbMOv9LqFYCJhOuY0RQE1t28PzYWA3aWQwe/6CMzL8OC94LPWMmQgAAAABJ\nRU5ErkJggg==\n", "text/latex": [ "$$\\left \\{ C_{1} : \\frac{1}{2}, \\quad C_{2} : - \\frac{1}{2}\\right \\}$$" ], "text/plain": [ "{C₁: 1/2, C₂: -1/2}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "constants = sym.solve([soln.rhs.subs(x,0) - 1, soln.rhs.diff(x,1).subs(x,0)- 0])\n", "constants" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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\nQzXU25Fp/i8I3lJkZlDr5wAAAABJRU5ErkJggg==\n", "text/latex": [ "$$f{\\left (x \\right )} = \\left(- \\frac{x}{2} + \\frac{1}{2}\\right) e^{x} + \\frac{1}{2} \\cos{\\left (x \\right )}$$" ], "text/plain": [ " ⎛ x 1⎞ x cos(x)\n", "f(x) = ⎜- ─ + ─⎟⋅ℯ + ──────\n", " ⎝ 2 2⎠ 2 " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "C1, C2 = sym.symbols('C1,C2')\n", "soln = soln.subs(constants)\n", "soln" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Convert soln to python function for numerical evaluation/plotting\n", "I'm not sure why I had to specify the modulue for conversion of sympy functions.
\n", "See http://docs.sympy.org/latest/modules/utilities/lambdify.html
\n", "In previous examples, sympy figured out a good module \"on its own.\" " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "func = sym.lambdify(x,soln.rhs,'numpy')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\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", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\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", " };\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 backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\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 * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\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 = $('