【问题标题】:sympy solve function gives wrong resultsympy 解决函数给出错误的结果
【发布时间】:2021-05-22 14:50:57
【问题描述】:

根据这张图:desmos

print(solve('x**2 + x - 1/x'))
# [-1/3 + (-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3) + 1/(9*(-1/2 - sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)), -1/3 + 1/(9*(-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3)) + (-1/2 + sqrt(3)*I/2)*(sqrt(69)/18 + 25/54)**(1/3), -1/3 + 1/(9*(sqrt(69)/18 + 25/54)**(1/3)) + (sqrt(69)/18 + 25/54)**(1/3)]

我期待[0.755, 0.57],但是,我得到了一些我在未来的程序中无法使用的东西。 我希望得到一个浮点列表作为结果,所以参考this post,我确实关注了,但我得到了一些更奇怪的:

def solver(solved, rit=3):
    res = []
    for val in solved:
        if isinstance(val, core.numbers.Add):
            flt = val.as_two_terms()[0]
            flt = round(flt, rit)
        else:
            flt = round(val, rit)
        if not isinstance(flt, core.numbers.Add):
            res.append(flt)
    return res

print(solver(solve('x**2 + x - 1/x')))
# [-0.333, -0.333, -0.333]

现在我对 sympy 真的很失望,我想知道是否有一种准确的方法来获取浮点数列表作为结果,或者我将编写自己的梯度下降算法来找到根和交点。

【问题讨论】:

    标签: python sympy


    【解决方案1】:

    sym.solve 求解自变量的方程。如果您提供一个表达式,它将假定等式sym.Eq(expr, 0)。但这只会给你 x 值。您必须替换上述解决方案才能找到 y 值。

    你的方程有 3 个解。复解和实解的共轭对。后者是您的两个图表相交的地方。

    import sympy as sym
    
    x = sym.Symbol('x')
    # better to represent it like the equation it is
    eq = sym.Eq(x**2, 1/x - x)
    sol = sym.solve(eq)
    
    for s in sol:
        if s.is_real:
            s = s.evalf()
            print(s, eq.lhs.subs({x: s}))   # eq.rhs works too
    

    【讨论】:

      【解决方案2】:

      您可以采取多种措施来获得解决方案。如果您知道大概的根位置并且想要一个数字答案,nsolve 是最简单的,因为它对表达式的类型没有要求:

      >>> from sympy import nsolve, symbols
      >>> x = symbols('x')
      >>> eq = x**2 + x - 1/x
      >>> nsolve(eq, 1)
      0.754877666246693
      

      您可以尝试在 0.57 附近进行猜测,但它会得到相同的解决方案。那么真的有第二个真正的根源吗?您不能在此表达式上使用 real_roots,因为它不是多项式形式。但是如果你把它分成分子和分母,你可以检查分子的根:

      >>> n, d = eq.as_numer_denom()
      >>> from sympy import real_roots
      >>> real_roots(n)
      [CRootOf(x**3 + x**2 - 1, 0)]
      

      所以这个表达式只有一个真正的根,nroots 给你的那个。

      注意:solve 给出的答案是三次方程的精确解,它无法确定哪些是方程的解,所以它返回所有三个。如果您评估它们,您会发现其中只有一个是真实的。但是由于您不需要符号解决方案,因此请坚持使用nroots

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多