我使用SymPy来识别和替换模式,并且效果很好。例如:
import sympy as sym
mu = sym.symbols('mu')
a=sym.Wild('a')
b=sym.Wild('b')
c=sym.Wild('c')
现在
I1=36*sym.exp(12)*mu**2
I1.replace(c*sym.exp(b)*mu**a,a,exact=True)
返回2.但是当我试图识别简单的电源功能时,我有这个:
I2=36*mu**2
I2.replace(c*mu**a,a,exact=True)
返回36.奇怪的结果,但是:
I2.replace(c*mu**a,c,exact=True)
I2.replace(c*mu**a,a*c,exact=True)
也会返回36。 然后我发现了下一个:
I2.replace(c*b**a,a,exact=True)
1
I2.replace(c*b**a,b,exact=True)
mu
I2.replace(c*b**a,c,exact=True)
1
所以为什么同情这样做,如果它是一个bug我可以让它以某种方式工作。我当然在等待这个结果:
I2.replace(c*b**a,a,exact=True)
2
下一个例子是
I2=12*mu**2
I2.match(c*mu**2)
{c_: 12}
但
I2.replace(c*mu**2,c)
12*(1/mu)**(2/mu**2)/mu**2
我使用python 3.6.5和sympy 1.1.1。
答案 0 :(得分:0)
要识别模式,请使用match
方法:
I2.match(c*b**a) # {a_: 2, c_: 36}
I2.match(c*mu**a) # {a_: 2, b_: mu, c_: 36}
可以从字典中检索特定值:I2.match(c*b**a)[a]
返回2。
使用replace
的方法存在问题,因为SymPy可能会找到子表达式并替换它们,而忽略了更大的结构。例如,
I2.replace(c*mu**a, sym.sin(a) + sym.cos(c), exact=True)
返回36*(cos(1) + sin(1))**2
。在这里,我们看到mu
本身与模式a=1
和c=1
匹配,并被替换为。
您的示例也是如此:子表达式mu
与1*mu**1
匹配,并替换为1,而36*1**2
为36。
可以通过从Wild 的可能值中排除1来避免这种情况:
>>> a = sym.Wild('a', exclude=[1])
>>> c = sym.Wild('c', exclude=[1])
>>> I2.replace(c*mu**a, a, exact=True)
2
exact=True
标志确保“只有在匹配模式中出现的每个Wild收到非零值时匹配才会成功”,这仍然允许值为1.具体排除1个修复那。
在I2=12*mu**2
的示例中,替换I2.replace(c*mu**2, c)
找到了多个匹配项。例如,指数2与模式匹配,因为2 = (2/mu**2) * mu**2
其中括号中的表达式被视为c。为防止这种情况,请指明c不应包含mu:
>>> c=sym.Wild('c', exclude=[mu])
>>> I2.replace(c*mu**2, c)
12