How to substitute a big expression with a single variable in sympy - sympy

I have a sympy code which has a expression as follows
$$
z = \frac{x - 0.5}{\epsilon}
$$
$$
\phi = \frac{1}{1 + e^{-z}}
$$
from sympy import *
x = symbols("x")
z = symbols("z")
phi = 1/(1 + exp(-z))
phi_x = diff(phi,x)
After differentiation, $\phi_x$ provides an expression
$$
\frac{e^{- \frac{x - 0.5}{\epsilon}}}{\epsilon \left(1 + e^{- \frac{x - 0.5}{\epsilon}}\right)^{2}}
$$
However, I just want to get the answer as below, where z is replaced for $(x - 0.5)/\epsilon$
$$
\frac{e^{-z}}{\epsilon \left(1 + e^{-z}\right)^{2}}
$$
I have tried both phi_x.subs(x-0.5/eps, z) and phi_x.replace(x-0.5/eps, z). Both does not seems to give a proper subsitution as above.

Related

Sympy: how to print a list of expressions all LaTeX typeset?

I have a list of polynomial expressions, (in my case obtained as the output of a Groebner basis computation), that I would like to view. I am using Jupyter, and I have started off with
import sympy as sy
sy.init_printing()
This causes an individual expression to be given nicely typeset. For a non-Groebner example:
sy.var('x')
fs = sy.factor_list(x**99-1)
fs2 = [x[0] for x in fs[1]]
fs2
The result is a nice list of LaTeX-typeset expressions. But how do I print these expressions one at a time; or rather; one per line? I've tried:
for f in fs2:
sy.pprint(f)
but this produces ascii pretty printing, not LaTeX. In general the expressions I have tend to be long, and I really do want to look at them individually. I can of course do
fs2[0]
fs2[1]
fs2[2]
and so on, but this is tiresome, and hardly useful for a long list. Any ideas or advice? Thanks!
Jupyter (through IPython) has a convenience function called display which works well with SymPy:
import sympy as sy
sy.init_printing()
sy.var('x')
fs = sy.factor_list(x**99-1)
fs2 = [x[0] for x in fs[1]]
for f in fs2:
display(f)
Output:
You can also get the latex code for each of these polynomials by using the latex function:
import sympy as sy
from sympy.printing.latex import latex
sy.init_printing()
sy.var('x')
fs = sy.factor_list(x**99-1)
fs2 = [x[0] for x in fs[1]]
for f in fs2:
print(latex(f))
Output:
x - 1
x^{2} + x + 1
x^{6} + x^{3} + 1
x^{10} + x^{9} + x^{8} + x^{7} + x^{6} + x^{5} + x^{4} + x^{3} + x^{2} + x + 1
x^{20} - x^{19} + x^{17} - x^{16} + x^{14} - x^{13} + x^{11} - x^{10} + x^{9} - x^{7} + x^{6} - x^{4} + x^{3} - x + 1
x^{60} - x^{57} + x^{51} - x^{48} + x^{42} - x^{39} + x^{33} - x^{30} + x^{27} - x^{21} + x^{18} - x^{12} + x^{9} - x^{3} + 1

Sympy - Simplify expression within domain

Can Sympy automatically simplify an expression that includes terms like this one:
cos(x)/(cos(x)**2)**(1/2)
which can be simplified to 1 in the domain that I am interested in 0 <= x <= pi/2 ?
(Examples of other terms that could be simplified in that domain: acos(cos(x)); sqrt(sin(x)**2); sqrt(cos(2*x) + 1); etc.)
If you know the functions that are in your expression (such as sin, cos and tan), you can do the following according to this stack overflow question:
from sympy import *
x = symbols("x", positive=True)
ex = cos(x)/(cos(x)**2)**(S(1)/2)
ex = refine(ex, Q.positive(sin(x)))
ex = refine(ex, Q.positive(cos(x)))
ex = refine(ex, Q.positive(tan(x)))
print(ex)
Note that Q.positive(x*(pi/2-x)) did not help in the process of simplification for trig functions even though this is exactly what you want in general.
But what if you might have crazy functions like polygamma? The following works for some arbitrary choices for ex according to my understanding.
It wouldn't be a problem if the expression was already generated before by SymPy, but if you are inputting the expression manually, I suggest using S(1)/2 or Rational(1, 2) to describe one half.
from sympy import *
# define everything as it would have come from previous code
# also define another variable y to be positive
x, y = symbols("x y", positive=True)
ex = cos(x)/(cos(x)**2)**(S(1)/2)
# If you can, always try to use S(1) or Rational(1, 2)
# if you are defining fractions.
# If it's already a pre-calculated variable in sympy,
# it will already understand it as a half, and you
# wouldn't have any problems.
# ex = cos(x)/(cos(x)**2)**(S(1)/2)
# if x = arctan(y) and both are positive,
# then we have implicitly that 0 < x < pi/2
ex = simplify(ex.replace(x, atan(y)))
# revert back to old variable x if x is still present
ex = simplify(ex.replace(y, tan(x)))
print(ex)
This trick can also be used to define other ranges. For example, if you wanted 1 < x, then you could have x = exp(y) where y = Symbol("y", positive=True).
I think subs() will also work instead of replace() but I just like to be forceful with substitutions, since SymPy can sometimes ignore the subs() command for some variable types like lists and stuff.
You can substitute for a symbol that has the assumptions you want:
In [27]: e = cos(x)/(cos(x)**2)**(S(1)/2) + cos(x)
In [28]: e
Out[28]:
cos(x)
cos(x) + ────────────
_________
╱ 2
╲╱ cos (x)
In [29]: cosx = Dummy('cosx', positive=True)
In [30]: e.subs(cos(x), cosx).subs(cosx, cos(x))
Out[30]: cos(x) + 1

Sympy: How to simplify expression containing exp(I*x)

I want to achieve this kind of simplification:
sqrt(2)*sqrt(pi)*(p**2 + (-p**2 + 4*pi**2)*exp(2*I*p) - 4*pi**2)*exp(-I*p)/(p**2 - 4*pi**2)**2=-2*I*sqrt(2*pi)*sin(p)/(p**2 - 4*pi**2)
However, sympy.simplify can't simplify this expression:
f=sqrt(2)*sqrt(pi)*(p**2 + (-p**2 + 4*pi**2)*exp(2*I*p) -\
4*pi**2)*exp(-I*p)/(p**2 - 4*pi**2)**2
print(sympy.simplify(f))
#sqrt(2)*sqrt(pi)*(p**2 + (-p**2 + 4*pi**2)*exp(2*I*p) - 4*pi**2)*exp(-I*p)/(p**2 - 4*pi**2)**2
How to simplify this expression with SymPy?
Besides, I don't want to use Piecewise((sqrt(2)*I/(2*sqrt(pi)), Eq(p, -2*pi))...)
Just massage the expression a bit. You know that with fractions, you generally factorize them and then you cancel like-terms. Then you simplify after that:
from sympy import *
p = Symbol("p", real=True)
f = sqrt(2)*sqrt(pi)*(p**2 + (-p**2 + 4*pi**2)*exp(2*I*p) - 4*pi**2)*exp(-I*p)/(p**2 - 4*pi**2)**2
f = simplify(expand(cancel(factor(f))))
print(f)
Gives
-2*sqrt(2)*I*sqrt(pi)*sin(p)/(p**2 - 4*pi**2)

SymPy: unable to simplify rather simple expression

I have an expression (expr, see below) that I am unable to simplify in SymPy. For real and positive x, expr is equivalent to x**3 + 2*x, but simplify and refine do not simplify the expression at all. (Mathematica does the simplication without any effort).
How to simplify this expression with SymPy?
from sympy import *
x = var('x')
expr = 16*x**3/(-x**2 + sqrt(8*x**2 + (x**2 - 2)**2) + 2)**2 - 2*2**(S(4)/5)*x*(-x**2 + sqrt(8*x**2 + (x**2 - 2)**2) + 2)**(S(3)/5) + 10*x
expr1 = simplify(expr) # does nothing
expr2 = refine(expr, Q.positive(x)) # does nothing
It can be done!
I rescind my earlier answer. Your expression can be simplified using Sympy. Here's how:
import sympy as sym
x = sym.symbols('x', positive=True)
expr = 16*x**3/(-x**2 + sym.sqrt(8*x**2 + (x**2 - 2)**2) + 2)**2 - 2*2**(sym.S(4)/5)*x*(-x**2 + sym.sqrt(8*x**2 + (x**2 - 2)**2) + 2)**(sym.S(3)/5) + 10*x
sym.simplify(sym.factor(sym.factor(sym.expand(sym.radsimp(expr))), deep=True))
Output:
x*(x**2 + 2)
Basically, I dug through all of the docs on sympy.simplify until I found that magic combination. Also, you have to define x as positive when you create the symbol, just as I did in the code above.
Comment on Mathematica
"Mathematica does the simplication without any effort"
I don't think you should ever underestimate the quantity of time and money that has gone into making the heuristic nightmare that is Mathematica's Simplify seem like it "just works". Sadly, in a lot of ways Sympy is still in it's infancy in comparison. sympy.simplify is one of those ways.

How to convert a regular grammar to regular expression?

Is there an algorithm or tool to convert regular grammar to regular expression?
Answer from dalibocai:
My goal is to convert regular grammer to DFA. Finally, I found an excellent tool : JFLAP.
A tutorial is available here: https://www2.cs.duke.edu/csed/jflap/tutorial/framebody.html
The algorithm is pretty straightforward if you can compute an automaton from your regular expression. Once you have your automaton. For instance for (aa*b|c), an automaton would be (arrows go to the right):
a
/ \
a \ / b
-> 0 ---> 1 ---> 2 ->
\___________/
c
Then just "enumerate" your transitions as rules. Below, consider that 0, 1, and 2 are nonterminal symbols, and of course a, b and c are the tokens.
0: a1 | c2
1: a1 | b2
2: epsilon
or, if you don't want empty right-hand sides.
0: a1 | c
1: a1 | b
And of course, the route in the other direction provides one means to convert a regular grammar into an automaton, hence a rational expression.
From a theoretical point of view, an algorithm to solve this problem works by creating a regular expression from each rule in the grammar, and solving the resulting system of equations for the initial symbol.
For example, for regular grammar ({S,A},{a,b,c},P,S):
P:
S -> aA | cS | a | c
A -> aA | a | bS
Take each non-termimal symbol and generate regular expression from right hand:
S = aA + cS + a + c
A = aA + bS + c
Solve equation system for initial symbol S:
A = a(aA + bS + c) + bS + c
A = a⁺bS + a⁺c + bS + c
S = aA + c(aA + cS + a + c)
S = aA + c⁺aA + c⁺a + c⁺
S = a(a⁺bS + a⁺c + bS + c) + c⁺a(a⁺bS + a⁺c + bS + c) + c⁺a + c⁺
S = a⁺bS + a⁺c + c⁺a⁺bS + c⁺a⁺c + c⁺a + c⁺
S = (c⁺ + ε)a⁺bS + a⁺c + c⁺(a⁺c + a + ε)
substitution: x = (c⁺ + ε)a⁺b
S = x(xS + a⁺c + c⁺(a⁺c + a + ε)) + a⁺c + c⁺(a⁺c + a + ε)
S = x⁺a⁺c + x⁺c⁺(a⁺c + a + ε) + a⁺c + c⁺(a⁺c + a + ε)
S = x*(a⁺c + c⁺(a⁺c + a + ε))
S = ((c⁺ + ε)a⁺b)*(⁺a⁺c + c⁺(a⁺c + a + ε))
Because all modifications were equivalent, ((c⁺ + ε)a⁺b)*(⁺a⁺c + c⁺(a⁺c + a + ε)) is a regular expression equivalent to all words which can be produced from the initial symbol. Thus the value of this expression must be equivalent to the language generated by the grammar whose initial symbol is S.
It ain't pretty, but i purposefully picked a grammar including cycles to portray the way the algorithm works. The hardest part is recognizing that S = xS | x is equivalent to S = x⁺, then just doing the substitutions.
I'll leave this as an answer to this old question, in case that anybody finds it useful:
I have recently released a library for exactly that purpose:
https://github.com/rindPHI/grammar2regex
You can precisely convert regular grammars, but also compute approximate regular expressions for more general general context-free grammars. The output format can be configured to be a custom ADT type or the regular expression format of the z3 SMT solver (z3.ReRef).
Internally, the tool converts grammars to finite automata. If you're interested in the automaton itself, you can call the method right_linear_grammar_to_nfa.