Last active
October 4, 2023 17:49
-
-
Save WetHat/fc77c1557cbe91072908c708623729b4 to your computer and use it in GitHub Desktop.
SymPy: Reducing Symbolic Sums Over Constants
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": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Reducing Symbolic Summations with SymPy\n", | |
"\n", | |
"This gist shows how to use [SymPy 1.5](https://www.sympy.org) to transform symbolic sums over products of constant terms (with respect to the summation index) and indexed terms like so:\n", | |
"\n", | |
"$$\n", | |
"\\sum^{m-1}_{i=0} (a \\cdot A_i + b \\cdot B_i + c)\n", | |
"\\rightarrow \n", | |
"a\\sum^{m-1}_{i=0}A_i + b\\sum^{m-1}_{0}B_i + m \\cdot c\n", | |
"$$" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"To get started with the example above we need to setup a SymPy session for symbolic summation:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from sympy import IndexedBase, Sum, expand, simplify, factor_terms,Eq\n", | |
"from sympy.abc import *\n", | |
"\n", | |
"A = IndexedBase('A')\n", | |
"B = IndexedBase('B')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Now let's work on the example above" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle \\sum_{i=0}^{m - 1} \\left(a {A}_{i} + b {B}_{i} + c\\right)$" | |
], | |
"text/plain": [ | |
"Sum(a*A[i] + b*B[i] + c, (i, 0, m - 1))" | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"s = Sum(a*A[i] + b*B[i] + c, (i,0,m-1))\n", | |
"s" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"First we pull the sum apart by expanding it." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle \\sum_{i=0}^{m - 1} c + \\sum_{i=0}^{m - 1} a {A}_{i} + \\sum_{i=0}^{m - 1} b {B}_{i}$" | |
], | |
"text/plain": [ | |
"Sum(c, (i, 0, m - 1)) + Sum(a*A[i], (i, 0, m - 1)) + Sum(b*B[i], (i, 0, m - 1))" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"s1 = expand(s)\n", | |
"s1" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"To evaluate the sum over the constant $c$, we factor out all constants." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle a \\sum_{i=0}^{m - 1} {A}_{i} + b \\sum_{i=0}^{m - 1} {B}_{i} + c \\sum_{i=0}^{m - 1} 1$" | |
], | |
"text/plain": [ | |
"a*Sum(A[i], (i, 0, m - 1)) + b*Sum(B[i], (i, 0, m - 1)) + c*Sum(1, (i, 0, m - 1))" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"s2 = factor_terms(s1)\n", | |
"s2" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"To get rid of the odd $\\sum^{i}_{m-1} 1$ we need one final step:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle \\sum_{i=0}^{m - 1} \\left(a {A}_{i} + b {B}_{i} + c\\right) = a \\sum_{i=0}^{m - 1} {A}_{i} + b \\sum_{i=0}^{m - 1} {B}_{i} + c m$" | |
], | |
"text/plain": [ | |
"Eq(Sum(a*A[i] + b*B[i] + c, (i, 0, m - 1)), a*Sum(A[i], (i, 0, m - 1)) + b*Sum(B[i], (i, 0, m - 1)) + c*m)" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"s3 = s2.doit()\n", | |
"Eq(s,s3)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Let's try a more complex example now:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle \\sum_{i=0}^{m - 1} \\left(a {A}_{i} + b {B}_{i} + c\\right)^{2}$" | |
], | |
"text/plain": [ | |
"Sum((a*A[i] + b*B[i] + c)**2, (i, 0, m - 1))" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"e = Sum((a*A[i] + b*B[i] + c)**2, (i,0,m-1))\n", | |
"e" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"for this we get:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle \\sum_{i=0}^{m - 1} \\left(a {A}_{i} + b {B}_{i} + c\\right)^{2} = a^{2} \\sum_{i=0}^{m - 1} {A}_{i}^{2} + 2 a b \\sum_{i=0}^{m - 1} {A}_{i} {B}_{i} + 2 a c \\sum_{i=0}^{m - 1} {A}_{i} + b^{2} \\sum_{i=0}^{m - 1} {B}_{i}^{2} + 2 b c \\sum_{i=0}^{m - 1} {B}_{i} + c^{2} m$" | |
], | |
"text/plain": [ | |
"Eq(Sum((a*A[i] + b*B[i] + c)**2, (i, 0, m - 1)), a**2*Sum(A[i]**2, (i, 0, m - 1)) + 2*a*b*Sum(A[i]*B[i], (i, 0, m - 1)) + 2*a*c*Sum(A[i], (i, 0, m - 1)) + b**2*Sum(B[i]**2, (i, 0, m - 1)) + 2*b*c*Sum(B[i], (i, 0, m - 1)) + c**2*m)" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"e1 = factor_terms(expand(e)).doit()\n", | |
"Eq(e,e1)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# About this Jupyter Notebook\n", | |
"\n", | |
"This Gist was created using the [Jupyter Lab](https://jupyter.org/) computational notebook with\n", | |
"the python3 kernel and following additional Python modules:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"| Component | Version | Description |\n", | |
"| --------------------------------- | -------------------------- | -------------------- |\n", | |
"| [Python](https://www.python.org/) | 3.12.0 | Programming Language |\n", | |
"| [jnbBuffs](https://github.com/WetHat/jupyter-notebooks) | 0.1.10 | Utilities for authoring JupyterLab Python notebooks. |\n", | |
"| [jupyterlab](https://pypi.org/project/jupyterlab/) | 4.0.6 | JupyterLab computational environment |\n", | |
"| [sympy](https://sympy.org) | 1.12 | Computer algebra system (CAS) in Python |" | |
], | |
"text/plain": [ | |
"<IPython.core.display.Markdown object>" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"from jnbBuffs.manifest import notebook_manifest\n", | |
"notebook_manifest('jupyterlab', 'sympy', 'jnbBuffs')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.12.0" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment