考虑一下python / sympy中的以下表达式:
from sympy.abc import x, y
expression = 3*x**2*y**1 + x**2*y**3
现在我要替换x**n*y**m
通过max(n,m)
使用模式匹配:
from sympy import Wild
n = Wild('n')
m = Wild('m')
expression = expression.replace(x**n*y**m,max(n,m))
但是,我得到了TypeError
:
Traceback (most recent call last):
File "wild.py", line 15, in <module>
expression = expression.replace(x**n*y**m,max(n,m))
File "/usr/lib/python3/dist-packages/sympy/core/relational.py", line 103, in __nonzero__
raise TypeError("cannot determine truth value of\n%s" % self)
TypeError: cannot determine truth value of
m_ > n_
问题显然是在匹配表达式时,sympy在将Wild符号的值转发给-function之前不会将其转换为匹配的值max
。有什么办法可以使这项工作吗?
请注意,这是我遇到的一个更普遍问题的简单示例,因此无法很好地概括的解决方法不是很有帮助。我特别希望有一个使用表达式匹配的解决方案。
更新:遵循三明治的建议max(n,m)
并由(m+n+abs(m-n))/2
工作取代,但是,我在实际程序中使用的功能要复杂得多。关于夹心提到的replace
从表达式树的底部开始执行替换的问题:如果我使用exact=True
并定义,f = sympy.Function('f')
那么以下工作(除了我将不得不分别处理某些情况):
expression = expression.replace(x**n*y**m,f(n,m),exact=True)
但是,它仍然不适用于max(n,m)
。
max
被内置在Python函数,它试图立即评估,因此误差(它不能确定其 n
和 m
较大时,他们是象征性)。您可能需要SymPy Max
函数,该函数可以象征性地工作。在 my_func
你在你的答案定义实际上是一个基本的实现的 Max
。
In [14]: expression = expression.replace(x**n*y**m, Max(n,m))
In [15]: expression
Out[15]: 4
看来这行不通(答案4是错误的)。问题是,它匹配x**2
的x**2*y**0
。由于替换函数的数学值取决于表达式的形式,因此这是有问题的,因为SymPy试图变得聪明。实际上,你可以做n
和m
不匹配0有Wild('n', exclude=[x, 0])
,但后来有一个问题,它不匹配x**2*y
的x**2*y**1
。
因此,我建议将表达式转换为多项式并进行精确替换。希望这能很好地概括您的实际工作
In [18]: Poly(expression, x, y)
Out[18]: Poly(x**2*y**3 + 3*x**2*y, x, y, domain='ZZ')
In [19]: Poly(expression, x, y).terms()
Out[19]: [((2, 3), 1), ((2, 1), 3)]
In [20]: sum(max(pows)*coeff for pows, coeff in Poly(expression, x, y).terms())
Out[20]: 9
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句