简体   繁体   English

如何通过 SymPy 中的给定子表达式自动简化表达式

[英]How to automate simplifying an expression by given sub-expressions in SymPy

I want to shorten a long equation with shorter expressions.我想用更短的表达式来缩短一个长方程。 Here is a simple example:这是一个简单的例子:

from sympy.abc import z, h, m, G
y = 0.2 * m  + 0.2 * z * m +z - h
y_1 = y.subs({m + z * m: G})
print(y_1)

Expected result is z - h + 0.2 * G but it doesn't replace the expression.预期结果是z - h + 0.2 * G但它不会替换表达式。 I know the problem is 0.2 .我知道问题是0.2 Is there any way to fix this automatically?有没有办法自动解决这个问题?

OR another solution can be : Common subexpression elimination (cse(y)), which is not efficient as it works with default conditions to create sub-expressions.或者另一种解决方案可以是:公共子表达式消除(cse(y)),因为它使用默认条件来创建子表达式,所以效率不高。

Unfortunately, as far as I know, subs just isn't as powerful (yet?).不幸的是,据我所知, subs还没有那么强大(还没有?)。 You can try to automate splitting your substitution m + z * m: G into two separate substitutions z: G / m - 1 and m: G / (z + 1) and simplify in between.您可以尝试将替换m + z * m: G自动拆分为两个单独的替换z: G / m - 1m: G / (z + 1)并在两者之间进行简化。

from sympy.abc import z, h, m, G
y = 0.2 * m + z - h + 0.2 * z * m
y_1 = y.subs({m + z * m: G})
print(y_1)
y_2 = y.subs({z: G / m - 1, m: G / (z + 1)}).simplify()
print(y_2)
y_3 = y_2.subs({G / m - 1: z, G / (z + 1): m}).simplify()
print(y_3)

Which has the following output:其中有以下输出:

-h + 0.2*m*z + 0.2*m + z
0.2*G + G/m - h - 1
0.2*G - h + z

Update: When I said that you can try to automate the process, I meant something like the following code example.更新:当我说您可以尝试自动化该过程时,我的意思是类似于以下代码示例。 I do not know how much this is applicable to your situation.我不知道这在多大程度上适用于您的情况。

from sympy import *
from sympy.abc import z, h, m, G

def elaborate_subs(expr, old, new):
    subs = {}
    for symbol in old.free_symbols:
        solution = solve(Eq(old, new), symbol, simplify=False)
        if solution:
            subs[symbol] = solution[0]
    expr = expr.subs(subs).simplify()
    expr = expr.subs({v: k for k, v in subs.items()}).simplify()
    return expr

y = 0.2 * m + z - h + 0.2 * z * m
print(elaborate_subs(y, m + z * m, G))

Which has the expected output:其中有预期的输出:

0.2*G - h + z

I don't think the subs method works the way you think it does.我不认为subs方法像你认为的那样工作。 It simply replaces a term with an input value that is passed.它只是用传递的输入值替换一个术语。 For example,例如,

expr = cos(x)
expr.subs(x, 0)#here 0 is replaced with x
print(expr) # 1, sinces cos(0) is 1

#Or

expr = x**3 + 4*x*y - z
expr.subs([(x, 2), (y, 4), (z, 0)])
print(expr) #40

As you can see, in your subs method you are not telling exactly what should be replaced.如您所见,在您的 subs 方法中,您并没有确切说明应该替换什么。 Follow the examples above as a guideline and it should work.按照上面的示例作为指导,它应该可以工作。 You can read more here你可以在这里阅读更多

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM