在Wolfram Mathematica中,我可以定义命名模式,其中_(称为
Blank)匹配任何表达式,然后在
replacement rule中使用匹配.
一个例子:
testexpr = p1[MM]*p2[NN] + p1[XX]*p2[MM] + p1[XX]^2;
FunTest[expr_] := Expand[expr] /. {(p1[l1_]*p2[l2_]) -> FF1[l1]*FF2[l2],
p1[l1_]^n_ -> 0, p2[l1_]^n_ -> 0}
FunTest[testexpr]
结果是FF1 [XX] FF2 [MM] FF1 [MM] FF2 [NN]
但是,我不知道如何在Python中使用sympy来做同样的事情.
import sympy as sp
p1 = sp.IndexedBase("p1")
p2 = sp.IndexedBase("p2")
FF1 = sp.IndexedBase("FF1")
FF2 = sp.IndexedBase("FF2")
MM,NN,XX=sp.symbols('MM NN XX')
SSlist=[MM,NN,XX]
testexpr=p1[MM]*p2[NN] + p1[XX]*p2[MM] + p1[XX]**2
def FunTest(expr):
expr=expr.subs([(p1[SS]*p2[SS2],FF1[SS]*FF2[SS2]) for SS in SSlist
for SS2 in SSlist]+[(p1[SS]**2,0) for SS in SSlist]+[(p2[SS]**2,0)
for SS in SSlist],simultaneous=True)
return expr
rest=FunTest(testexpr)
print(rest)
因此结果也是FF1 [MM] * FF2 [NN] FF1 [XX] * FF2 [MM].
但是我想知道是否有一种简单的方法可以使它更加通用,就像在Wolfram Mathematica中一样.如果SSlist是一个大型列表并且存在许多不同的变量,那么使用我的解决方案将难以实现.
I wonder whether there is an easy way without writing a loop over the whole list, for SS in SSlist, as in Mathematica. Can someone familiar with sympy give me any hints?
非常感谢!
最佳答案 我找到了一个解决我自己问题的方法.它按照我的意愿运作.我没有使用subs(),而是使用wild运算符和replace().
import sympy as sp
p1 = sp.IndexedBase("p1")
p2 = sp.IndexedBase("p2")
FF1 = sp.IndexedBase("FF1")
FF2 = sp.IndexedBase("FF2")
MM,NN,XX=sp.symbols('MM NN XX')
SSlist=[MM,NN,XX]
SS = sp.Wild('SS')
SS1 = sp.Wild('SS1')
testexpr=p1[MM]*p2[NN] + p1[XX]*p2[MM] + p1[XX]**2
replacements = {p1[SS]*p2[SS1] : FF1[SS]*FF2[SS1], p1[SS]**2: 0, p2[SS]**2 : 0}
def replaceall(expr, repls):
for i, j in repls.items():
expr = expr.replace(i, j, map=False, simultaneous=True, exact=False)
return expr
rest=replaceall(testexpr,replacements)
print(rest)
结果与我之前完全相同:
FF1[MM]*FF2[NN] + FF1[XX]*FF2[MM]
我想知道的一件事是,由于for循环,有许多符号时效率很高.看来这两种方法是相似的,只是我最近发现的方法看起来更简洁.
我想知道是否有更通用的方法来做Wolfram Mathematica所做的事情.
欢迎任何评论.谢谢!