Math 简化表达式
我有一个类似的表达方式:Math 简化表达式,math,expression,sympy,Math,Expression,Sympy,我有一个类似的表达方式: a*b*c + d*e + f - g*h*h + i*a 换句话说:术语可以加或减,每个术语都是一些符号的产物 有没有办法得到一个最小/更简单的表达式,基本上与expand相反?我尝试过简化和系数,但我无法让它们工作。例如: a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4 应变成: (a - b)**4 - a 但在使用上述命令时,它保持不变 PS:如果这是SymPy根本无法做到的,请您推荐一种替代方法,可
a*b*c + d*e + f - g*h*h + i*a
换句话说:术语可以加或减,每个术语都是一些符号的产物
有没有办法得到一个最小/更简单的表达式,基本上与expand相反?我尝试过简化和系数,但我无法让它们工作。例如:
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
应变成:
(a - b)**4 - a
但在使用上述命令时,它保持不变
PS:如果这是SymPy根本无法做到的,请您推荐一种替代方法,可以做到这一点吗?如果您事先知道该函数,那么您可以使用更强大的软件包,如Maple,在将其放入计算机代码之前减少表达式。Maple中有一个优化包,它将表达式简化为子表达式,从而利用表达式中的重复操作。此外,您还可以以非常可靠的方式分解非常复杂的表达式 此外,此类软件还可以创建编程代码作为输出,您可以直接将其粘贴到程序中。如果您无法访问Maple或Mathematica软件,也可以使用免费(但功能强大)的maxima软件 见。Symphy的
factor
只知道如何对整个表达式进行因子分解,但如果您知道要重写内容的术语,则可以对subs使用技巧,如:
>>> expr = a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
>>> expr.subs(a, x + b).expand()
-b + x**4 - x
>>> expr.subs(a, x + b).expand().subs(x, a - b)
-a + (a - b)**4
基本上,让x=a-b
,这样a=x+b
。然后将a
替换为x+b
,展开内容,然后将其替换回来
对于更复杂的示例,SymPy实际上足够聪明,可以正确地替换表达式中的a*b
:
>>> expr = (a*b - c*d)**2 - a
>>> expr = expr.expand()
>>> expr
a**2*b**2 - 2*a*b*c*d - a + c**2*d**2
>>> expr.subs(a*b, x + c*d)
-a + c**2*d**2 - 2*c*d*(c*d + x) + (c*d + x)**2
>>> expr.subs(a*b, x + c*d).expand()
-a + x**2
>>> expr.subs(a*b, x + c*d).expand().subs(x, a*b - c*d)
-a + (a*b - c*d)**2
解决此问题的另一种可能方法是尝试在表达式中的术语子集上使用因子(itertools.compositions
)。例如,要尝试从原始表达式中分解除一个以外的所有术语的所有组合,请执行以下操作:
>>> args = Add.make_args(expr)
>>> for comb in combinations(args, len(args) - 1):
... print(factor(Add(*comb)) + Add(*(set(args) - set(comb))))
...
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
a**4 - 4*a**3*b + 6*a**2*b**2 - 4*a*b**3 - a + b**4
-a + (a - b)**4
a*(a**3 - 4*a**2*b + 6*a*b**2 - 4*b**3 - 1) + b**4
您可以选中
notisinstance(factored\u expr,Add)
以筛选出未考虑因素的因素 W | A并没有以同样的方式减少公式。如果你用一个你知道会简化的方程-@corn3lius-我不太明白:因子(a**4-4*a**3*b+6*a**2*b**2-4*a*b**3+b**4)
确实有效,是的。但是大多数的表达几乎从来没有这么简单过……看(这可能被认为是这个问题的重复)。这样的“部分因子分解”并没有很好的定义,尽管如果你知道答案应该是什么样的话,有一些技巧可以得到它们。@asmuer有趣!虽然我还不确定我是否理解它是如何工作的。假设我想算出a*b-c*d
,然后呢?@asmurer我知道你是SymPy的开发者!我最近在邮件列表中问到,为什么SymPy不能自动完成上面的简化?有一个根本性的问题吗?你提到了唯一性——只要它有最少数量的运算符,就不可能进行任意的因式分解吗?例如,“如果你事先知道函数”-哪个函数?在上面的例子中,我不知道(a-b)**4-a
,当然,这就是我试图计算的。但也许我误解了你的意思……我的意思是表达a**4-4*a**3*b+6*a**2*b**2-4*a*b**3-a+b**4
。您可以使用Maple对其进行分解,然后手动将输出输入到代码中,或者使用Maple为您生成代码。我刚刚尝试了Maxima,它无法简化它,W | A(IIRC在Mathematica上运行)也无法简化它。不幸的是,我没有访问Maple的权限。@EcirHana我刚刚在Maple中尝试了你的表达,它在Maple中也不起作用。但是,如果您删除-a
,它会工作。我想在一般情况下,即使是枫树也不能帮助你!感谢您在Maple中试用,这是非常有用的信息。没有-a
它也可以在其他工具中使用。