【问题标题】:SymPy: unable to simplify rather simple expressionSymPy:无法简化相当简单的表达式
【发布时间】:2018-12-17 18:05:45
【问题描述】:

我有一个无法在 SymPy 中简化的表达式(expr,见下文)。对于实数和正数xexpr 等价于x**3 + 2*x,但simplifyrefine 根本不简化表达式。 (Mathematica 毫不费力地进行了简化)。 如何用 SymPy 简化这个表达式?

from sympy import *

x = var('x')

expr = 16*x**3/(-x**2 + sqrt(8*x**2 + (x**2 - 2)**2) + 2)**2 - 2*2**(S(4)/5)*x*(-x**2 + sqrt(8*x**2 + (x**2 - 2)**2) + 2)**(S(3)/5) + 10*x

expr1 = simplify(expr) # does nothing

expr2 = refine(expr, Q.positive(x)) # does nothing

【问题讨论】:

  • 可以做到,只是没有 Mathematica 做的那么简单。详情见我的回答。

标签: sympy simplify


【解决方案1】:

可以的!

我撤销了我之前的回答。可以使用 Sympy 简化您的表达式。方法如下:

import sympy as sym

x = sym.symbols('x', positive=True)
expr = 16*x**3/(-x**2 + sym.sqrt(8*x**2 + (x**2 - 2)**2) + 2)**2 - 2*2**(sym.S(4)/5)*x*(-x**2 + sym.sqrt(8*x**2 + (x**2 - 2)**2) + 2)**(sym.S(3)/5) + 10*x

sym.simplify(sym.factor(sym.factor(sym.expand(sym.radsimp(expr))), deep=True))

输出:

x*(x**2 + 2)

基本上,我翻遍了sympy.simplify 上的所有docs,直到找到那个神奇的组合。此外,您必须在创建符号时将x 定义为positive,就像我在上面的代码中所做的那样。

对 Mathematica 的评论

“Mathematica 毫不费力地进行化简”

我认为您永远不应低估使 Mathematica 的 Simplify 的启发式噩梦看起来“正常工作”所花费的时间和金钱。可悲的是,相比之下,Sympy 在很多方面仍处于起步阶段。 sympy.simplify 就是其中一种方式。

【讨论】:

  • expand上调用因子有什么用?这些函数不是互逆吗?
  • 也许你会这么认为,但它们绝对不是逆向实现的。我做了测试:这是产生正确简化输出的最小操作集。你拿走一个(包括deep 标志),充其量,你最终得到了一半简化的垃圾。
  • 这样想:所有的 Sympy 简化函数都无法处理嵌套项(在这方面,我认为 Mathematica 类似)。调用expand 会暴露factor 的术语的内部结构,然后进行操作。假设,如果deep 标志设置为subexpressions will be factored。因此,如果这种行为更加稳健,那么可能就不需要调用expand(以及第二次调用factor)了。
  • 看来bottom_up(expr, factor)也能胜任。
  • 你也可以直接使用factor(expr, deep=True)
猜你喜欢
  • 1970-01-01
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多