[英]how to pattern match and change all occurrences of subexpression in expression?
使用sympy,我需要用C*exp(anything)
替換所有出現的exp(C+anything)
C*exp(anything)
。 因為exp(C)
是常數,所以我只是寫為C
我可以在表達式中出現一次exp
。 但如果有一個實例,不要怎么做。
例如,對於一個實例,如在x+exp(C_0+3*x)+3*y
,我需要將其更改為x+C_0*exp(3*x)+3*y
例如,這似乎在經過一些試驗和錯誤之后起作用
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]))
這使
C_0*exp(3*x) + x + 3*y
但是x+exp(C_0+3*x)+3*y+exp(C_0+30*x+y)
我需要改為x+C_0*exp(3*x)+3*y+C_0*exp(30*x+y)
我無法為每種可能的情況進行特殊模式匹配。 我需要一種方法來改變所有事件
在Mathematica中,我按如下方式進行上述操作
expr = x + Exp[c + 3*x]*3*y + 3*y + Exp[c + 30*x + y]
expr /. Exp[c + any_] :> (c Exp[any])
這使
我實際上更喜歡告訴Python只是將exp(C+anything)
更改為C*exp(anything)
而不必為整個表達式賦予模式,因為它可以以多種方式改變。
我確信上面的內容也可以在python / sympy中使用。 任何提示如何做到這一點?
我會在表達式中查找函數exp
,檢查它的參數是否為Add
,然后C_0
是否在Add
的參數中。 然后構建一個用exp
替換exp
的東西。 考慮以下:
from sympy import *
x, y, C_0 = symbols('x y C_0')
expr = x + exp(C_0+3*x) + 3*y + exp(y+C_0+30*x) - exp(x+y-C_0) + exp(x*y)
exp_sum = [(a, a.args[0].args) for a in preorder_traversal(expr) if a.func == exp and a.args[0].func == Add]
exp_sum = [p for p in exp_sum if C_0 in p[1]]
new_exp = [C_0*exp(Add(*[x for x in p[1] if x != C_0])) for p in exp_sum]
for (old, new) in zip(exp_sum, new_exp):
expr = expr.subs(old[0], new)
最初, exp_sum
包含表單exp(Add(...))
所有部分。 之后,它被過濾到包含C_0
總和。 新指數由采取有不是所有的被加數形成C_0
,將它們添加,應用exp
和乘以C_0
。 然后替換發生。
為了闡明這個過程, exp_sum
是上面例子中的exp_sum
:元組列表(指數和內部的加法):
[(exp(C_0 + 3*x), (C_0, 3*x)), (exp(C_0 + 30*x + y), (C_0, y, 30*x))]
這是new_exp
[C_0*exp(3*x), C_0*exp(30*x + y)]
最后, expr
結尾:
C_0*exp(3*x) + C_0*exp(30*x + y) + x + 3*y + exp(x*y) - exp(-C_0 + x + y)
請注意,exp(-C_0 ...)不受更改的影響; 它不是模式的一部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.