【问题标题】:Sympy comparison fail with sympified expressionsSympy 比较因简化表达式而失败
【发布时间】:2014-01-18 01:07:14
【问题描述】:

我最近遇到了无法解决的 SympPy 问题;我是图书馆的初学者,我花了很长时间在网上寻找解决方案,但没有找到,这就是我来这里的原因。

问题是:我有一个来自 javascript Web 应用程序的输出,它给了我表达式 (x**2)**(1/3) 而不是 x**(2/3)。 “没问题”,我想,“SymPy 会解析那个”......但不是。如果我比较,我会得到这个结果:

>>> sympify("(x**2)**(1/3)") == sympify("x**(2/3)")
False

我进行了一些测试,但我只得到简化表达式中的指数。示例:

>>> (x**(1/3))**2 == x**(2/3)
True

更奇怪的是,如果我将两个指数取反,我会得到正确的结果:

>>> sympify("(x**(1/3))**2") == sympify("x**(2/3)")
True

我尝试使用simplifyextend,但它也不起作用。获得好结果的唯一方法是使用eval,但这需要首先创建一个符号“x”,这是我无法做到的,因为我无法确切知道哪些符号将用于表达式。

所以问题来了:这是 SymPy 中的错误,还是我做错了什么?

如果这个问题众所周知并且我自己找不到任何相关信息,请原谅。

【问题讨论】:

    标签: python sympy


    【解决方案1】:

    正如the SymPy issue 所指出的,这是故意的。对于一般复杂的x,这两个表达式不相等。以x = -1((-1)**2)**(1/3) == 1**(1/3) == 1(-1)**(2/3) = -1/2 + sqrt(3)/2*I 为例。有关更多信息,请参阅http://docs.sympy.org/0.7.3/tutorial/simplification.html#powers。如果 SymPy 知道它对于整个域是正确的,它只会简化这些指数。

    特别是,如果x 为非负数,则此为真。如果b 是一个整数,(x**a)**b == x**(a*b) 也是如此,这就是您的其他测试有效的原因。

    如果您想强制简化这一点,有两个主要选项。一个(最好的选择)是假设x 不是负数或正数。

    >>> x = symbols('x', positive=True)
    >>> (x**2)**(S(1)/3)
    x**(2/3)
    

    如果你想在解析字符串后用正数替换你的符号,你可以使用posify:

    >>> posify((x**2)**(S(1)/3))
    (_x**(2/3), {_x: x})
    

    或者您可以使用sympifylocals 参数来手动设置{'x': Symbol('x', positive=True}

    如果这不能完全满足您的需求,另一种方法是使用 powdenest 强制简化它:

    >>> x = symbols('x') # No assumptions on x
    >>> (x**2)**(S(1)/3)
    (x**2)**(1/3)
    >>> powdenest((x**2)**(S(1)/3), force=True)
    x**(2/3)
    

    如果你这样做,你需要小心,因为你应用的恒等式并不总是正确的,所以你最终可能会得到数学上不正确的结果。

    【讨论】:

      【解决方案2】:

      这是 sympy 中的一个错误。

      指数层次结构没有正确展开(请参阅https://github.com/sympy/sympy/blob/master/sympy/core/power.py#L445

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-07
        • 1970-01-01
        • 2022-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        相关资源
        最近更新 更多