我已经搜索了很多问题,老实说,没有找到适用于我的情况的东西。
我正在使用SymPy库来执行大型计算,它工作得非常好。然而,我最近的结果变得太复杂了。因此,我开始实现更多的定义和符号,以便执行几次替换,并将表达式缩小到更可行的形式。我已经“手动”完成了很多术语,这些术语太特殊了,不允许任何类型的自动化。但是,如果我可以运行这个简单的替换规则,那么在我的表达式中有一个特定的贡献家族可以大大简化。
设A是我的完整表达式。在this image中,点表示已经简化的术语,求和表示查询背后的一般设置。我的目标是像this一样重写它。
T_k只是表示通用术语;实际上,它们由几个文字Symbols
组成。在我的代码中,rho字母与单个变量Symbol
-type关联。因此,我的问题可以举例如下:
# sympy symbols: rho, a, b, c, d
# sympy functions: f, g, h
A = (a * b) * f(rho) + (c * d) * g(rho) + (a * c * d * b) * h(rho)
# apply some clever substitution method ???
A.subs(???)
>>> f(a * b) * rho + g(c * d) * rho + h(a * c * d * b) * rho
当然,在上面的例子中,我可以“手工”完成。当有很多这样的术语时,问题就出在这里。我试图使用lambda
表达式来实现我的目标,但无法实现。想法是:对于任何通用的lambda t
,我可以尝试为每个符号函数(# f, g, h
)输入映射{t * f(rho) : f(t) * rho}
,而不关心特定的伴随术语。
例如,我尝试定义genSub_f = lambda t: A.subs(t * f(rho), f(t) * rho)
。但是,为了进行替换,我必须调用genSub_f(a * b)
,这是有效的,但这是不可行的,因为必须保留与f(rho)
一起使用的符号组合的先验知识。如何继续?
发布于 2021-02-12 18:35:30
您可以使用Wild
符号来实现这一点,但是有几种方法可以获得您想要的输出。
一个复杂的问题是,您似乎不想应用替换f(a*b)*rho -> f(a*b*rho)
。有几种方法可以实现这一点,但首先我将给出一个确实会导致此替换的答案:
from sympy import *
rho, a, b, c, d = symbols("rho, a, b, c, d")
f, g, h = symbols("f, g, h", cls=Function)
A = (a * b) * f(rho) + (c * d) * g(rho) + (a * c * d * b) * h(rho)
w1, w2 = symbols("w1, w2", cls=Wild)
for ff in [f, g, h]:
A = A.replace(w1*ff(w2), w2*ff(w1))
print(A) # f(a*b*rho) + g(c*d*rho) + h(a*b*c*d*rho)
那么排除替换rho*f(a*b) -> f(a*b*rho)
又如何呢?
一种方法是从Wild
匹配中排除rho
,方法是像这样定义您的Wild
符号w1
(我们还必须排除替换1*f(...) -> ...*f(1)
)。这将产生所需的输出:
A = (a * b) * f(rho) + (c * d) * g(rho) + (a * c * d * b) * h(rho)
w1 = Wild("w1", exclude=[rho, 1]) # exclude unwanted substitutions
w2 = Wild("w2")
for ff in [f, g, h]:
A = A.replace(w1*ff(w2), w2*ff(w1))
print(A) # rho*f(a*b) + rho*g(c*d) + rho*h(a*b*c*d)
但是,实现所需输出的另一种方法是使用match
而不是replace
。这样,您就不必显式地排除rho
(使用这种方法,替换是手动完成的,因此无需担心避免替换规则的“双重”应用):
A = (a * b) * f(rho) + (c * d) * g(rho) + (a * c * d * b) * h(rho)
w1, w2, w3 = symbols("w1, w2, w3", cls=Wild)
for ff in [f, g, h]:
m = A.match(w1*ff(w2) + w3)
if m:
A = m[w2]*ff(m[w1]) + m[w3] # manual replacement
print(A) # rho*f(a*b) + rho*g(c*d) + rho*h(a*b*c*d)
https://stackoverflow.com/questions/66175255
复制