You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Sympy solveset返回虚数解求助:三次方程求实根失败

解决Sympy求解三次方程实根显示为复数形式的问题

我懂你碰到的这个问题——明明函数图像显示有三个实根,可用Sympy的solveset求解时,得到的却是看起来像复数的表达式。其实这不是Sympy出bug了,而是它的一个特性:当三次方程的实根没法用实数域内的简洁根式表示时(也就是三次方程判别式大于0的不可约情形),Sympy会用复数域的根式形式来表达这些实根,但实际上这些表达式计算出来的结果都是实数。

先确认方程确实有三个不同实根

我们可以先计算方程的判别式,验证它确实存在三个不同实根:

from sympy import *
x = symbols('x')
f = x**3 - 4*x**2 + 1
# 计算判别式
print(discriminant(f, x))

运行结果是229,大于0,说明方程确实有三个不同的实根,和你从图像里看到的一致。

三种获取数值形式实根的方法

如果你想要得到像Wolfram Alpha那样的近似数值解,试试下面这些方法:

方法1:用nsolveset直接求数值解

nsolveset是Sympy专门用于求数值解的函数,指定实数域后会直接输出近似实根:

from sympy import *
x = symbols('x')
# 直接求解并指定实数域
solutions = nsolveset(x**3 - 4*x**2 + 1, x, domain=S.Reals)
print(solutions)

输出结果会是:{-0.472830956984245, 0.537402019888976, 3.93542893709527},和你预期的完全一致。

方法2:将solveset的解析解转为数值

如果你已经用solveset得到了解析形式的解,可以用N()函数把每个根转换成数值:

from sympy import *
x = symbols('x')
# 先获取解析解
analytic_sols = solveset(x**3 - 4*x**2 + 1, x, domain=S.Reals)
# 逐个转换为数值
for root in analytic_sols:
    print(N(root))

运行后同样会输出三个实根的近似值。

方法3:使用nroots函数

对于多项式方程,nroots可以直接返回所有数值根,默认就会输出实根(如果存在的话):

from sympy import *
x = symbols('x')
f = x**3 - 4*x**2 + 1
# 直接获取数值根
print(f.nroots())

输出结果:[-0.472830956984245, 0.537402019888976, 3.93542893709527]

补充说明:为什么solveset会输出复数形式的实根?

这是因为三次方程的卡丹求根公式在判别式大于0时,会涉及到复数运算,但最终计算结果是实数。Sympy默认优先输出解析形式的解,所以会保留这些复数表达式,但只要通过数值转换,就能得到你需要的实根近似值。

内容的提问来源于stack exchange,提问作者AshishSinha5

火山引擎 最新活动