Last active
May 1, 2017 00:30
-
-
Save knowsuchagency/cc8bd636157d804b4aabf0ca8b2bbed9 to your computer and use it in GitHub Desktop.
right hand sum, left hand sum, and integration example in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"start_time": "2017-05-01T00:29:50.203856Z", | |
"end_time": "2017-05-01T00:29:50.566830Z" | |
}, | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "from functools import partial, singledispatch\nfrom itertools import islice, count\nfrom sympy import sympify, init_printing\nfrom sympy import integrate as _integrate\nfrom textwrap import dedent\nfrom mpmath import e\nimport sympy\n\ninit_printing()\n\ndef _sum(left_or_right, y_values, delta_x):\n \"\"\"\n Return the left or right hand sum of a list of y values.\n \"\"\"\n # make sure y_values is a list\n y_values = list(y_values)\n \n if left_or_right == 'left':\n y_values = y_values[:-1]\n elif left_or_right == 'right':\n y_values = y_values[1:]\n \n return sum(y*delta_x for y in y_values)\n\nlhs = partial(_sum, 'left')\nrhs = partial(_sum, 'right')\n\n@singledispatch\ndef integrate():\n pass\n\n@integrate.register(dict) \ndef _(observations, a_b=None, n=None, delta_x=None, verbose=False):\n \"\"\"\n Given a table of x, y values as a dictionary\n return the definite integral.\n \"\"\"\n if delta_x is not None and n is not None:\n raise ValueError('delta x and n are mutually exclusive')\n \n # pair down table of values if delta x is given\n if delta_x is not None:\n observations = {\n k:v for k,v in observations.items() if k % delta_x == 0\n }\n x_vals = list(observations.keys())\n else:\n x_vals = list(observations.keys())\n delta_x = x_vals[1]-x_vals[0]\n \n \n \n # n is the number of times we evenly split the observations\n # by default, we'll choose the maximum amount of splits possible\n \n n = len(observations)-1 if n is None else n\n \n # let a and b be the largest and smallest values\n # in our list of x values by default\n \n if a_b is not None:\n a, b = a_b\n else:\n a = x_vals[0]\n b = x_vals[-1]\n \n # create the list of y values that we will compute\n # the right and left hand sums of\n start = x_vals.index(a)\n stop = x_vals.index(b)+1\n step = len(observations) // n \n y_vals = list(observations.values())[start:stop:step]\n \n # return the average of the left and right hand sums\n left_hand_sum = lhs(y_vals, delta_x)\n right_hand_sum = rhs(y_vals, delta_x)\n result = (left_hand_sum + right_hand_sum) / 2\n \n if verbose:\n print(dedent(f\"\"\"\n inputs: {observations}\n \n a : {a} (x-axis lower limit)\n b : {b} (x-axis upper limit)\n n : {n} (the number of times we split the graph)\n delta x : {delta_x} (the interval between numbers on the x-axis)\n left hand sum : {left_hand_sum}\n right hand sum: {right_hand_sum}\n \n result: {result}\n \"\"\"))\n \n return result\n\n@integrate.register(sympy.Basic)\ndef _(expr, a_b=None, n=None, verbose=False):\n \"\"\"\n Return the integral of a single-variable expression.\n \"\"\"\n \n # ensure we replace e variable with constant e in\n # expression\n expr = expr.subs('e', e)\n \n # get symbol from expression\n variable = list(expr.free_symbols)[0]\n \n # if n is given, create a table and use that to compute integral\n if n is not None:\n if a_b is None: raise ValueError('must specify range: a, b with n')\n a, b = a_b\n delta_x = (b-a)/n\n x_vals = islice(count(a, delta_x), n+1)\n observations = {\n x: float(expr.subs(variable, x)) for x in x_vals\n }\n return integrate(observations, verbose=verbose)\n \n elif a_b is not None:\n a, b = a_b\n return _integrate(expr, (variable, a, b))\n \n return _integrate(expr)\n\n@integrate.register(str)\ndef _(expr, *args, **kwargs):\n \"\"\"\n Return the integral of a single-variable expression.\n \"\"\"\n return integrate(sympify(expr), *args, **kwargs)\n \n ", | |
"execution_count": 9, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"start_time": "2017-05-01T00:26:35.080460Z", | |
"end_time": "2017-05-01T00:26:35.894648Z" | |
}, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "observations = {20: 5, 22: 7, 24: 11, 26: 18, 28: 29, 30: 45}\n\nintegrate(observations, verbose=True) # -> 180 ", | |
"execution_count": 2, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "\ninputs: {20: 5, 22: 7, 24: 11, 26: 18, 28: 29, 30: 45}\n\na : 20 (x-axis lower limit)\nb : 30 (x-axis upper limit)\nn : 5 (the number of times we split the graph)\ndelta x : 2 (the interval between numbers on the x-axis)\nleft hand sum : 140\nright hand sum: 220\n\nresult: 180.0\n\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 2, | |
"data": { | |
"text/plain": "180.0", | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAADsAAAASCAYAAADlhqZNAAAABHNCSVQICAgIfAhkiAAAAjpJREFU\nWIXt1kuIjWEYB/CfyaRM05BroWQabKVcUprZKLGgZGUrKxHF1m6QNGUjaYxigwWyYIiFlCxkhTEu\nR7kMScwwk4kZi/c9M1+f8505NwuZf52eznP5P8/zfu/l4T/GNpzAXfRjFOcmiNmEbrzBEF7iItYW\niVmITrzDD+TQgZkV1Fwx1yOhwQE8MXGzR6LPJ5zGYVzCMEawo0BMMz7EuMsx5nb8/xSzJiqyVlxt\naMEUtCre7Hz8Qh/mFuAZFb5yGjeibXdKfzzqTxYr8G9xtSre7Opov5Jh7xd2SBLNMeYV6lK2RnzD\ndzSUUF/ZXGmnctArbNdVmJ2yrY8Jb6X0bVF2C9s8iQHcw3SsKSF/2VzVNPsZBzEPj3EK7bgQC7iJ\nXamYZVE+y+DsjXJpCfnL5ppaAmkxdAi3Xyd2JvTP0YWPKf+mKL9m8OX1M0rIXTZXNV8WDgi3b5dw\nhhqwUriYzuNolfw1RTXNtgpPz1XsExocxENsxVvsx5JETH61mxRGXv+lhPxlc1XT7OYo7xSwDeJB\n5F+R0PdEmXUmW6LMOodJlM1VTbPTopyTYc/rhxO6/MJsKJC7EeuEhbpfQv5ack34zm6P9j4sSNk2\nCs/BkD+nmEoGgWYsR30NuMawRbhsunA9BrxI6I4lfOuE52VUGCDOGj/DI1G/J6Pw5IjXbnzE61F4\nxMtF++IacI3hUHTM+uVS/vXYK2yVfvwUnptrwvbKwiKcwXthm79WfHjPKdxsJVyTmMS/jN9N+8IR\nHUdLYAAAAABJRU5ErkJggg==\n", | |
"text/latex": "$$180.0$$" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"start_time": "2017-05-01T00:26:35.896972Z", | |
"end_time": "2017-05-01T00:26:36.134840Z" | |
}, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "integrate('2*x') # -> x**2\n\nintegrate('2*x', (0, 10)) # -> 100", | |
"execution_count": 3, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 3, | |
"data": { | |
"text/plain": " 2\nx ", | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAABcAAAAWCAYAAAArdgcFAAAABHNCSVQICAgIfAhkiAAAASdJREFU\nOI3t078rxVEYx/EXyiAWpRgsKJRffwCLTMrEZCKrf4DJxoIMks3KQlmwK3UHZZCJDXWHKwNFXMP3\n3Pq6vt873PtNBp86dZ7zPOf9POec5/CHtYQcnpHHMQaygp9iPgAHcYhHtGaVIK5mfGAK6jOGtwRm\nIWMuOMAlGrIGb+AeXWkBZyhiumy9DnvBt5awbxMP6KuUfVj0INe+H209gHcT9myJOqS/ErikUoVz\nwV4O9r6fDbAt6vFxtMdGcxq8E6+4w2IAn6AxIbaYMlYqVb8aCzxHU6XgNKX1eT42X8BLNfAkzeJT\n9PpF7GQFnsQbrtCGG7yjt1bwqOj4t+gIazOi6o9qAY/gSXQV3WW+XEgwVg24R/QJChhK8E8E+EU1\n8H/9rr4AkGRDHpkg5ysAAAAASUVORK5CYII=\n", | |
"text/latex": "$$x^{2}$$" | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 3, | |
"data": { | |
"text/plain": "100", | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAACcAAAASCAYAAADYFMcrAAAABHNCSVQICAgIfAhkiAAAASxJREFU\nSInt1bEuQ2EYxvFfjUQQiRiYmtYlEFM7WQ1uw+YCjCaRWEwsLoCRwSLMNlRCLURCgjIwYOjXRI6e\ntL7TRogn+fLmvM/7z3lOcvJ+/CLNYRX7eMQ7NlswY1jHFV5QxQqGOsw4CoFqOG4jXB43YW4LS9gL\nzycY7hADyiggh1Ib4XbCzHyivxz6ax1ivqhVuHzwL9CT8PrxhGf0xTLJge+oHOou3hJeDQfoxVQs\nkyXcRKiVFP8s1GIskyXcQKgPKX6jPxjLZAnXdWUJ1/jKgRS/0b+PZbKEOw21mOIXQv38f8UwTVXy\nw6skSzi6vIRziYHZcGAUMzhXv2vhFguf5vM4xAi21a+8SfV9VsE07hLviGHAYkifdqpNmHFs4Bqv\nuNT6Eo9h/vU39AGTVH07+0lGTwAAAABJRU5ErkJggg==\n", | |
"text/latex": "$$100$$" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"start_time": "2017-05-01T00:26:36.137182Z", | |
"end_time": "2017-05-01T00:26:36.289456Z" | |
}, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "integrate('2**x', (0, 6), n=2, verbose=True)", | |
"execution_count": 4, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "\ninputs: {0: 1.0, 3.0: 8.0, 6.0: 64.0}\n\na : 0 (x-axis lower limit)\nb : 6.0 (x-axis upper limit)\nn : 2 (the number of times we split the graph)\ndelta x : 3.0 (the interval between numbers on the x-axis)\nleft hand sum : 27.0\nright hand sum: 216.0\n\nresult: 121.5\n\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 4, | |
"data": { | |
"text/plain": "121.5", | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAADoAAAASCAYAAAAKRM1zAAAABHNCSVQICAgIfAhkiAAAAfZJREFU\nWIXt1k2ITlEYwPHfaETNjoVZMZKiyNaKFwtJyudOJJaSomyoWVooNMooRVGWs1A+UgZjqyShiCHl\nzUwyjJSva3HO5brzfszr3nch86/TOT09H/c5z/s+5+E/ZSv6MIQPSHCxju5s7MEAnuEzxnAXuzGt\nhBjNGI72tVY1q9iZMzyMZRjHayxqEGQbTuMNBvEKc7AZZ7Eu6iQFYkyGMZyoIR9vZLQKC9GBisa3\nvRobTKxct5B0gi0FYzRjOK6m5D9yEE9NrEItbuIyfuTkVfTHc6WGXSsxSiP/0y2Lr3H/1ib/WWZg\nO+biEx7gDr5nldqRaCd2xPO1NvjP040LOdkL7MLtVFCvMxbhKJbgCq63wX+Wc1gjJNuFpTiDHlwV\nml5TKlpvFPuizWPMalOMyXAs+h1IBWVWdC9O4pHQWd+V6LtV0ma4IhWUleh+YQh4KCRZbazedkbi\n3pUKykj0EI7jvpDk2xJ8FmV53J+ngqKJHhGazz2hKYwW9FePBcIENT0jWyxTsQw9OBXPv/77HTml\njXEROtla4VaGomwUB+N5J84L71WfMIrlGY46fxsj62ce5vs9CfXigPBmvsRH4ULWY6bQ9TfhS43v\n0qv+kJz4c9xqppvgVsEY2UQToVopK3EJT/BeGFJGcEN4x/NFnGKKf5GfcTuUV03wiXYAAAAASUVO\nRK5CYII=\n", | |
"text/latex": "$$121.5$$" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"ExecuteTime": { | |
"start_time": "2017-05-01T00:29:54.031338Z", | |
"end_time": "2017-05-01T00:29:54.171287Z" | |
} | |
}, | |
"cell_type": "code", | |
"source": "observations = {\n 0: 48,\n 2: 45,\n 4: 36,\n 6: 21,\n 8: 0,\n}\n\nintegrate(observations, delta_x=4, verbose=True)", | |
"execution_count": 10, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": "\ninputs: {0: 48, 4: 36, 8: 0}\n\na : 0 (x-axis lower limit)\nb : 8 (x-axis upper limit)\nn : 2 (the number of times we split the graph)\ndelta x : 4 (the interval between numbers on the x-axis)\nleft hand sum : 336\nright hand sum: 144\n\nresult: 240.0\n\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 10, | |
"data": { | |
"text/plain": "240.0", | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAADsAAAASCAYAAADlhqZNAAAABHNCSVQICAgIfAhkiAAAAjhJREFU\nWIXt10+IzVEUB/DPaCzQNIOaLEzolT9lw4YkNWRpZevPwigL/8pCTQ2zM6XRyIYSIgulsJF/SRps\nLJTyXx6LkUIzDcl/i3vfeM283595M0My3/p17zvn3u8959x7zr2P/xTT0YJzeIZP6EM3NmFCDo51\n+Bm/lpRxM3EMPfiMIrowtQq7q+LaEo3swWnsiyS9UX4WNSnzm+LYfunOFvAmjjmPDlyPvx8JQc+L\nqrlWYo2hOzgDryLB2oS5NbiG59gv3dnLUb9tkPxAlB9OMnCMuQbQGicfStDvwA+sQLtkZwtR98LQ\noNbhAz5iSg6bhs2VJw/ha2y/VdAtEI7PQdzM4GmO7RUhOOXoxy1MxtIcNg2bK4+ztdgQ+5cq6E4J\nx7w1B9e82D5J0D+N7dyx4KrNQdqBhbgo5Eg59mARlgvVOwv1se1L0JfkDWPBlbWz27FLqGzrB+mW\nCLvZiTs5jPvrSHN2q5CHD4T8eF+mq8VJ4Qi1DWO9UrTrE/Qlee+f5NopVLr7aKygb/D78ZD1dZXN\na4myIwnrlq6SVVkGVsNV6ZGwW8jTe1iNtxXGTJJ8DS0W8rgbj3EVZ6KuILzOirFfXkXr8Dra1Chc\nG2kYMVebEI27mJaxWBLajf6jooD5mDgSrvKd3YgT+C7sWqUqV4xj0tCOvdiMowmG3xYifgEPhWLX\nLNSAZXhXYd1ZmBP7I+EaMDIr/25kOFrOk/ZHoAnHhaP2BS+lP96LkXP2KHCNYxz/Mn4BnMTGEamo\nxBYAAAAASUVORK5CYII=\n", | |
"text/latex": "$$240.0$$" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "", | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"_draft": { | |
"nbviewer_url": "https://gist.github.com/cc8bd636157d804b4aabf0ca8b2bbed9" | |
}, | |
"gist": { | |
"id": "cc8bd636157d804b4aabf0ca8b2bbed9", | |
"data": { | |
"description": "right hand sum, left hand sum, and integration example in Python", | |
"public": true | |
} | |
}, | |
"hide_input": false, | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"name": "python", | |
"version": "3.6.1", | |
"mimetype": "text/x-python", | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"pygments_lexer": "ipython3", | |
"nbconvert_exporter": "python", | |
"file_extension": ".py" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment