Skip to content

Instantly share code, notes, and snippets.

@WetHat
Last active October 4, 2023 17:49
Show Gist options
  • Save WetHat/fc77c1557cbe91072908c708623729b4 to your computer and use it in GitHub Desktop.
Save WetHat/fc77c1557cbe91072908c708623729b4 to your computer and use it in GitHub Desktop.
SymPy: Reducing Symbolic Sums Over Constants
Display the source blob
Display the rendered blob
Raw
{
"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