【问题标题】:Sympy `factor` and `simplify` not working properly?Sympy `factor` 和 `simplify` 不能正常工作?
【发布时间】:2021-07-16 15:39:59
【问题描述】:

由于我正在从事一个涉及平方根的项目,因此我需要将平方根简化到最大值。但是,某些平方根表达式不会产生不想要的结果。请考虑检查此示例:

>>> from sympy import * # just an example don't tell me that import * is obsolete
>>> x1 = simplify(factor(sqrt(3 + 2*sqrt(2))))
>>> x1 # notice that factoring doesn't work
sqrt(2*sqrt(2) + 3)
>>> x2 = sqrt(2) + 1
>>> x2 
sqrt(2) + 1
>>> x1 == x2
False
>>> N(x1)
2.41421356237309
>>> N(x2)
2.41421356237309
>>> N(x1) == N(x2)
True

如您所见,这些数字实际上是相等的,但 numpy 无法识别这一点,因为它无法分解和简化 x1。那么如何获得 x1 的简化形式,以便相等性正确而不必将它们转换为 float 呢?

提前致谢。

【问题讨论】:

  • simplify(x1-x2)0
  • 这只是一个例子,假设我不知道 x2 的值,我想要 x1 的简化形式
  • 你要的函数是sqrtdenest

标签: python sympy square-root factorization simplification


【解决方案1】:

当您使用嵌套的sqrt 表达式时,sqrtdenest 是一个不错的选择。但是使用nsimplify 是一个很好的后备方案,它在某些情况下可能更有用。由于这可以给出与输入不完全相同的答案,所以我喜欢使用这个“安全”函数来进行简化:

def safe_nsimplify(x):
    from sympy import nsimplify
    if x.is_number:
        ns = nsimplify(x)
        if ns != x and x.equals(ns):
            return ns
    return x

>>> from sympy import sqrt, sqrtdenest
>>> eq = (-sqrt(2) + sqrt(10))/(2*sqrt(sqrt(5) + 5))
>>> simplify(eq)
(-sqrt(2) + sqrt(10))/(2*sqrt(sqrt(5) + 5))  <-- no change
>>> sqrtdenest(eq)
-sqrt(2)/(2*sqrt(sqrt(5) + 5)) + sqrt(10)/(2*sqrt(sqrt(5) + 5))  <-- worse
>>> safe_nsimplify(eq)
sqrt(1 - 2*sqrt(5)/5)  <-- better

看你的表情

>>> safe_nsimplify(sqrt(2 * sqrt(2) + 3))
1 + sqrt(2)

如果你想在更大的表达式中找到这样的表达式,你可以使用

>>> from sympy import bottom_up, tan
>>> bottom_up(tan(eq), safe_nsimplify)
tan(sqrt(1 - 2*sqrt(5)/5))

可能接受sqrtdenest 的结果,而不是像中那样使用nsimplify

def safe_nsimplify(x):
  from sympy import nsimplify, sqrtdenest, Pow, S
  if x.is_number:
    if isinstance(x, Pow) and x.exp is S.Half:
        ns = sqrtdenest(x)
        if ns != x:
            return ns
    ns = nsimplify(x)
    if ns != x and x.equals(ns):
        return ns
  return x

【讨论】:

  • 这正是我想要的!非常感谢
  • 我添加了一个安全功能的变体,你也可以考虑。
【解决方案2】:

感谢Oscar Benjamin,我要找的函数是sqrtdenest

>>> from sympy import *
>>> sqrtdenest(sqrt(2 * sqrt(2) + 3))
1 + sqrt(2)

我希望这个答案对其他人有所帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-11
    • 2012-09-24
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    相关资源
    最近更新 更多