how to pattern match and change all occurrences of subexpression in expression?

Viewed 389

Using sympy, I need to replace all occurrence of exp(C+anything) with C*exp(anything). Because exp(C) is constant, I just write at as C.

I can do this for one occurrence of exp in the expression. But do not how to do it if there are than one instance.

For example, for one instance, as in x+exp(C_0+3*x)+3*y, I need to change it to x+C_0*exp(3*x)+3*y

For one instance, this seems to work after some trial and error

from sympy import *
x,y,C_0 = symbols('x y C_0')
expr=x+exp(C_0+3*x)+3*y
#first check if exp is in the expression
if  any([isinstance(a, exp) for a in preorder_traversal(expr)]):
    p_1=Wild('p1');p_2=Wild('p_2');p_3=Wild('p_3')
    r=(p_1+exp(C_0+p_2)+p_3).matches(expr)
    expr.subs(exp(C_0+r[p_2]),C_0*exp(r[p_2]))

Which gives

C_0*exp(3*x) + x + 3*y

But what about something like x+exp(C_0+3*x)+3*y+exp(C_0+30*x+y) which I need to change to x+C_0*exp(3*x)+3*y+C_0*exp(30*x+y) I can't make special pattern match for each possible case. I need a way to change all occurrences

In Mathematica, I do the above as follows

expr = x + Exp[c + 3*x]*3*y + 3*y + Exp[c + 30*x + y]
expr /. Exp[c + any_] :> (c Exp[any])

Which gives

Mathematica graphics

I actually prefer to tell Python just to change exp(C+anything) to C*exp(anything) without having to give pattern for the overall expression, since that can change in many way.

I am sure the above is also possible in python/sympy. Any hints how to do it?

1 Answers
Related