Difference between revisions of "Python:Symbolic Computations"
Jump to navigation
Jump to search
(→Useful Pages) |
(→Future Work) |
||
(7 intermediate revisions by the same user not shown) | |||
Line 6: | Line 6: | ||
== Getting Started == | == Getting Started == | ||
* [https://docs.sympy.org/latest/tutorials/intro-tutorial/index.html#intro-tutorial Tutorial] (note - some of the internal links on SymPy do not get to the tutorial - this link does). | * [https://docs.sympy.org/latest/tutorials/intro-tutorial/index.html#intro-tutorial Tutorial] (note - some of the internal links on SymPy do not get to the tutorial - this link does). | ||
− | * Anaconda | + | * Anaconda and Google Colab both come with SymPy already installed so you can skip the installation part if you are using Anaconda. |
* Note that sometimes the tutorial imports SymPy as <code>sympy</code> and other times it imports all of SymPy. This does make it a little harder to keep track of which commands are SymPy-specific! | * Note that sometimes the tutorial imports SymPy as <code>sympy</code> and other times it imports all of SymPy. This does make it a little harder to keep track of which commands are SymPy-specific! | ||
Line 16: | Line 16: | ||
== Preamble == | == Preamble == | ||
* This page will be consistent with [[Python:Nicknames]] in terms of module imports. Note that there are several ways to get the SymPy package into Python: | * This page will be consistent with [[Python:Nicknames]] in terms of module imports. Note that there are several ways to get the SymPy package into Python: | ||
− | ** import sympy as sym (what this page does) | + | ** <code>import sympy as sym</code> (what this page does) |
− | ** import sympy as sp (this is more consistent with bringing in NumPy, but that's what we will use for SciPy) | + | ** <code>import sympy as sp</code> (this is more consistent with bringing in NumPy, but that's what we will use for SciPy) |
− | ** from sympy import * (if you are sure nothing in SymPy will contradict anything in built-in Python) | + | ** <code>from sympy import *</code> (if you are sure nothing in SymPy will contradict anything in built-in Python) |
− | ** from sympy import TUPLE OF THINGS (if you just have a few specific things you want to do with SymPy) | + | ** <code>from sympy import TUPLE OF THINGS</code> (if you just have a few specific things you want to do with SymPy) |
− | * sym.init_session() will automatically bring in x, y, z, and t as symbols; k, m, n as integers; f, g, h as function names; and sym.init_printing HOWEVER it brings in all of sympy with from sympy import *! | + | * <code>sym.init_session()</code> will automatically bring in x, y, z, and t as symbols; k, m, n as integers; f, g, h as function names; and sym.init_printing HOWEVER it brings in all of sympy with from sympy import *! |
+ | |||
+ | == Output == | ||
+ | * To make output prettier: <code>sym.init_printing()</code> | ||
+ | * The display depends on if LaTeX is installed or not; the command above will try to make the output as pretty as possible given the circumstances. | ||
== Defining Symbols == | == Defining Symbols == | ||
− | * a, b, c = sym. | + | * There are a variety of different ways to define symbols; your choice will be based on how you are writing and running code (for example, Spyder versus Jupyter versus Trinket). |
− | * The symbolic representation can be entirely different from the variable with a, b, c = sym. | + | * If the symbolic representation and variable names exactly match, it is most efficient to use <code>sym.var('a b c')</code> or <code>sym.var('a, b, c')</code> |
− | * | + | ** Spyder's editor will not recognize that the variables are defined, meaning you will get error flags in the editor. If you want to explicitly demonstrate that the variables exist, you can use <code>a, b, c = sym.var('a b c')</code> |
− | ** | + | ** Alternatively, if you want to create a list with all the variables in it, you can use <code>THING = sym.var('a b c')</code> |
+ | ** '''''Top choice''''' - If you want the best of both worlds, use <code>a, b, c = sym.var('a b c')</code> and <code>THING = a, b, c</code>; once you make the string, it is easy enough to copy and paste it in front of the = on the first line and after the = on the second. | ||
+ | * (This part is informational, but potentially not useful) The symbolic representation can be entirely different from the variable with something like <code>v1, ib, pabsR3 = sym.var('v_1 i_b p_{{abs\,R_{3}}}}')</code> or <code>a, b, c = sym.var('let\'s go Duke')</code>. When Python displays the variables, it will use the characters assigned to the variable in the string. This doesn't look pretty in all version of Python, though, and requires <code>sym.init_printing()</code> to have a chance at working. | ||
+ | * <code>sym.symbols()</code> is similar to <code>sym.var()</code> except that you must explicitly list the names on the right of an = if you want things defined: | ||
+ | ** <code>a, b, c = sym.var('a b c')</code> is the same as <code>a, b, c = sym.symbols('a b c')</code> | ||
+ | ** <code>sym.symbols('a b c')</code> does not create variables while <code>sym.var('a b c')</code> does. | ||
+ | ** <code>THING = sym.symbols('a b c')</code> creates a single tuple called THING that has symbols in it, but does not actually create those symbols! That is to say, <code>THING[0]</code> will display as $$a$$, but you cannot use $$a$$ in an expression. | ||
+ | * SymPy (with sym.init_printing()) will automatically subscript a trailing number when displaying - for instance, using <code>blah = sym.var('x17')</code> means if you type <code>blah</code> in the console it will display $$x_{17}$$. | ||
== Substitutions == | == Substitutions == | ||
− | * use .subs(variable, value) or .subs(iterable) where iterable has a collection of variables and values | + | * If you have some symbolic object X that contains several other symbols, you can use <code>X.subs(variable, value)</code> for a single substitution or <code>X.subs(iterable)</code> where iterable has a collection of variables and values; for example, <code>X.subs([(a, 10), (b, 20)])</code> |
− | + | * If you have several variables and several values, it may be useful to have a list of each and "zip" them together: | |
− | == | + | <syntaxhighlight lang=python> |
− | + | > vars = ['a', 'b'] | |
− | + | > vals = [10, 20] | |
+ | > print(list(zip(vars, vals))) | ||
+ | [('a', 10), ('b', 20)] | ||
+ | > x = a + b | ||
+ | > print(x) | ||
+ | a + b | ||
+ | > x.subs(zip(vars, vals)) | ||
+ | 30 | ||
+ | </syntaxhighlight> | ||
== Solving == | == Solving == | ||
− | * sym.solve() | + | * sym.solve(EQNS, VARS) for a system of equations |
− | * sym.dsolve() | + | * sym.dsolve(EQNS, VARS) for a system of differential equations |
== Interesting Things == | == Interesting Things == | ||
Line 44: | Line 63: | ||
* sym.Matrix() can have symbols and will calculate things symbolically | * sym.Matrix() can have symbols and will calculate things symbolically | ||
− | == Philosophical Things == | + | == Philosophical Things == |
− | |||
− | |||
− | |||
− | |||
== References == | == References == | ||
Line 55: | Line 70: | ||
== Future Work == | == Future Work == | ||
+ | * Determine good ways to collect equations and variables. | ||
+ | * Clarify when to solve after numbers are in versus before. | ||
* Subscripts are...strange. Numbers coming at the end of a variable print as subscripts but letters end that behavior. One workaround is to define a variable with the xa = sym.Symbol('x_a') command but that will only take a single character superscript. | * Subscripts are...strange. Numbers coming at the end of a variable print as subscripts but letters end that behavior. One workaround is to define a variable with the xa = sym.Symbol('x_a') command but that will only take a single character superscript. | ||
− | * You can create a neat symbol like pdelvCC = sym.Symbol('p_{{del,v_{CC}}}}') and it will work great in a notebook or inline. Spyder has a display() function that will also work but creates a plot with the rendering. Displays really ugly on Trinket. | + | * You can create a neat symbol like pdelvCC = sym.Symbol('p_{{del\,v_{CC}}}}') and it will work great in a notebook or inline. Spyder has a display() function that will also work but creates a plot with the rendering. Displays really ugly on Trinket. Best to avoid for now if work will end up in Trinket. |
Latest revision as of 16:47, 24 January 2023
This is a sandbox for information on symbolic computation with Python. It is about as organized as one might expect...
Contents
Introduction
SymPy is a package that allows Python to perform symbolic calculations. The main English-language site is https://www.sympy.org/en/index.html
Getting Started
- Tutorial (note - some of the internal links on SymPy do not get to the tutorial - this link does).
- Anaconda and Google Colab both come with SymPy already installed so you can skip the installation part if you are using Anaconda.
- Note that sometimes the tutorial imports SymPy as
sympy
and other times it imports all of SymPy. This does make it a little harder to keep track of which commands are SymPy-specific!
Useful Pages
Preamble
- This page will be consistent with Python:Nicknames in terms of module imports. Note that there are several ways to get the SymPy package into Python:
import sympy as sym
(what this page does)import sympy as sp
(this is more consistent with bringing in NumPy, but that's what we will use for SciPy)from sympy import *
(if you are sure nothing in SymPy will contradict anything in built-in Python)from sympy import TUPLE OF THINGS
(if you just have a few specific things you want to do with SymPy)
sym.init_session()
will automatically bring in x, y, z, and t as symbols; k, m, n as integers; f, g, h as function names; and sym.init_printing HOWEVER it brings in all of sympy with from sympy import *!
Output
- To make output prettier:
sym.init_printing()
- The display depends on if LaTeX is installed or not; the command above will try to make the output as pretty as possible given the circumstances.
Defining Symbols
- There are a variety of different ways to define symbols; your choice will be based on how you are writing and running code (for example, Spyder versus Jupyter versus Trinket).
- If the symbolic representation and variable names exactly match, it is most efficient to use
sym.var('a b c')
orsym.var('a, b, c')
- Spyder's editor will not recognize that the variables are defined, meaning you will get error flags in the editor. If you want to explicitly demonstrate that the variables exist, you can use
a, b, c = sym.var('a b c')
- Alternatively, if you want to create a list with all the variables in it, you can use
THING = sym.var('a b c')
- Top choice - If you want the best of both worlds, use
a, b, c = sym.var('a b c')
andTHING = a, b, c
; once you make the string, it is easy enough to copy and paste it in front of the = on the first line and after the = on the second.
- Spyder's editor will not recognize that the variables are defined, meaning you will get error flags in the editor. If you want to explicitly demonstrate that the variables exist, you can use
- (This part is informational, but potentially not useful) The symbolic representation can be entirely different from the variable with something like
v1, ib, pabsR3 = sym.var('v_1 i_b p_{{abs\,R_{3}}}}')
ora, b, c = sym.var('let\'s go Duke')
. When Python displays the variables, it will use the characters assigned to the variable in the string. This doesn't look pretty in all version of Python, though, and requiressym.init_printing()
to have a chance at working. sym.symbols()
is similar tosym.var()
except that you must explicitly list the names on the right of an = if you want things defined:a, b, c = sym.var('a b c')
is the same asa, b, c = sym.symbols('a b c')
sym.symbols('a b c')
does not create variables whilesym.var('a b c')
does.THING = sym.symbols('a b c')
creates a single tuple called THING that has symbols in it, but does not actually create those symbols! That is to say,THING[0]
will display as $$a$$, but you cannot use $$a$$ in an expression.
- SymPy (with sym.init_printing()) will automatically subscript a trailing number when displaying - for instance, using
blah = sym.var('x17')
means if you typeblah
in the console it will display $$x_{17}$$.
Substitutions
- If you have some symbolic object X that contains several other symbols, you can use
X.subs(variable, value)
for a single substitution orX.subs(iterable)
where iterable has a collection of variables and values; for example,X.subs([(a, 10), (b, 20)])
- If you have several variables and several values, it may be useful to have a list of each and "zip" them together:
> vars = ['a', 'b']
> vals = [10, 20]
> print(list(zip(vars, vals)))
[('a', 10), ('b', 20)]
> x = a + b
> print(x)
a + b
> x.subs(zip(vars, vals))
30
Solving
- sym.solve(EQNS, VARS) for a system of equations
- sym.dsolve(EQNS, VARS) for a system of differential equations
Interesting Things
- sym.lambdify((variables), expression, "numpy") will return a function that performs the calculation in the expression
- sym.simplify(expression) will work to simplify an expression
- sym.Matrix() can have symbols and will calculate things symbolically
Philosophical Things
References
Future Work
- Determine good ways to collect equations and variables.
- Clarify when to solve after numbers are in versus before.
- Subscripts are...strange. Numbers coming at the end of a variable print as subscripts but letters end that behavior. One workaround is to define a variable with the xa = sym.Symbol('x_a') command but that will only take a single character superscript.
- You can create a neat symbol like pdelvCC = sym.Symbol('p_{{del\,v_{CC}}}}') and it will work great in a notebook or inline. Spyder has a display() function that will also work but creates a plot with the rendering. Displays really ugly on Trinket. Best to avoid for now if work will end up in Trinket.