Simplify expressions given by sympy.sympify
Question:
sp.simplify doesn’t seem to work when your expression is given by sp.sympify. How can I change that?
import sympy as sp
r = sp.Symbol('r', real = True)
f_str = 'sqrt(1/r**4)'
f1 = sp.sympify( f_str )
f2 = sp.sqrt(1/r**4)
for f in f1,f2:
sp.pprint(sp.simplify(f))
which outputs
____
╱ 1
╱ ── # f1
╱ 4
╲╱ r
1
── # f2
2
r
I was expecting that given a real value (r), a sympify expression could get simplified
Answers:
The r
in f1
isn’t the same as the r
symbol you defined:
>>> f1.free_symbols == f2.free_symbols
False
In particular, this means that the assumption that r
is real doesn’t carry through, which is necessary for the simplification you want.
You can remedy this postmortem by substituting the r
in f1
with your r
symbol:
>>> f1 # old r, no assumptions
sqrt(r**(-4))
>>> f1.subs("r", r) # your r, with real assumption
r**(-2)
In general, you can specify assumptions for string inputs at construction time by passing a dictionary mapping string symbols to your desired SymPy Symbols:
>>> f3 = sp.sympify(f_str, {"r": r})
>>> f3
r**(-2)
>>> f3.free_symbols == f2.free_symbols
True
The other answer is correct but I want to note an alternative way that might be useful. The sympify
function when given a string as input will pass that string to SymPy’s parse_expr
function. Actually if you are parsing strings then it is better to call parse_expr
directly rather than using sympify
. If you do use parse_expr
directly then you can pass other options to control how the expression gets parsed including specifying which symbol objects to use for each symbol name appearing in the string.
In [4]: import sympy as sp
...:
...: r = sp.Symbol('r', real = True)
In [5]: sp.parse_expr('sqrt(1/r**4)', {'r': r})
Out[5]:
1
──
2
r
In [6]: sp.parse_expr('sqrt(1/r**4)')
Out[6]:
____
╱ 1
╱ ──
╱ 4
╲╱ r
sp.simplify doesn’t seem to work when your expression is given by sp.sympify. How can I change that?
import sympy as sp
r = sp.Symbol('r', real = True)
f_str = 'sqrt(1/r**4)'
f1 = sp.sympify( f_str )
f2 = sp.sqrt(1/r**4)
for f in f1,f2:
sp.pprint(sp.simplify(f))
which outputs
____
╱ 1
╱ ── # f1
╱ 4
╲╱ r
1
── # f2
2
r
I was expecting that given a real value (r), a sympify expression could get simplified
The r
in f1
isn’t the same as the r
symbol you defined:
>>> f1.free_symbols == f2.free_symbols
False
In particular, this means that the assumption that r
is real doesn’t carry through, which is necessary for the simplification you want.
You can remedy this postmortem by substituting the r
in f1
with your r
symbol:
>>> f1 # old r, no assumptions
sqrt(r**(-4))
>>> f1.subs("r", r) # your r, with real assumption
r**(-2)
In general, you can specify assumptions for string inputs at construction time by passing a dictionary mapping string symbols to your desired SymPy Symbols:
>>> f3 = sp.sympify(f_str, {"r": r})
>>> f3
r**(-2)
>>> f3.free_symbols == f2.free_symbols
True
The other answer is correct but I want to note an alternative way that might be useful. The sympify
function when given a string as input will pass that string to SymPy’s parse_expr
function. Actually if you are parsing strings then it is better to call parse_expr
directly rather than using sympify
. If you do use parse_expr
directly then you can pass other options to control how the expression gets parsed including specifying which symbol objects to use for each symbol name appearing in the string.
In [4]: import sympy as sp
...:
...: r = sp.Symbol('r', real = True)
In [5]: sp.parse_expr('sqrt(1/r**4)', {'r': r})
Out[5]:
1
──
2
r
In [6]: sp.parse_expr('sqrt(1/r**4)')
Out[6]:
____
╱ 1
╱ ──
╱ 4
╲╱ r