如何在Wolfram Mathematica中用Python(Sympy)实现与“ _”相同的功能和替换规则?

时间:2018-12-08 21:46:58

标签: python math wolfram-mathematica sympy

在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是一个很大的列表,并且有许多不同的变量,那么使用我的解决方案将很难实现。

  

我想知道是否有一种简单的方法,而不是像Mathematica中那样在SSlist中的 SS 上遍历整个列表。熟悉sympy的人可以给我任何提示吗?

非常感谢!

1 个答案:

答案 0 :(得分:1)

我为自己的问题找到了一种解决方案。可以按我的要求工作。我没有使用subs(),而是使用了野生运算符和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那样的通用方法来做这些事情。

欢迎任何评论。谢谢!