症状求解函数给出了错误的结果



根据此图: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],但是,我得到了一些我不能在未来的程序中使用的东西我想得到一个浮动列表作为结果,所以参考这篇文章,我做了以下操作,但我得到了一些更奇怪的:

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真的很失望,我想知道是否有一种准确的方法可以得到一个浮动列表,或者我会编写自己的梯度下降算法来找到根和交集。

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

你的方程式有三个解。复解和实解的共轭对。后者是你的两张图相遇的地方。

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

您可以做很多事情来获得解决方案。如果你知道近似的根位置,并且你想要一个数字答案,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即可。

最新更新