使用sympy,我需要将所有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)
的{{1}}之类的内容我不能为每种可能的情况进行特殊模式匹配。我需要一种方法来更改所有出现次数
在Mathematica中,我按照以下步骤进行操作
x+C_0*exp(3*x)+3*y+C_0*exp(30*x+y)
哪个给出了
我实际上更愿意告诉Python只需将expr = x + Exp[c + 3*x]*3*y + 3*y + Exp[c + 30*x + y]
expr /. Exp[c + any_] :> (c Exp[any])
更改为exp(C+anything)
而无需为整个表达式提供模式,因为这可能会以多种方式发生变化。
我确信上面的内容也可以在python / sympy中使用。有任何提示怎么做?
答案 0 :(得分:1)
我会在表达式中查找函数exp
,检查其参数是否为Add
,然后C_0
是Add
的参数。然后构建一个替换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(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 ...)不受更改的影响;它不是模式的一部分。