Useful tools for working with SymPy
Project description
sympy-addons
Useful tools for working with SymPy.
Main features:
- tools for working on subexpressions including a convenient query API
- graph visualization of expression trees
- tools for vector analysis
Installation
pip install --upgrade sympy-addons
Documentation
For a full documentation of the project, see this website.
Usage
The examples in this section use the following expression for performing queries:
$$ \left(x - 1\right)^{2} + \frac{\left(x - 4\right)^{3} + \left(x + 2\right)^{2} + \sin{\left(z \right)}}{\sqrt{\left(x - 1\right)^{2} + \left(x + 3\right)^{2}}} $$
or in SymPy:
from sympy import *
from sympy.abc import x, z
expr = (x - 1) ** 2 + ((x + 2) ** 2 + (x - 4) ** 3 + sin(z)) / sqrt((x - 1) ** 2 + (x + 3) ** 2)
Query API
The query API allows to select specific subexpressions.
Querying for types
To get all subexpression matching a given type, e.g. Pow
:
from sympy_addons import Query
# define the query:
query = Query(type=Pow)
# execute it on an expression:
result = query.run(expr)
# result is an instance of QueryResult. You can iterate over it:
for item in result:
print(item)
# or get the result as a list:
this_is_a_list_of_matching_expressions = result.all()
# or just the first/last:
first_matching_expr = result.first()
last_matching_expr = result.last()
Querying for inherited types
To find all subexpressions that are instances of, say, Atom
and all
classes inheriting from Atom
, use the isinstance
keyword:
result = Query(isinstance=Atom)
Querying for arguments
Non-atomic types in SymPy have an args
attribute. You can query for
subexpression which have exactly the args
that you look for (order does not matter).
For example,
result = Query(args=(x, 1)).run(expr)
will return all subexpressions with args==(x, 1)
or args==(1, x)
.
If you don't want to specify all args
, use args__contains
instead:
result = Query(args__contains=(x,)).run(expr)
will return all subexpression with args
attribute containing x
.
Custom tests
You can define your own predicates to query for. For instance, to query for subexpressions with exactly three arguments, you could write
query = Query(test=lambd e: (not e.is_Atom) and len(e.args) == 3).run(expr)
Chaining queries
Each query is defined as one predicate. But you can concatenate queries to combine them logically.
For a logical OR, use the |
operator:
query_1 = ...
query_2 = ...
result = (query_1 | query_2).run(expr)
For an AND operation, use the filter
method:
query_1 = ...
query_2 = ...
result = query_1.run(expr).filter(query_2)
Getting EPaths
The epath
function in SymPy allows to work directly on subexpressions. As input, it needs
the path to the subexpression, which is often cumbersome to get. The get_paths
and get_path
facilitate getting those paths.
For example,
from sympy_addons import get_epaths, get_epath
paths = get_epaths((x-1)**2, expr)
returns
['/[0]', '/[1]/[0]/[0]/[0]']
To only expand the $(x-1)^2$ under the square root, we would need the second path:
epath(paths[1], expr, expand)
The get_path
function works just as the get_paths
function, but it will raise
an exception if the expression is not found or not unique.
Running the Tests
Run the tests with pytest
:
# if you haven't installed pytest yet:
pip install pytest
pytest sympy_addons
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for sympy_addons-0.0.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b11117b9ef2987cc22b687e1db2d6c7a95ba317ff6c509a2856c21086b6b3a0f |
|
MD5 | 456e13f9242392ee5d74a896dbd7d7b9 |
|
BLAKE2b-256 | b6254f17570f9349e2091e1c0faa176bcc73681ce1ac1740f5185b81c97985ad |